Old teams page in v2 (#4553)
* Old teams page in v2 * Tea nav item fix * Team creation modal converted to v2 * Updated emptyscreen and shell button Co-authored-by: Peer Richelsen <peeroke@gmail.com>pull/4486/head^2
parent
00071bcdf0
commit
1b2707d4f0
|
@ -3,9 +3,9 @@ import { useRef, useState } from "react";
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { Button } from "@calcom/ui";
|
||||
import { Alert } from "@calcom/ui/Alert";
|
||||
import { Dialog, DialogContent, DialogFooter } from "@calcom/ui/Dialog";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import { Alert } from "@calcom/ui/v2/core/Alert";
|
||||
import { Dialog, DialogContent, DialogFooter } from "@calcom/ui/v2/core/Dialog";
|
||||
|
||||
interface Props {
|
||||
isOpen: boolean;
|
||||
|
@ -28,15 +28,14 @@ export default function TeamCreate(props: Props) {
|
|||
},
|
||||
});
|
||||
|
||||
const createTeam = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const createTeam = () => {
|
||||
createTeamMutation.mutate({ name: nameRef?.current?.value });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog open={props.isOpen} onOpenChange={props.onClose}>
|
||||
<DialogContent>
|
||||
<DialogContent type="creation" actionText={t("create_new_team")} actionOnClick={createTeam}>
|
||||
<div className="mb-4 sm:flex sm:items-start">
|
||||
<div className="bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<Icon.FiUsers className="text-brandcontrast h-6 w-6" />
|
||||
|
@ -50,7 +49,7 @@ export default function TeamCreate(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form onSubmit={createTeam}>
|
||||
<form>
|
||||
<div className="mb-4">
|
||||
<label htmlFor="name" className="block text-sm font-medium text-gray-700">
|
||||
{t("name")}
|
||||
|
@ -66,18 +65,6 @@ export default function TeamCreate(props: Props) {
|
|||
/>
|
||||
</div>
|
||||
{errorMessage && <Alert severity="error" title={errorMessage} />}
|
||||
<DialogFooter>
|
||||
<Button type="button" color="secondary" onClick={props.onClose}>
|
||||
{t("cancel")}
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
className="ltr:ml-2 rtl:mr-2"
|
||||
data-testid="create-new-team-button">
|
||||
{t("create_team")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useState } from "react";
|
||||
|
||||
import showToast from "@calcom/lib/notification";
|
||||
import { inferQueryOutput, trpc } from "@calcom/trpc/react";
|
||||
import showToast from "@calcom/ui/v2/core/notifications";
|
||||
|
||||
import TeamListItem from "./TeamListItem";
|
||||
|
||||
|
|
|
@ -4,19 +4,19 @@ import Link from "next/link";
|
|||
import classNames from "@calcom/lib/classNames";
|
||||
import { getPlaceholderAvatar } from "@calcom/lib/getPlaceholderAvatar";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import showToast from "@calcom/lib/notification";
|
||||
import { inferQueryOutput, trpc } from "@calcom/trpc/react";
|
||||
import Button from "@calcom/ui/Button";
|
||||
import ConfirmationDialogContent from "@calcom/ui/ConfirmationDialogContent";
|
||||
import { Dialog, DialogTrigger } from "@calcom/ui/Dialog";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import Button from "@calcom/ui/v2/core/Button";
|
||||
import ConfirmationDialogContent from "@calcom/ui/v2/core/ConfirmationDialogContent";
|
||||
import { Dialog, DialogTrigger } from "@calcom/ui/v2/core/Dialog";
|
||||
import Dropdown, {
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@calcom/ui/Dropdown";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import { Tooltip } from "@calcom/ui/Tooltip";
|
||||
} from "@calcom/ui/v2/core/Dropdown";
|
||||
import { Tooltip } from "@calcom/ui/v2/core/Tooltip";
|
||||
import showToast from "@calcom/ui/v2/core/notifications";
|
||||
|
||||
import Avatar from "@components/ui/Avatar";
|
||||
|
||||
|
@ -84,7 +84,7 @@ export default function TeamListItem(props: Props) {
|
|||
!isInvitee && "group hover:bg-neutral-50"
|
||||
)}>
|
||||
{!isInvitee ? (
|
||||
<Link href={"/settings/teams/" + team.id}>
|
||||
<Link href={"/settings/teams/" + team.id + "/profile"}>
|
||||
<a className="flex-grow cursor-pointer truncate text-sm" title={`${team.name}`}>
|
||||
{teamInfo}
|
||||
</a>
|
||||
|
@ -112,7 +112,6 @@ export default function TeamListItem(props: Props) {
|
|||
<DropdownMenuItem>
|
||||
<Button
|
||||
color="minimal"
|
||||
size="sm"
|
||||
className="w-full rounded-none font-medium"
|
||||
StartIcon={Icon.FiCheck}
|
||||
onClick={acceptInvite}>
|
||||
|
@ -121,8 +120,7 @@ export default function TeamListItem(props: Props) {
|
|||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
color="warn"
|
||||
size="sm"
|
||||
color="destructive"
|
||||
className="w-full rounded-none font-medium"
|
||||
StartIcon={Icon.FiX}
|
||||
onClick={declineInvite}>
|
||||
|
@ -158,11 +156,10 @@ export default function TeamListItem(props: Props) {
|
|||
<DropdownMenuContent hidden={hideDropdown}>
|
||||
{isAdmin && (
|
||||
<DropdownMenuItem>
|
||||
<Link href={"/settings/teams/" + team.id}>
|
||||
<Link href={"/settings/teams/" + team.id + "/profile"}>
|
||||
<a>
|
||||
<Button
|
||||
color="minimal"
|
||||
size="sm"
|
||||
className="w-full rounded-none font-medium"
|
||||
StartIcon={Icon.FiEdit2}>
|
||||
{t("edit_team")}
|
||||
|
@ -176,7 +173,6 @@ export default function TeamListItem(props: Props) {
|
|||
<a target="_blank">
|
||||
<Button
|
||||
color="minimal"
|
||||
size="sm"
|
||||
className="w-full rounded-none font-medium"
|
||||
StartIcon={Icon.FiExternalLink}>
|
||||
{t("preview_team")}
|
||||
|
@ -193,8 +189,7 @@ export default function TeamListItem(props: Props) {
|
|||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
color="warn"
|
||||
size="sm"
|
||||
color="destructive"
|
||||
className="w-full rounded-none font-medium"
|
||||
StartIcon={Icon.FiTrash}>
|
||||
{t("disband_team")}
|
||||
|
@ -220,7 +215,7 @@ export default function TeamListItem(props: Props) {
|
|||
<DialogTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
color="warn"
|
||||
color="destructive"
|
||||
size="lg"
|
||||
StartIcon={Icon.FiLogOut}
|
||||
className="w-full rounded-none"
|
||||
|
|
|
@ -17,6 +17,7 @@ const V2_WHITELIST = [
|
|||
"/event-types",
|
||||
"/workflows",
|
||||
"/apps",
|
||||
"/teams",
|
||||
"/success",
|
||||
"/auth/login",
|
||||
];
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import UserV2OptInBanner from "@calcom/features/users/components/UserV2OptInBanner";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { MobileNavigationMoreItems } from "@calcom/ui/Shell";
|
||||
import { Shell } from "@calcom/ui/v2";
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import { useState } from "react";
|
||||
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import { Shell } from "@calcom/ui/v2";
|
||||
import { Alert } from "@calcom/ui/v2/core/Alert";
|
||||
import Button from "@calcom/ui/v2/core/Button";
|
||||
import EmptyScreen from "@calcom/ui/v2/core/EmptyScreen";
|
||||
|
||||
import SkeletonLoaderTeamList from "@components/team/SkeletonloaderTeamList";
|
||||
import TeamCreateModal from "@components/team/TeamCreateModal";
|
||||
import TeamList from "@components/team/TeamList";
|
||||
|
||||
function Teams() {
|
||||
const { t } = useLocale();
|
||||
const [showCreateTeamModal, setShowCreateTeamModal] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
|
||||
const { data, isLoading } = trpc.useQuery(["viewer.teams.list"], {
|
||||
onError: (e) => {
|
||||
setErrorMessage(e.message);
|
||||
},
|
||||
});
|
||||
|
||||
const teams = data?.filter((m) => m.accepted) || [];
|
||||
const invites = data?.filter((m) => !m.accepted) || [];
|
||||
|
||||
return (
|
||||
<Shell
|
||||
heading={t("teams")}
|
||||
subtitle={t("create_manage_teams_collaborative")}
|
||||
CTA={
|
||||
<Button type="button" onClick={() => setShowCreateTeamModal(true)}>
|
||||
<Icon.FiPlus className="inline-block h-3.5 w-3.5 text-white group-hover:text-black ltr:mr-2 rtl:ml-2" />
|
||||
{t("new")}
|
||||
</Button>
|
||||
}>
|
||||
<>
|
||||
{!!errorMessage && <Alert severity="error" title={errorMessage} />}
|
||||
{showCreateTeamModal && (
|
||||
<TeamCreateModal isOpen={showCreateTeamModal} onClose={() => setShowCreateTeamModal(false)} />
|
||||
)}
|
||||
{invites.length > 0 && (
|
||||
<div className="mb-4">
|
||||
<h1 className="mb-2 text-lg font-medium">{t("open_invitations")}</h1>
|
||||
<TeamList teams={invites} />
|
||||
</div>
|
||||
)}
|
||||
{isLoading && <SkeletonLoaderTeamList />}
|
||||
{!teams.length && !isLoading && (
|
||||
<EmptyScreen
|
||||
Icon={Icon.FiUsers}
|
||||
headline={t("no_teams")}
|
||||
description={t("no_teams_description")}
|
||||
buttonRaw={
|
||||
<Button color="secondary" onClick={() => setShowCreateTeamModal(true)}>
|
||||
{t("create_team")}
|
||||
</Button>
|
||||
}
|
||||
buttonOnClick={() => setShowCreateTeamModal(true)}
|
||||
/>
|
||||
)}
|
||||
{teams.length > 0 && <TeamList teams={teams} />}
|
||||
</>
|
||||
</Shell>
|
||||
);
|
||||
}
|
||||
|
||||
Teams.requiresLicense = false;
|
||||
|
||||
export default Teams;
|
|
@ -382,6 +382,8 @@ export type NavigationItemType = {
|
|||
icon?: SVGComponent;
|
||||
child?: NavigationItemType[];
|
||||
pro?: true;
|
||||
onlyMobile?: boolean;
|
||||
onlyDesktop?: boolean;
|
||||
isCurrent?: ({
|
||||
item,
|
||||
isChild,
|
||||
|
@ -411,6 +413,12 @@ const navigation: NavigationItemType[] = [
|
|||
href: "/availability",
|
||||
icon: Icon.FiClock,
|
||||
},
|
||||
{
|
||||
name: "teams",
|
||||
href: "/teams",
|
||||
icon: Icon.FiUsers,
|
||||
onlyDesktop: true,
|
||||
},
|
||||
{
|
||||
name: "apps",
|
||||
href: "/apps",
|
||||
|
@ -480,7 +488,7 @@ const { desktopNavigationItems, mobileNavigationBottomItems, mobileNavigationMor
|
|||
// We filter out the "more" separator in desktop navigation
|
||||
if (item.name !== MORE_SEPARATOR_NAME) items.desktopNavigationItems.push(item);
|
||||
// Items for mobile bottom navigation
|
||||
if (index < moreSeparatorIndex + 1) items.mobileNavigationBottomItems.push(item);
|
||||
if (index < moreSeparatorIndex + 1 && !item.onlyDesktop) items.mobileNavigationBottomItems.push(item);
|
||||
// Items for the "more" menu in mobile navigation
|
||||
else items.mobileNavigationMoreItems.push(item);
|
||||
return items;
|
||||
|
|
Loading…
Reference in New Issue