Skip to content

Commit

Permalink
add teams
Browse files Browse the repository at this point in the history
  • Loading branch information
xvvvyz committed Oct 30, 2024
1 parent eaec78d commit cce1d81
Show file tree
Hide file tree
Showing 101 changed files with 3,053 additions and 462 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Add the following to your `.env` file:
```dotenv
NEXT_PUBLIC_SUPABASE_ANON_KEY=<SUPABASE_ANON_KEY>
NEXT_PUBLIC_SUPABASE_URL=<SUPABSE_API_URL>
SUPABASE_SERVICE_KEY=<SUPABASE_SERVICE_KEY>
```

Generate types and start the dev server:
Expand All @@ -43,7 +44,8 @@ Vercel common secrets:
Vercel environment secrets:

- LEMON_SQUEEZY_API_KEY
- LEMON_SQUEEZY_VARIANT_ID
- LEMON_SQUEEZY_VARIANT_ID_PRO
- LEMON_SQUEEZY_VARIANT_ID_TEAM
- LEMON_SQUEEZY_WEBHOOK_SECRET
- RESEND_API_KEY
- SUPABASE_SERVICE_KEY
Expand Down
28 changes: 19 additions & 9 deletions app/(pages)/(with-nav)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import NotificationsSubscription from '@/_components/notifications-subscription'
import canInsertSubjectOnCurrentPlan from '@/_queries/can-insert-subject-on-current-plan';
import countNotifications from '@/_queries/count-notifications';
import getCurrentUser from '@/_queries/get-current-user';
import listTeams from '@/_queries/list-teams';
import Bars3Icon from '@heroicons/react/24/outline/Bars3Icon';
import DocumentTextIcon from '@heroicons/react/24/outline/DocumentTextIcon';
import HomeIcon from '@heroicons/react/24/outline/HomeIcon';
Expand All @@ -20,14 +21,20 @@ interface LayoutProps {
}

