Skip to content

Commit

Permalink
workspace invite bugs worked out
Browse files Browse the repository at this point in the history
- settings page set for teams -- personal and current workspace
-- added accept invites modal
- for invites to existing users, just send a login link to the [personalHandle]/settings/team
- also show notification on userMenu avatar when there are existing invites
- changed useWorkspace hook over to optimistically setting workspace (w/ useOptimistic & useTransition, same as useTypedOptimisicQuery)
-
  • Loading branch information
adambarito committed Dec 19, 2024
1 parent 6b34707 commit e5057d2
Show file tree
Hide file tree
Showing 49 changed files with 1,119 additions and 562 deletions.
11 changes: 7 additions & 4 deletions apps/app/src/app/[handle]/_components/dash-sidebar-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ interface SidebarNavGroup {
type SidebarNavItem = SidebarNavLink | SidebarNavGroup;

export function SidebarNav() {
// const handle = props.workspace.handle;
const pathname = usePathname();
const workspace = useWorkspace();
const handle = workspace.handle;
const { workspace, handle, isPersonal } = useWorkspace();

const workspaces = useWorkspaces();

const allHandles = workspaces.map(workspace => workspace.handle);
Expand Down Expand Up @@ -127,8 +126,12 @@ export function SidebarNav() {

const topSettingsLinks: SidebarNavItem[] = [
{ title: 'profile', icon: 'profile', href: `/${handle}/settings` },
{
title: isPersonal ? 'teams' : 'team',
icon: 'users',
href: `/${handle}/settings/team`,
},
{ title: 'socials', icon: 'socials', href: `/${handle}/settings/socials` },
{ title: 'team', icon: 'users', href: `/${handle}/settings/team` },
{ title: 'apps', icon: 'apps', href: `/${handle}/settings/apps` },
{
title: 'email',
Expand Down
23 changes: 17 additions & 6 deletions apps/app/src/app/[handle]/_components/user-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export function UserAccountNav() {
imageHeight={28}
imageS3Key={personalAccount?.avatarImageS3Key}
priority
notification={user.workspaceInvites && user.workspaceInvites.length > 0}
/>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'>
Expand All @@ -63,16 +64,26 @@ export function UserAccountNav() {
</div>
</div>
<DropdownMenuSeparator />
{/* <DropdownMenuItem asChild>
<Link href={`/${user.handle}/`}>Dashboard</Link>
</DropdownMenuItem> */}
{/* <DropdownMenuItem asChild>
<Link href={`/${user.handle}/billing`}>Billing</Link>
</DropdownMenuItem> */}
<DropdownMenuItem asChild>
<Link href={`/${user.handle}/settings`}>Personal Settings</Link>
</DropdownMenuItem>

<DropdownMenuSeparator />
{user.workspaceInvites && user.workspaceInvites.length > 0 && (
<>
<DropdownMenuItem asChild>
<Link href={`/${user.handle}/settings/team`}>
<div className='flex flex-row items-center justify-between gap-2'>
<span>Invites</span>
<span className='text-sm text-slate-500'>
{user.workspaceInvites.length}
</span>
</div>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem
className='cursor-pointer'
onSelect={event => {
Expand Down
78 changes: 23 additions & 55 deletions apps/app/src/app/[handle]/_components/workspace-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePusherSocketId } from '@barely/lib/hooks/use-pusher';
import { useSetAtom } from 'jotai';

import { useUser } from '@barely/hooks/use-user';
import { useSetWorkspace, useWorkspace } from '@barely/hooks/use-workspace';
import { useWorkspace } from '@barely/hooks/use-workspace';
import { useWorkspaces } from '@barely/hooks/use-workspaces';

import { Avatar } from '@barely/ui/elements/avatar';
Expand Down Expand Up @@ -38,7 +38,13 @@ export function WorkspaceSwitcher() {
const setNewWorkspaceModalOpen = useSetAtom(showNewWorkspaceModalAtom);

const user = useUser();
const currentWorkspace = useWorkspace();
const { workspace: currentWorkspace, setWorkspace: setCurrentWorkspace } = useWorkspace(
{
onBeginSet: () => {
setSwitcherOpen(false);
},
},
);
const allWorkspaces = useWorkspaces();

const personalAccount = allWorkspaces.find(
Expand All @@ -53,11 +59,18 @@ export function WorkspaceSwitcher() {
type: toTitleCase(underscoresToSpaces(currentWorkspace.type)),
};

const onKeydown = useCallback((e: KeyboardEvent) => {
if (e.key === '.' && (e.metaKey || !e.ctrlKey)) {
setSwitcherOpen(true);
}
}, []);
const onKeydown = useCallback(
(e: KeyboardEvent) => {
if (e.key === '.' && (e.metaKey || e.ctrlKey)) {
if (switcherOpen) {
setSwitcherOpen(false);
} else {
setSwitcherOpen(true);
}
}
},
[switcherOpen, setSwitcherOpen],
);

useEffect(() => {
document.addEventListener('keydown', onKeydown);
Expand All @@ -66,56 +79,11 @@ export function WorkspaceSwitcher() {
};
}, [onKeydown]);

// useEffect(() => {
// console.log(currentWorkspace);
// }, [currentWorkspace]);

// const setCurrentWorkspace = useCallback(
// async (workspace: SessionWorkspace) => {
// console.log('setting current workspace to', workspace, '@', Date.now());
// apiUtils.workspace.current.setData(undefined, workspace);

// const newWorkspaceCartData = apiUtils.cartFunnel.byWorkspace.getInfiniteData({
// handle: workspace.handle,
// });

// if (newWorkspaceCartData) {
// apiUtils.cartFunnel.byWorkspace.setInfiniteData(
// { handle: workspace.handle },
// newWorkspaceCartData,
// );
// } else {
// apiUtils.cartFunnel.byWorkspace.setInfiniteData(
// { handle: workspace.handle },
// {
// pages: [
// {
// cartFunnels: [],
// nextCursor: undefined,
// },
// ],
// pageParams: [],
// },
// );
// }

// console.log(currentWorkspace.handle, workspace.handle);
// const { setWorkspace: setCurrentWorkspace } = useOptimisticWorkspace({
// onBeginSet: () => {
// setSwitcherOpen(false);
// if (currentWorkspace.handle === workspace.handle) return;
// if (currentPath) {
// router.push(currentPath.replace(currentWorkspace.handle, workspace.handle));
// return console.log('pushed @', Date.now());
// }
// router.push(`/${workspace.handle}`);
// console.log('pushed @', Date.now());
// },
// [apiUtils, currentPath, currentWorkspace, router, setSwitcherOpen],
// );
const { setCurrentWorkspace } = useSetWorkspace({
onBeginSet: () => {
setSwitcherOpen(false);
},
});
// });

return (
<Popover open={switcherOpen} onOpenChange={setSwitcherOpen}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Button } from '@barely/ui/elements/button';
import { Icon } from '@barely/ui/elements/icon';

export function CampaignTabs() {
const workspace = useWorkspace();
const { workspace } = useWorkspace();

const params = useParams();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { campaignTypeDisplay } from '@barely/utils/campaign';

export const AllCampaigns = () => {
const params = useParams();
const workspace = useWorkspace();
const { workspace } = useWorkspace();

const stage = z
.enum(['screening', 'approved', 'active'])
Expand Down
19 changes: 9 additions & 10 deletions apps/app/src/app/[handle]/carts/_components/cart-dialogs.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
'use client';

import { useWorkspace } from '@barely/lib/hooks/use-workspace';
import { isProduction } from '@barely/lib/utils/environment';

import { Alert } from '@barely/ui/elements/alert';

import { env } from '~/env';

export function CartDialogs() {
const {
handle,
shippingAddressPostalCode,
cartSupportEmail,
stripeConnectAccountId,
stripeConnectAccountId_devMode,
workspace: {
handle,
shippingAddressPostalCode,
cartSupportEmail,
stripeConnectAccountId,
stripeConnectAccountId_devMode,
},
} = useWorkspace();

const stripeConnected =
env.NEXT_PUBLIC_VERCEL_ENV === 'production' ?
stripeConnectAccountId
: stripeConnectAccountId_devMode;
isProduction() ? stripeConnectAccountId : stripeConnectAccountId_devMode;

const atLeastOneDialog =
!shippingAddressPostalCode || !cartSupportEmail || !stripeConnected;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { useCartFunnelContext } from '~/app/[handle]/carts/_components/cartFunne

export function CreateOrUpdateFunnelModal({ mode }: { mode: 'create' | 'update' }) {
const apiUtils = api.useUtils();
const workspace = useWorkspace();
const { workspace } = useWorkspace();

/* funnel context */
const {
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/app/[handle]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default async function DashboardLayout({
}

const defaultWorkspace = await getDefaultWorkspaceOfCurrentUser();
return redirect(`${defaultWorkspace.handle}/links`);
return redirect(`${defaultWorkspace.handle}/fm`);
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function CreateOrUpdateLinkModal(props: { mode: 'create' | 'update' }) {
label: domain.domain,
}));

const workspace = useWorkspace();
const { workspace } = useWorkspace();

const { mutateAsync: createLink } = api.link.create.useMutation({
onSuccess: async () => {
Expand Down Expand Up @@ -344,7 +344,7 @@ export function TransparentLinkDisplay({
export function AddWorkspaceSpotifyArtistId(props: { spotifyArtistId?: string }) {
const [show, setShow] = useState(true);
const apiUtils = api.useUtils();
const workspace = useWorkspace();
const { workspace } = useWorkspace();
const { mutateAsync: updateWorkspace } = api.workspace.update.useMutation();

const { data: spotifyArtistIdTaken } = api.workspace.spotifyArtistIdTaken.useQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function LinkOptionalSettings({
}) {
const { data: endpoints } = api.analyticsEndpoint.byCurrentWorkspace.useQuery();
const setShowUpgradeModal = useSetAtom(showUpgradeModalAtom);
const workspace = useWorkspace();
const { workspace } = useWorkspace();

const hasEndpoint = Object.values(endpoints ?? {}).some(endpoint => endpoint !== null);

Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/app/[handle]/playlists/all-playlists.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Icon } from '@barely/ui/elements/icon';
const AllPlaylists = () => {
const utils = api.useContext();

const workspace = useWorkspace();
const { workspace } = useWorkspace();

const [playlistsMap] = api.playlist.byWorkspaceId.useSuspenseQuery({
workspaceId: workspace.id,
Expand Down
12 changes: 5 additions & 7 deletions apps/app/src/app/[handle]/press/_components/press-kit-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,15 @@ export function PressKitForm({
}: {
initialPressKit: Promise<NormalizedPressKit>;
}) {
const { handle, bio, bookingEmail, bookingName, bookingTitle } = useWorkspace();
const {
workspace: { handle, bio, bookingEmail, bookingName, bookingTitle },
} = useWorkspace();

const initialData = use(initialPressKit);

const { data: pressKit } = api.pressKit.byWorkspace.useQuery(
{
handle,
},
{
initialData,
},
{ handle },
{ initialData },
);

const { data: infiniteMixtapeOptions } = api.mixtape.byWorkspace.useInfiniteQuery(
Expand Down
25 changes: 0 additions & 25 deletions apps/app/src/app/[handle]/products/_components/product-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,6 @@ import { productSearchParamsSchema } from '@barely/lib/server/routes/product/pro

import type { InfiniteItemsContext } from '~/app/[handle]/_types/all-items-context';

// export interface ProductCtx {
// products: AppRouterOutputs['product']['byWorkspace']['products'];
// productSelection: Selection;
// lastSelectedProductId: string | undefined;
// lastSelectedProduct:
// | AppRouterOutputs['product']['byWorkspace']['products'][number]
// | undefined;
// setProductSelection: (selection: Selection) => void;
// gridListRef: React.RefObject<HTMLDivElement>;
// focusGridList: () => void;
// showCreateProductModal: boolean;
// setShowCreateProductModal: (show: boolean) => void;
// showUpdateProductModal: boolean;
// setShowUpdateProductModal: (show: boolean) => void;
// showArchiveProductModal: boolean;
// setShowArchiveProductModal: (show: boolean) => void;
// showDeleteProductModal: boolean;
// setShowDeleteProductModal: (show: boolean) => void;
// // filters
// filters: z.infer<typeof productFilterParamsSchema>;
// pendingFiltersTransition: boolean;
// setSearch: (search: string) => void;
// toggleArchived: () => void;
// clearAllFilters: () => void;
// }
export type ProductContext = InfiniteItemsContext<
AppRouterOutputs['product']['byWorkspace']['products'][number],
z.infer<typeof productFilterParamsSchema>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface ExternalAccountCardProps {
export const ProviderAccountCard = ({ provider }: ExternalAccountCardProps) => {
const router = useRouter();
const utils = api.useUtils();
const workspace = useWorkspace();
const { workspace } = useWorkspace();

const { data: providerAccounts } = api.providerAccount.byWorkspace.useQuery({
handle: workspace.handle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import { capitalize } from '@barely/utils/text';
import { showUpgradeModalAtom } from '~/app/[handle]/settings/billing/upgrade-modal';

export function BillingSummary() {
const { plan, linkUsage, linkUsageLimit } = useWorkspace();
const {
workspace: { plan, linkUsage, linkUsageLimit },
} = useWorkspace();

const setShowUpgradeModal = useSetAtom(showUpgradeModalAtom);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function UpgradeModal(props: {
checkoutSuccessPath?: string;
checkoutCancelPath?: string;
}) {
const workspace = useWorkspace();
const { workspace } = useWorkspace();

const [showUpgradeModal, setShowUpgradeModal] = useAtom(showUpgradeModalAtom);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ export const editDomainAtom = atom<InsertDomain | undefined>(undefined);

export function DomainModal() {
const apiUtils = api.useUtils();
const workspace = useWorkspace();
// const { data: domains } = api.domain.byWorkspace.useQuery();
const { workspace } = useWorkspace();
const { domains } = useWebDomains();

const [editDomain, setEditDomain] = useAtom(editDomainAtom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const updateEmailDomainAtom = atom<InsertEmailDomain | undefined>(undefin

export function EmailDomainModal() {
const apiUtils = api.useUtils();
// const workspace = useWorkspace();
// const {workspace} = useWorkspace();

// const { domains } = useEmailDomains();

Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/app/[handle]/settings/payouts/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { isProduction } from '@barely/utils/environment';
import { DashContentHeader } from '~/app/[handle]/_components/dash-content-header';

export default function PayoutsSettingsPage() {
const workspace = useWorkspace();
const { workspace } = useWorkspace();
const params = useParams();

const needsOnboarding =
Expand Down
Loading

0 comments on commit e5057d2

Please sign in to comment.