Skip to content

Commit

Permalink
V2 settings teams (Profil, Members, Appearance View) (#4350)
Browse files Browse the repository at this point in the history
* add team profile

* first version for team members page

* finish up design of member list item

* fix dialog buttons

* add missing seats and upgrading information

* add v2 dialog for changing role

* finish basic version of member's schedule

* remove modalContainer

* design fixes team profile page

* show only team info to non admins

* allow all member to check availabilities

* make time available heading sticky

* add dropdown for mobile view

* create team appearance view

* finish appearance page

* use settings layout and add danger zone for member

* add fallback logo

* Add teams to sidebar and fix UI

* add team invitations

* Clean up

* code clean up

* add impersontation and disable autofocus on calendar

* improve team info

* refactor teaminvitelist code and fix leaving a team

* add team pages to settings shell

* add link to create new team

* small fixes

* clean up comments

* V2 Multi-select (Team Select) (#4324)

* --init

* design improved

* further fine tuning

* more fixes

* removed extra JSX tag

* added story

* NIT

* revert to use of CheckedTeamSelect

* Removes comments

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* fix: toggle alligment (#4361)

* fix: add checked tranform for switch (#4357)

* fixed input size on mobile, fixed settings (#4360)

* fix image uploader button in safari

* code clean up

* fixing type errors

* Moved v2 team components to features

Adds deprecation notices

* Update SettingsLayout.tsx

* Migrated to features and build fixes

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
  • Loading branch information
8 people committed Sep 13, 2022
1 parent 8fdbd8a commit d7dc068
Show file tree
Hide file tree
Showing 24 changed files with 1,573 additions and 533 deletions.
1 change: 1 addition & 0 deletions apps/web/components/ImageUploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ function CropContainer({
);
}

/** @deprecated Use `packages/ui/v2/core/ImageUploader.tsx` */
export default function ImageUploader({
target,
id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { User } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react";
import { Button, showToast, TextArea } from "@calcom/ui/v2";
import ImageUploader from "@calcom/ui/v2/core/ImageUploader";

import { AvatarSSR } from "@components/ui/AvatarSSR";
import ImageUploader from "@components/v2/settings/ImageUploader";

interface IUserProfile {
user?: User;
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/DisableTeamImpersonation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { trpc } from "@calcom/trpc/react";
import Badge from "@calcom/ui/Badge";
import Button from "@calcom/ui/Button";

/** @deprecated Use `packages/features/ee/teams/components/DisableTeamImpersonation.tsx` */
const DisableTeamImpersonation = ({ teamId, memberId }: { teamId: number; memberId: number }) => {
const { t } = useLocale();

Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/MemberChangeRoleModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type MembershipRoleOption = {
value: MembershipRole;
};

/** @deprecated Use `packages/features/ee/teams/components/MemberChangeRoleModal.tsx` */
export default function MemberChangeRoleModal(props: {
isOpen: boolean;
currentMember: MembershipRole;
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/MemberInvitationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type MembershipRoleOption = {

const _options: MembershipRoleOption[] = [{ value: "MEMBER" }, { value: "ADMIN" }, { value: "OWNER" }];

/** @deprecated Use `packages/features/ee/teams/components/MemberInvitationModal.tsx` */
export default function MemberInvitationModal(props: MemberInvitationModalProps) {
const [errorMessage, setErrorMessage] = useState("");
const { t, i18n } = useLocale();
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/MemberListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface Props {
member: inferQueryOutput<"viewer.teams.get">["members"][number];
}

/** @deprecated Use `packages/features/ee/teams/components/MemberListItem.tsx` */
export default function MemberListItem(props: Props) {
const { t } = useLocale();

Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/TeamPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface Props {
color?: PillColor;
}

/** @deprecated Use `packages/features/ee/teams/components/TeamPill.tsx` */
export default function TeamPill(props: Props) {
return (
<div
Expand Down
1 change: 1 addition & 0 deletions apps/web/components/team/UpgradeToFlexibleProModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Props {
teamId: number;
}

/** @deprecated Use `packages/features/ee/teams/components/UpgradeToFlexibleProModal.tsx` */
export function UpgradeToFlexibleProModal(props: Props) {
const { t } = useLocale();
const [errorMessage, setErrorMessage] = useState<string | null>(null);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/pages/v2/settings/my-account/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Alert } from "@calcom/ui/Alert";
import Avatar from "@calcom/ui/v2/core/Avatar";
import { Button } from "@calcom/ui/v2/core/Button";
import { Dialog, DialogContent, DialogTrigger } from "@calcom/ui/v2/core/Dialog";
import ImageUploader from "@calcom/ui/v2/core/ImageUploader";
import Meta from "@calcom/ui/v2/core/Meta";
import { Form, Label, TextField, PasswordField } from "@calcom/ui/v2/core/form/fields";
import { getLayout } from "@calcom/ui/v2/core/layouts/SettingsLayout";
Expand All @@ -23,7 +24,6 @@ import showToast from "@calcom/ui/v2/core/notifications";
import { inferSSRProps } from "@lib/types/inferSSRProps";

import TwoFactor from "@components/auth/TwoFactor";
import ImageUploader from "@components/v2/settings/ImageUploader";

interface DeleteAccountValues {
totpCode: string;
Expand Down
102 changes: 1 addition & 101 deletions apps/web/pages/v2/settings/teams/[id]/appearance.tsx
Original file line number Diff line number Diff line change
@@ -1,101 +1 @@
import { MembershipRole } from "@prisma/client";
import { useRouter } from "next/router";
import { Controller, useForm } from "react-hook-form";

import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Button, Form, showToast, Switch } from "@calcom/ui/v2/core";
import Meta from "@calcom/ui/v2/core/Meta";
import { getLayout } from "@calcom/ui/v2/core/layouts/SettingsLayout";

interface TeamAppearanceValues {
hideBranding: boolean;
}

const ProfileView = () => {
const { t } = useLocale();
const router = useRouter();
const utils = trpc.useContext();

const mutation = trpc.useMutation("viewer.teams.update", {
onError: (err) => {
showToast(err.message, "error");
},
async onSuccess() {
await utils.invalidateQueries(["viewer.teams.get"]);
showToast(t("your_team_updated_successfully"), "success");
},
});

const form = useForm<TeamAppearanceValues>();

const { data: team, isLoading } = trpc.useQuery(["viewer.teams.get", { teamId: Number(router.query.id) }], {
onError: () => {
router.push("/settings");
},
onSuccess: (team) => {
if (team) {
form.setValue("hideBranding", team.hideBranding);
}
},
});

const isAdmin =
team && (team.membership.role === MembershipRole.OWNER || team.membership.role === MembershipRole.ADMIN);

return (
<>
<Meta title="booking_appearance" description="appearance_team_description" />
{!isLoading && (
<>
{isAdmin ? (
<Form
form={form}
handleSubmit={(values) => {
if (team) {
const hideBranding = form.getValues("hideBranding");
if (team.hideBranding !== hideBranding) {
mutation.mutate({ id: team.id, hideBranding });
}
}
}}>
<div className="relative flex items-start">
<div className="flex-grow text-sm">
<label htmlFor="hide-branding" className="font-medium text-gray-700">
{t("disable_cal_branding")}
</label>
<p className="text-gray-500">{t("team_disable_cal_branding_description")}</p>
</div>
<div className="flex-none">
<Controller
control={form.control}
name="hideBranding"
render={({ field }) => (
<Switch
defaultChecked={field.value}
onCheckedChange={(isChecked) => {
form.setValue("hideBranding", isChecked);
}}
/>
)}
/>
</div>
</div>
<Button color="primary" className="mt-8" type="submit" loading={mutation.isLoading}>
{t("update")}
</Button>
</Form>
) : (
<div className="rounded-md border border-gray-200 p-5">
<span className="text-sm text-gray-600">{t("only_owner_change")}</span>
</div>
)}
</>
)}
</>
);
};

ProfileView.getLayout = getLayout;

export default ProfileView;
export { default } from "@calcom/features/ee/teams/pages/team-appearance-view";
147 changes: 1 addition & 146 deletions apps/web/pages/v2/settings/teams/[id]/members.tsx
Original file line number Diff line number Diff line change
@@ -1,146 +1 @@
import { MembershipRole } from "@prisma/client";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { useState } from "react";

import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Icon } from "@calcom/ui/Icon";
import { Alert, Button } from "@calcom/ui/v2/core";
import Meta from "@calcom/ui/v2/core/Meta";
import { getLayout } from "@calcom/ui/v2/core/layouts/SettingsLayout";

import DisableTeamImpersonation from "@components/v2/settings/teams/DisableTeamImpersonation";
import MemberInvitationModal from "@components/v2/settings/teams/MemberInvitationModal";
import MemberListItem from "@components/v2/settings/teams/MemberListItem";
import TeamInviteList from "@components/v2/settings/teams/TeamInviteList";
import { UpgradeToFlexibleProModal } from "@components/v2/settings/teams/UpgradeToFlexibleProModal";

const MembersView = () => {
const { t } = useLocale();
const router = useRouter();
const session = useSession();

const { data: team, isLoading } = trpc.useQuery(["viewer.teams.get", { teamId: Number(router.query.id) }], {
onError: () => {
router.push("/settings");
},
});

const [showMemberInvitationModal, setShowMemberInvitationModal] = useState(false);

const isInviteOpen = !team?.membership.accepted;

const isAdmin =
team && (team.membership.role === MembershipRole.OWNER || team.membership.role === MembershipRole.ADMIN);

return (
<>
<Meta title="team_members" description="members_team_description" />
{!isLoading && (
<>
<div>
{team && (
<>
{isInviteOpen && (
<TeamInviteList
teams={[
{
id: team.id,
accepted: team.membership.accepted || false,
logo: team.logo,
name: team.name,
slug: team.slug,
role: team.membership.role,
},
]}
/>
)}
{team.membership.role === MembershipRole.OWNER &&
team.membership.isMissingSeat &&
team.requiresUpgrade ? (
<Alert
severity="warning"
title={t("hidden_team_member_title")}
message={
<>
{t("hidden_team_owner_message")} <UpgradeToFlexibleProModal teamId={team.id} />
</>
}
className="mb-4 "
/>
) : (
<>
{team.membership.isMissingSeat && (
<Alert
severity="warning"
title={t("hidden_team_member_title")}
message={t("hidden_team_member_message")}
className="mb-4 "
/>
)}
{team.membership.role === MembershipRole.OWNER && team.requiresUpgrade && (
<Alert
severity="warning"
title={t("upgrade_to_flexible_pro_title")}
message={
<span>
{t("upgrade_to_flexible_pro_message")} <br />
<UpgradeToFlexibleProModal teamId={team.id} />
</span>
}
className="mb-4"
/>
)}
</>
)}
</>
)}
{isAdmin && (
<div className="relative mb-5 flex w-full items-center ">
<Button
type="button"
color="primary"
StartIcon={Icon.FiPlus}
className="ml-auto"
onClick={() => setShowMemberInvitationModal(true)}
data-testid="new-member-button">
{t("add")}
</Button>
</div>
)}
<div>
<ul className="divide-y divide-gray-200 rounded-md border ">
{team?.members.map((member) => {
return <MemberListItem key={member.id} team={team} member={member} />;
})}
</ul>
</div>
<hr className="my-8 border-gray-200" />

{team && session.data && (
<DisableTeamImpersonation
teamId={team.id}
memberId={session.data.user.id}
disabled={isInviteOpen}
/>
)}
<hr className="my-8 border-gray-200" />
</div>
{showMemberInvitationModal && team && (
<MemberInvitationModal
isOpen={showMemberInvitationModal}
team={team}
currentMember={team.membership.role}
onExit={() => setShowMemberInvitationModal(false)}
/>
)}
</>
)}
</>
);
};

MembersView.getLayout = getLayout;

export default MembersView;
export { default } from "@calcom/features/ee/teams/pages/team-members-view";
Loading

0 comments on commit d7dc068

Please sign in to comment.