const Layout = async ({ children }: LayoutProps) => {
const [{ data: canCreateSubject }, { count }, user] = await Promise.all([
canInsertSubjectOnCurrentPlan(),
countNotifications(),
getCurrentUser(),
]);

const user = await getCurrentUser();
if (!user) return null;

const [{ data: canCreateSubject }, { count }, { data: teams }] =
await Promise.all([
user.app_metadata.is_client
? Promise.resolve({ data: false })
: canInsertSubjectOnCurrentPlan(),
countNotifications(),
user.app_metadata.is_client ? Promise.resolve({ data: [] }) : listTeams(),
]);

if (!teams) return null;

return (
<>
<div className="mx-auto max-w-lg pb-[calc(theme('spacing.16')+5.2rem)]">
Expand Down Expand Up @@ -61,7 +68,7 @@ const Layout = async ({ children }: LayoutProps) => {
</div>
Inbox
</Button>
{!user.user_metadata.is_client && (
{!user.app_metadata.is_client && (
<>
<Drawer.Root>
<Drawer.Trigger asChild>
Expand All @@ -77,7 +84,10 @@ const Layout = async ({ children }: LayoutProps) => {
<Drawer.Content>
<Drawer.Title>Add new menu</Drawer.Title>
<Drawer.Description />
<AddNewMenuItems canCreateSubject={canCreateSubject} />
<AddNewMenuItems
canCreateSubject={canCreateSubject}
user={user}
/>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
Expand Down Expand Up @@ -109,7 +119,7 @@ const Layout = async ({ children }: LayoutProps) => {
</Drawer.Root>
</>
)}
<AccountMenu user={user} />
<AccountMenu user={user} teams={teams} />
</nav>
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions app/(pages)/(with-nav)/subjects/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const Page = async () => {
teamSubjects,
} = subjects.reduce(
(acc, subject) => {
if (subject.team_id === user.id) {
if (subject.team_id === user.app_metadata.active_team_id) {
if (subject.archived) acc.archivedTeamSubjects.push(subject);
else acc.teamSubjects.push(subject);
} else {
Expand All @@ -48,17 +48,17 @@ const Page = async () => {
{!clientSubjects.length && !teamSubjects.length && (
<Empty>
<InformationCircleIcon className="w-7" />
{user.user_metadata.is_client ? (
{user.app_metadata.is_client ? (
'No active subjects.'
) : (
<div>
Create a <span className="text-fg-2">subject</span> using the
yellow
Create a new <span className="text-fg-2">subject</span> using
the yellow
<br />
<div className="mr-1.5 inline-flex size-4 items-center justify-center rounded-full bg-accent-1 text-bg-1">
<PlusIcon className="inline w-3 stroke-2" />
</div>
button for eternal glory.
button. Let&rsquo;s make changes.
</div>
)}
</Empty>
Expand Down
30 changes: 14 additions & 16 deletions app/(pages)/@modal/(layout)/hey/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,22 @@ const Page = async () => {
title={`Hey, ${user.user_metadata.first_name}!`}
/>
<div className="px-4 pb-8 sm:px-8">
<div className="prose">
<div className="prose max-w-[26rem]">
<p>
At llog, our mission is to empower behavior professionals and their
clients by crafting intuitive and effective software tools that make
lasting behavior change more&nbsp;attainable.
</p>
<p className="max-w-[25rem]">
Your feedback is invaluable as we evolve and improve. Whether you
have thoughts, ideas, concerns or even dreams, we&rsquo;d love to
hear from you. Feel free to drop us a message at{' '}
<Button href="mailto:[email protected]" variant="link">
[email protected]
</Button>{' '}
or{' '}
<Button href="https://cal.com/llogapp/chat" variant="link">
schedule a call
</Button>
.
clients with tools that make lasting behavior change
more&nbsp;attainable. Your feedback is invaluable as we evolve and
improve. Whether you have thoughts, ideas, concerns or even dreams:{' '}
<span className="whitespace-nowrap">
<Button href="mailto:[email protected]" variant="link">
email us
</Button>{' '}
or{' '}
<Button href="https://cal.com/llogapp/chat" variant="link">
book a call
</Button>
.
</span>
</p>
<p>Happy behavior hacking!</p>
<p className="text-fg-4">~ Cade, Founder</p>
Expand Down
12 changes: 9 additions & 3 deletions app/(pages)/@modal/(layout)/subjects/[subjectId]/edit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import * as Modal from '@/_components/modal';
import PageModalHeader from '@/_components/page-modal-header';
import SubjectForm from '@/_components/subject-form';
import getSubject from '@/_queries/get-subject';
import listTags from '@/_queries/list-tags';

interface PageProps {
params: Promise<{ subjectId: string }>;
}

const Page = async ({ params }: PageProps) => {
const { subjectId } = await params;
const { data: subject } = await getSubject(subjectId);
if (!subject) return null;

const [{ data: subject }, { data: tags }] = await Promise.all([
getSubject(subjectId),
listTags(),
]);

if (!subject || !tags) return null;

return (
<Modal.Content>
<PageModalHeader title="Edit subject" />
<SubjectForm subject={subject} />
<SubjectForm subject={subject} tags={tags} />
</Modal.Content>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const Page = async ({ params }: PageProps) => {
]);

if (!subject || !eventType) return null;
const isTeamMember = !!user && subject.team_id === user.id;

const isTeamMember =
!!user && subject.team_id === user.app_metadata.active_team_id;

return (
<Modal.Content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ const Page = async ({ params }: PageProps) => {
!subject ||
!subjects ||
!protocol ||
!user ||
subject.team_id !== user.id
!user
) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ const Page = async ({ params }: PageProps) => {
!subject ||
!subjects ||
!protocol ||
!user ||
subject.team_id !== user.id
!user
) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ const Page = async ({ params }: PageProps) => {
!subject ||
!subjects ||
!protocol ||
!user ||
subject.team_id !== user.id
!user
) {
return null;
}
Expand Down
18 changes: 12 additions & 6 deletions app/(pages)/@modal/(layout)/subjects/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import * as Modal from '@/_components/modal';
import PageModalHeader from '@/_components/page-modal-header';
import SubjectForm from '@/_components/subject-form';
import listTags from '@/_queries/list-tags';

const Page = () => (
<Modal.Content>
<PageModalHeader title="New subject" />
<SubjectForm />
</Modal.Content>
);
const Page = async () => {
const { data: tags } = await listTags();
if (!tags) return null;

return (
<Modal.Content>
<PageModalHeader title="New subject" />
<SubjectForm tags={tags} />
</Modal.Content>
);
};

export default Page;
23 changes: 23 additions & 0 deletions app/(pages)/@modal/(layout)/teams/[teamId]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as Modal from '@/_components/modal';
import PageModalHeader from '@/_components/page-modal-header';
import TeamForm from '@/_components/team-form';
import getTeam from '@/_queries/get-team';

interface PageProps {
params: Promise<{ teamId: string }>;
}

const Page = async ({ params }: PageProps) => {
const { teamId } = await params;
const { data: team } = await getTeam(teamId);
if (!team) return null;

return (
<Modal.Content>
<PageModalHeader title="Edit organization" />
<TeamForm team={team} />
</Modal.Content>
);
};

export default Page;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PageModalLoading from '@/_components/page-modal-loading';

const Loading = PageModalLoading;

export default Loading;
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import Button from '@/_components/button';
import CheckoutButton from '@/_components/checkout-button';
import * as Modal from '@/_components/modal';
import PageModalHeader from '@/_components/page-modal-header';
import UpgradePlanButton from '@/_components/upgrade-plan-button';
import SubscriptionVariantName from '@/_constants/enum-subscription-variant-name';
import getCurrentUser from '@/_queries/get-current-user';
import getTeam from '@/_queries/get-team';

const Page = async () => {
const user = await getCurrentUser();
if (!user) return;
interface PageProps {
params: Promise<{ teamId: string }>;
}

const Page = async ({ params }: PageProps) => {
const { teamId } = await params;

const [{ data: team }, user] = await Promise.all([
getTeam(teamId),
getCurrentUser(),
]);

if (!team || !user) return;

return (
<Modal.Content>
Expand Down Expand Up @@ -51,7 +63,11 @@ const Page = async () => {
Close
</Button>
</Modal.Close>
<UpgradePlanButton user={user} />
<CheckoutButton
disabled={!!team.subscriptions.length}
teamId={teamId}
variant={SubscriptionVariantName.Pro}
/>
</div>
</div>
</Modal.Content>
Expand Down
5 changes: 5 additions & 0 deletions app/(pages)/@modal/(layout)/teams/create/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import PageModalLoading from '@/_components/page-modal-loading';

const Loading = PageModalLoading;

export default Loading;
12 changes: 12 additions & 0 deletions app/(pages)/@modal/(layout)/teams/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Modal from '@/_components/modal';
import PageModalHeader from '@/_components/page-modal-header';
import TeamForm from '@/_components/team-form';

const Page = async () => (
<Modal.Content>
<PageModalHeader title="New organization" />
<TeamForm />
</Modal.Content>
);

export default Page;
4 changes: 1 addition & 3 deletions app/(pages)/subjects/[subjectId]/join/[shareCode]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ const Page = async ({ params }: PageProps) => {
if (!subject) {
await (
await createServerSupabaseClient()
).rpc('join_subject_as_manager', {
share_code: shareCode,
});
).rpc('join_subject_as_client', { share_code: shareCode });
}

redirect(`/subjects/${subjectId}`);
Expand Down
Loading

0 comments on commit cce1d81

Please sign in to comment.