Skip to content

Commit ec93c2e

Browse files
Revert "[dev] [Itsnotaka] daniel/ui (#1915)" (#1928)
This reverts commit 44faa9e. Co-authored-by: Mariano Fuentes <[email protected]>
1 parent b522c10 commit ec93c2e

File tree

21 files changed

+636
-1303
lines changed

21 files changed

+636
-1303
lines changed

apps/app/src/actions/sidebar.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use server';
2+
3+
import { addYears } from 'date-fns';
4+
import { createSafeActionClient } from 'next-safe-action';
5+
import { cookies } from 'next/headers';
6+
import { z } from 'zod';
7+
8+
const schema = z.object({
9+
isCollapsed: z.boolean(),
10+
});
11+
12+
export const updateSidebarState = createSafeActionClient()
13+
.inputSchema(schema)
14+
.action(async ({ parsedInput }) => {
15+
const cookieStore = await cookies();
16+
17+
cookieStore.set({
18+
name: 'sidebar-collapsed',
19+
value: JSON.stringify(parsedInput.isCollapsed),
20+
expires: addYears(new Date(), 1),
21+
});
22+
23+
return { success: true };
24+
});

apps/app/src/app/(app)/[orgId]/layout.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { AppSidebar } from '@/components/app-sidebar';
1+
import { AnimatedLayout } from '@/components/animated-layout';
22
import { CheckoutCompleteDialog } from '@/components/dialogs/checkout-complete-dialog';
33
import { Header } from '@/components/header';
44
import { AssistantSheet } from '@/components/sheets/assistant-sheet';
5+
import { Sidebar } from '@/components/sidebar';
56
import { TriggerTokenProvider } from '@/components/trigger-token-provider';
7+
import { SidebarProvider } from '@/context/sidebar-context';
68
import { auth } from '@/utils/auth';
7-
import { SidebarInset, SidebarProvider } from '@comp/ui/sidebar';
89
import { db, Role } from '@db';
910
import dynamic from 'next/dynamic';
1011
import { cookies, headers } from 'next/headers';
@@ -14,6 +15,7 @@ import { ConditionalOnboardingTracker } from './components/ConditionalOnboarding
1415
import { ConditionalPaddingWrapper } from './components/ConditionalPaddingWrapper';
1516
import { DynamicMinHeight } from './components/DynamicMinHeight';
1617

18+
// Helper to safely parse comma-separated roles string
1719
function parseRolesString(rolesStr: string | null | undefined): Role[] {
1820
if (!rolesStr) return [];
1921
return rolesStr
@@ -36,9 +38,10 @@ export default async function Layout({
3638
const { orgId: requestedOrgId } = await params;
3739

3840
const cookieStore = await cookies();
39-
const defaultOpen = cookieStore.get('sidebar_state')?.value !== 'false';
40-
const publicAccessToken = cookieStore.get('publicAccessToken')?.value || undefined;
41+
const isCollapsed = cookieStore.get('sidebar-collapsed')?.value === 'true';
42+
let publicAccessToken = cookieStore.get('publicAccessToken')?.value || undefined;
4143

44+
// Check if user has access to this organization
4245
const session = await auth.api.getSession({
4346
headers: await headers(),
4447
});
@@ -48,11 +51,13 @@ export default async function Layout({
4851
return redirect('/auth');
4952
}
5053

54+
// First check if the organization exists and load access flags
5155
const organization = await db.organization.findUnique({
5256
where: { id: requestedOrgId },
5357
});
5458

5559
if (!organization) {
60+
// Organization doesn't exist
5661
return redirect('/auth/not-found');
5762
}
5863

@@ -65,6 +70,7 @@ export default async function Layout({
6570
});
6671

6772
if (!member) {
73+
// User doesn't have access to this organization
6874
return redirect('/auth/unauthorized');
6975
}
7076

@@ -76,10 +82,12 @@ export default async function Layout({
7682
return redirect('/no-access');
7783
}
7884

85+
// If this org is not accessible on current plan, redirect to upgrade
7986
if (!organization.hasAccess) {
8087
return redirect(`/upgrade/${organization.id}`);
8188
}
8289

90+
// If onboarding is required and user isn't already on onboarding, redirect
8391
if (!organization.onboardingCompleted) {
8492
return redirect(`/onboarding/${organization.id}`);
8593
}
@@ -95,9 +103,8 @@ export default async function Layout({
95103
triggerJobId={onboarding?.triggerJobId || undefined}
96104
initialToken={publicAccessToken || undefined}
97105
>
98-
<SidebarProvider defaultOpen={defaultOpen}>
99-
<AppSidebar organization={organization} />
100-
<SidebarInset>
106+
<SidebarProvider initialIsCollapsed={isCollapsed}>
107+
<AnimatedLayout sidebar={<Sidebar organization={organization} />} isCollapsed={isCollapsed}>
101108
{onboarding?.triggerJobId && <ConditionalOnboardingTracker onboarding={onboarding} />}
102109
<Header organizationId={organization.id} />
103110
<ConditionalPaddingWrapper>
@@ -107,7 +114,7 @@ export default async function Layout({
107114
<Suspense fallback={null}>
108115
<CheckoutCompleteDialog orgId={organization.id} />
109116
</Suspense>
110-
</SidebarInset>
117+
</AnimatedLayout>
111118
<HotKeys />
112119
</SidebarProvider>
113120
</TriggerTokenProvider>

apps/app/src/app/providers.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { JwtTokenManager } from '@/components/auth/jwt-token-manager';
44
import { env } from '@/env.mjs';
55
import { AnalyticsProvider } from '@comp/analytics';
66
import { Toaster } from '@comp/ui/sooner';
7-
import { TooltipProvider } from '@comp/ui/tooltip';
87
import { GoogleTagManager } from '@next/third-parties/google';
98
import {
109
defaultShouldDehydrateQuery,
@@ -87,11 +86,9 @@ export function Providers({ children, session }: ProviderProps) {
8786
userId={session?.user?.id ?? undefined}
8887
userEmail={session?.user?.email ?? undefined}
8988
>
90-
<TooltipProvider delayDuration={0}>
91-
<JwtTokenManager />
92-
{children}
93-
<Toaster richColors />
94-
</TooltipProvider>
89+
<JwtTokenManager />
90+
{children}
91+
<Toaster richColors />
9592
</AnalyticsProvider>
9693
</ThemeProvider>
9794
</QueryClientProvider>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { cn } from '@comp/ui/cn';
2+
3+
interface AnimatedLayoutProps {
4+
children: React.ReactNode;
5+
sidebar: React.ReactNode;
6+
isCollapsed: boolean;
7+
blurred?: boolean;
8+
}
9+
10+
export function AnimatedLayout({ children, sidebar, isCollapsed, blurred }: AnimatedLayoutProps) {
11+
return (
12+
<div className="flex h-dvh w-full overflow-hidden">
13+
<div
14+
className={cn(
15+
'bg-background hidden h-full shrink-0 overflow-y-auto border-r duration-300 ease-in-out md:block',
16+
isCollapsed ? 'w-[80px]' : 'w-[240px]',
17+
blurred ? 'pointer-events-none blur-xs select-none' : '',
18+
)}
19+
>
20+
{sidebar}
21+
</div>
22+
<div className="bg-background flex-1 overflow-y-auto">{children}</div>
23+
</div>
24+
);
25+
}

apps/app/src/components/header.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import { getFeatureFlags } from '@/app/posthog';
12
import { UserMenu } from '@/components/user-menu';
3+
import { getOrganizations } from '@/data/getOrganizations';
4+
import { auth } from '@/utils/auth';
25
import { Skeleton } from '@comp/ui/skeleton';
3-
import { SidebarTrigger } from '@comp/ui/sidebar';
6+
import { headers } from 'next/headers';
47
import { Suspense } from 'react';
58
import { AssistantButton } from './ai/chat-button';
9+
import { MobileMenu } from './mobile-menu';
610
import { NotificationBell } from './notifications/notification-bell';
711

812
export async function Header({
@@ -12,9 +16,29 @@ export async function Header({
1216
organizationId?: string;
1317
hideChat?: boolean;
1418
}) {
19+
const { organizations } = await getOrganizations();
20+
21+
// Check feature flags for menu items
22+
const session = await auth.api.getSession({
23+
headers: await headers(),
24+
});
25+
let isQuestionnaireEnabled = false;
26+
let isTrustNdaEnabled = false;
27+
if (session?.user?.id) {
28+
const flags = await getFeatureFlags(session.user.id);
29+
isQuestionnaireEnabled = flags['ai-vendor-questionnaire'] === true;
30+
isTrustNdaEnabled =
31+
flags['is-trust-nda-enabled'] === true || flags['is-trust-nda-enabled'] === 'true';
32+
}
33+
1534
return (
1635
<header className="border/40 sticky top-0 z-10 flex items-center justify-between border-b px-4 py-2 backdrop-blur-sm bg-card">
17-
<SidebarTrigger className="md:hidden" />
36+
<MobileMenu
37+
organizations={organizations}
38+
organizationId={organizationId}
39+
isQuestionnaireEnabled={isQuestionnaireEnabled}
40+
isTrustNdaEnabled={isTrustNdaEnabled}
41+
/>
1842

1943
{!hideChat && <AssistantButton />}
2044

0 commit comments

Comments
 (0)