Formated Files

This commit is contained in:
Ahmad 2024-02-15 20:49:19 -05:00
parent d5631b309a
commit e768d9181f
No known key found for this signature in database
GPG key ID: 8FD8A93530D182BF
138 changed files with 1829 additions and 1851 deletions

View file

@ -1,21 +1,21 @@
import Link from "next/link";
import { auth } from "@clerk/nextjs";
import { redirect } from "next/navigation";
import { HelpCircle, User2 } from "lucide-react";
import Link from 'next/link';
import { auth } from '@clerk/nextjs';
import { redirect } from 'next/navigation';
import { HelpCircle, User2 } from 'lucide-react';
import { db } from "@/lib/db";
import { Hint } from "@/components/hint";
import { Skeleton } from "@/components/ui/skeleton";
import { FormPopover } from "@/components/form/form-popover";
import { MAX_FREE_BOARDS } from "@/constants/boards";
import { getAvailableCount } from "@/lib/org-limit";
import { checkSubscription } from "@/lib/subscription";
import { db } from '@/lib/db';
import { Hint } from '@/components/hint';
import { Skeleton } from '@/components/ui/skeleton';
import { FormPopover } from '@/components/form/form-popover';
import { MAX_FREE_BOARDS } from '@/constants/boards';
import { getAvailableCount } from '@/lib/org-limit';
import { checkSubscription } from '@/lib/subscription';
export const BoardList = async () => {
const { orgId } = auth();
if (!orgId) {
return redirect("/select-org");
return redirect('/select-org');
}
const boards = await db.board.findMany({
@ -23,7 +23,7 @@ export const BoardList = async () => {
orgId,
},
orderBy: {
createdAt: "desc",
createdAt: 'desc',
},
});
@ -31,32 +31,32 @@ export const BoardList = async () => {
const isPro = await checkSubscription();
return (
<div className="space-y-4">
<div className="flex items-center font-semibold text-lg text-neutral-700">
<User2 className="h-6 w-6 mr-2" />
<div className='space-y-4'>
<div className='flex items-center text-lg font-semibold text-neutral-700'>
<User2 className='mr-2 h-6 w-6' />
Your boards
</div>
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
<div className='grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4'>
{boards.map((board) => (
<Link
key={board.id}
href={`/board/${board.id}`}
className="group relative aspect-video bg-no-repeat bg-center bg-cover bg-sky-700 rounded-sm h-full w-full p-2 overflow-hidden"
className='group relative aspect-video h-full w-full overflow-hidden rounded-sm bg-sky-700 bg-cover bg-center bg-no-repeat p-2'
style={{ backgroundImage: `url(${board.imageThumbUrl})` }}
>
<div className="absolute inset-0 bg-black/30 group-hover:bg-black/40 transition" />
<p className="relative font-semibold text-white">{board.title}</p>
<div className='absolute inset-0 bg-black/30 transition group-hover:bg-black/40' />
<p className='relative font-semibold text-white'>{board.title}</p>
</Link>
))}
<FormPopover sideOffset={10} side="right">
<FormPopover sideOffset={10} side='right'>
<div
role="button"
className="aspect-video relative h-full w-full bg-muted rounded-sm flex flex-col gap-y-1 items-center justify-center hover:opacity-75 transition"
role='button'
className='relative flex aspect-video h-full w-full flex-col items-center justify-center gap-y-1 rounded-sm bg-muted transition hover:opacity-75'
>
<p className="text-sm">Create new board</p>
<span className="text-xs">
<p className='text-sm'>Create new board</p>
<span className='text-xs'>
{isPro
? "Unlimited"
? 'Unlimited'
: `${MAX_FREE_BOARDS - availableCount} remaining`}
</span>
<Hint
@ -65,7 +65,7 @@ export const BoardList = async () => {
Free Workspaces can have up to 5 open boards. For unlimited boards upgrade this workspace.
`}
>
<HelpCircle className="absolute bottom-2 right-2 h-[14px] w-[14px]" />
<HelpCircle className='absolute bottom-2 right-2 h-[14px] w-[14px]' />
</Hint>
</div>
</FormPopover>
@ -76,15 +76,15 @@ export const BoardList = async () => {
BoardList.Skeleton = function SkeletonBoardList() {
return (
<div className="grid gird-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<Skeleton className="aspect-video h-full w-full p-2" />
<div className='gird-cols-2 grid gap-4 sm:grid-cols-3 lg:grid-cols-4'>
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
<Skeleton className='aspect-video h-full w-full p-2' />
</div>
);
};

View file

@ -1,10 +1,10 @@
"use client";
'use client';
import Image from "next/image";
import { CreditCard } from "lucide-react";
import Image from 'next/image';
import { CreditCard } from 'lucide-react';
import { useOrganization } from "@clerk/nextjs";
import { Skeleton } from "@/components/ui/skeleton";
import { useOrganization } from '@clerk/nextjs';
import { Skeleton } from '@/components/ui/skeleton';
interface InfoProps {
isPro: boolean;
@ -18,20 +18,20 @@ export const Info = ({ isPro }: InfoProps) => {
}
return (
<div className="flex items-center gap-x-4">
<div className="w-[60px] h-[60px] relative">
<div className='flex items-center gap-x-4'>
<div className='relative h-[60px] w-[60px]'>
<Image
fill
src={organization?.imageUrl!}
alt="Organization Logo"
className="rounded-md object-cover"
alt='Organization Logo'
className='rounded-md object-cover'
/>
</div>
<div className="space-y-1">
<p className="font-semibold text-xl">{organization?.name}</p>
<div className="flex items-center text-xs text-muted-foreground">
<CreditCard className="h-3 w-3 mr-1" />
{isPro ? "Pro" : "Free"}
<div className='space-y-1'>
<p className='text-xl font-semibold'>{organization?.name}</p>
<div className='flex items-center text-xs text-muted-foreground'>
<CreditCard className='mr-1 h-3 w-3' />
{isPro ? 'Pro' : 'Free'}
</div>
</div>
</div>
@ -40,15 +40,15 @@ export const Info = ({ isPro }: InfoProps) => {
Info.Skeleton = function SkeletonInfo() {
return (
<div className="flex items-center gap-x-4">
<div className="w-[60px] h-[60px] relative">
<Skeleton className="w-full h-full absolute" />
<div className='flex items-center gap-x-4'>
<div className='relative h-[60px] w-[60px]'>
<Skeleton className='absolute h-full w-full' />
</div>
<div className="space-y-2">
<Skeleton className="h-10 w-[200px]" />
<div className="flex items-center">
<Skeleton className="h-4 w-4 mr-2" />
<Skeleton className="h-4 w-[100px]" />
<div className='space-y-2'>
<Skeleton className='h-10 w-[200px]' />
<div className='flex items-center'>
<Skeleton className='mr-2 h-4 w-4' />
<Skeleton className='h-4 w-[100px]' />
</div>
</div>
</div>

View file

@ -1,8 +1,8 @@
"use client";
'use client';
import { useEffect } from "react";
import { useParams } from "next/navigation";
import { useOrganizationList } from "@clerk/nextjs";
import { useEffect } from 'react';
import { useParams } from 'next/navigation';
import { useOrganizationList } from '@clerk/nextjs';
export const OrgControl = () => {
const params = useParams();

View file

@ -1,27 +1,27 @@
import { auth } from "@clerk/nextjs";
import { redirect } from "next/navigation";
import { auth } from '@clerk/nextjs';
import { redirect } from 'next/navigation';
import { db } from "@/lib/db";
import { ActivityItem } from "@/components/activity-item";
import { Skeleton } from "@/components/ui/skeleton";
import { db } from '@/lib/db';
import { ActivityItem } from '@/components/activity-item';
import { Skeleton } from '@/components/ui/skeleton';
export const ActivityList = async () => {
const { orgId } = auth();
if (!orgId) redirect("/select-org");
if (!orgId) redirect('/select-org');
const auditLogs = await db.auditLog.findMany({
where: {
orgId,
},
orderBy: {
createdAt: "desc",
createdAt: 'desc',
},
});
return (
<ol className="space-y-4 mt-4">
<p className="hidden last:block text-xs text-center text-muted-foreground">
<ol className='mt-4 space-y-4'>
<p className='hidden text-center text-xs text-muted-foreground last:block'>
No activity found inside this organization
</p>
{auditLogs.map((log) => (
@ -33,12 +33,12 @@ export const ActivityList = async () => {
ActivityList.Skeleton = function ActivityListSkeleton() {
return (
<ol className="space-y-4 mt-4">
<Skeleton className="w-[80%] h-14" />
<Skeleton className="w-[50%] h-14" />
<Skeleton className="w-[70%] h-14" />
<Skeleton className="w-[80%] h-14" />
<Skeleton className="w-[75%] h-14" />
<ol className='mt-4 space-y-4'>
<Skeleton className='h-14 w-[80%]' />
<Skeleton className='h-14 w-[50%]' />
<Skeleton className='h-14 w-[70%]' />
<Skeleton className='h-14 w-[80%]' />
<Skeleton className='h-14 w-[75%]' />
</ol>
);
};

View file

@ -1,18 +1,18 @@
import { Suspense } from "react";
import { Suspense } from 'react';
import { Separator } from "@/components/ui/separator";
import { Separator } from '@/components/ui/separator';
import { Info } from "../_components/info";
import { ActivityList } from "./_components/activity-list";
import { checkSubscription } from "@/lib/subscription";
import { Info } from '../_components/info';
import { ActivityList } from './_components/activity-list';
import { checkSubscription } from '@/lib/subscription';
const ActivityPage = async () => {
const isPro = await checkSubscription();
return (
<div className="w-full">
<div className='w-full'>
<Info isPro={isPro} />
<Separator className="my-2" />
<Separator className='my-2' />
<Suspense fallback={<ActivityList.Skeleton />}>
<ActivityList />
</Suspense>

View file

@ -1,11 +1,11 @@
"use client";
'use client';
import { toast } from "sonner";
import { toast } from 'sonner';
import { stripeRedirect } from "@/actions/stripe-redirect";
import { Button } from "@/components/ui/button";
import { useAction } from "@/hooks/use-action";
import { useProModal } from "@/hooks/use-pro-modal";
import { stripeRedirect } from '@/actions/stripe-redirect';
import { Button } from '@/components/ui/button';
import { useAction } from '@/hooks/use-action';
import { useProModal } from '@/hooks/use-pro-modal';
interface SubscriptionButtonProps {
isPro: boolean;
@ -32,8 +32,8 @@ export const SubscriptionButton = ({ isPro }: SubscriptionButtonProps) => {
};
return (
<Button disabled={isLoading} onClick={onClick} variant="primary">
{isPro ? "Manage Subscription" : "Upgrade to Pro"}
<Button disabled={isLoading} onClick={onClick} variant='primary'>
{isPro ? 'Manage Subscription' : 'Upgrade to Pro'}
</Button>
);
};

View file

@ -1,19 +1,19 @@
import { checkSubscription } from "@/lib/subscription";
import { Separator } from "@/components/ui/separator";
import { checkSubscription } from '@/lib/subscription';
import { Separator } from '@/components/ui/separator';
import { Info } from "../_components/info";
import { SubscriptionButton } from "./_components/subscription-button";
import { Info } from '../_components/info';
import { SubscriptionButton } from './_components/subscription-button';
const BillingPage = async () => {
const isPro = await checkSubscription();
return (
<div className="w-full">
<div className='w-full'>
<Info isPro={isPro} />
<Separator className="my-2" />
<Separator className='my-2' />
<SubscriptionButton isPro={isPro} />
</div>
);
};
export default BillingPage;
export default BillingPage;

View file

@ -1,13 +1,13 @@
import { startCase } from "lodash";
import { auth } from "@clerk/nextjs";
import { startCase } from 'lodash';
import { auth } from '@clerk/nextjs';
import { OrgControl } from "./_components/org-control";
import { OrgControl } from './_components/org-control';
export async function generateMetadata() {
const { orgSlug } = auth();
return {
title: startCase(orgSlug ?? "organization"),
title: startCase(orgSlug ?? 'organization'),
};
}

View file

@ -1,19 +1,19 @@
import { Suspense } from "react";
import { Suspense } from 'react';
import { Separator } from "@/components/ui/separator";
import { checkSubscription } from "@/lib/subscription";
import { Separator } from '@/components/ui/separator';
import { checkSubscription } from '@/lib/subscription';
import { Info } from "./_components/info";
import { BoardList } from "./_components/board-list";
import { Info } from './_components/info';
import { BoardList } from './_components/board-list';
const OrganizationIdPage = async () => {
const isPro = await checkSubscription();
return (
<div className="w-full mb-20">
<div className='mb-20 w-full'>
<Info isPro={isPro} />
<Separator className="my-4" />
<div className="px-2 md:px-4">
<Separator className='my-4' />
<div className='px-2 md:px-4'>
<Suspense fallback={<BoardList.Skeleton />}>
<BoardList />
</Suspense>

View file

@ -1,19 +1,19 @@
import { OrganizationProfile } from "@clerk/nextjs";
import { OrganizationProfile } from '@clerk/nextjs';
const SettingsPage = () => {
return (
<div className="w-full">
<div className='w-full'>
<OrganizationProfile
appearance={{
elements: {
rootBox: {
boxShadow: "none",
width: "100%",
boxShadow: 'none',
width: '100%',
},
card: {
border: "1px solid #e5e5e5",
boxShadow: "none",
width: "100%",
border: '1px solid #e5e5e5',
boxShadow: 'none',
width: '100%',
},
},
}}

View file

@ -1,10 +1,10 @@
import { Sidebar } from "../_components/sidebar";
import { Sidebar } from '../_components/sidebar';
const OrganizationLayout = ({ children }: { children: React.ReactNode }) => {
return (
<main className="pt-20 md:pt-24 px-4 max-w-6xl 2xl:max-w-screen-xl mx-auto">
<div className="flex gap-x-7">
<div className="w-64 shrink-0 hidden md:block">
<main className='mx-auto max-w-6xl px-4 pt-20 md:pt-24 2xl:max-w-screen-xl'>
<div className='flex gap-x-7'>
<div className='hidden w-64 shrink-0 md:block'>
<Sidebar />
</div>
{children}