diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index bffb357..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/.husky/pre-commit b/.husky/pre-commit index 234b476..fec151f 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,3 @@ pnpm lint +pnpm prettier pnpm build \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..175ca03 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# Ignore artifacts: +build +coverage +node_modules +pnpm-lock.yaml \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..a9a0000 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "printWidth": 120, + "tabWidth": 2, + "semi": false, + "singleQuote": false +} diff --git a/components.json b/components.json index 8c574b7..7559f63 100644 --- a/components.json +++ b/components.json @@ -14,4 +14,4 @@ "components": "@/components", "utils": "@/lib/utils" } -} \ No newline at end of file +} diff --git a/eslint.config.mjs b/eslint.config.mjs index ac5942f..ed9ee0e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,14 +1,35 @@ -import globals from "globals"; -import pluginJs from "@eslint/js"; -import tseslint from "typescript-eslint"; -import pluginReact from "eslint-plugin-react"; +import eslintConfigPrettier from "eslint-config-prettier" +import nextPlugin from "@next/eslint-plugin-next" +import tsPlugin from "@typescript-eslint/eslint-plugin" +import tsParser from "@typescript-eslint/parser" - -/** @type {import('eslint').Linter.Config[]} */ export default [ - {files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]}, - {languageOptions: { globals: globals.browser }}, - pluginJs.configs.recommended, - ...tseslint.configs.recommended, - pluginReact.configs.flat.recommended, -]; \ No newline at end of file + { + ignores: ["node_modules/**", "dist/**", ".next/**", "out/**"], + }, + { + files: ["**/*.{ts,tsx}"], + plugins: { + "@typescript-eslint": tsPlugin, + "@next/next": nextPlugin, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + }, + }, + rules: { + // Avertissement pour les 'any' + "@typescript-eslint/no-explicit-any": "warn", + + // Avertissement pour les imports/variables non utilisés + "@typescript-eslint/no-unused-vars": "warn", + + // Avertissement pour les types implicites qui pourraient être 'any' + "@typescript-eslint/no-inferrable-types": "warn", + }, + }, + eslintConfigPrettier, +] diff --git a/next.config.mjs b/next.config.mjs index 8c8bab6..3d55197 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,6 +1,6 @@ /** @type {import('next').NextConfig} */ const nextConfig = { output: "standalone", -}; +} -export default nextConfig; +export default nextConfig diff --git a/package.json b/package.json index cd66d93..3bd1214 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint", + "lint": "npx eslint .", + "prettier": "prettier --check .", + "prettier:format": "prettier --write .", "prepare": "husky" }, "dependencies": { @@ -47,6 +49,8 @@ "@types/node": "^22.9.0", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", "eslint": "^9.14.0", "eslint-config-next": "14.2.5", "eslint-config-prettier": "^9.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b510145..49d9a61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -114,6 +114,12 @@ importers: '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.13.0 + version: 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.2))(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.2) + '@typescript-eslint/parser': + specifier: ^8.13.0 + version: 8.13.0(eslint@9.14.0(jiti@1.21.6))(typescript@5.6.2) eslint: specifier: ^9.14.0 version: 9.14.0(jiti@1.21.6) diff --git a/postcss.config.mjs b/postcss.config.mjs index 1a69fd2..0dc456a 100644 --- a/postcss.config.mjs +++ b/postcss.config.mjs @@ -3,6 +3,6 @@ const config = { plugins: { tailwindcss: {}, }, -}; +} -export default config; +export default config diff --git a/src/app/(gistLayout)/layout-ui.tsx b/src/app/(gistLayout)/layout-ui.tsx index 7af4fea..78819af 100644 --- a/src/app/(gistLayout)/layout-ui.tsx +++ b/src/app/(gistLayout)/layout-ui.tsx @@ -1,16 +1,16 @@ -import { OrgListFeature } from '@/components/logic/org-list-logic' -import { Avatar, AvatarFallback, AvatarImage } from '@/components/shadcn/avatar' -import { Button } from '@/components/shadcn/button' -import { Codearea } from '@/components/shadcn/codearea' -import { Input } from '@/components/shadcn/input' -import { Sidebar, SidebarContent, SidebarHeader, SidebarProvider } from '@/components/shadcn/sidebar' -import MenuButton from '@/components/ui/menu-button' -import { Modal } from '@/components/ui/modal' -import { ProfileDropdown } from '@/components/ui/profile-dropdown' -import TooltipShortcut, { TooltipShortcutTrigger } from '@/components/ui/tooltip-shortcut' -import { getLanguage } from '@/lib/language' -import { FileCodeIcon, LucidePencil, PlusIcon } from 'lucide-react' -import { useState } from 'react' +import { OrgListFeature } from "@/components/logic/org-list-logic" +import { Avatar, AvatarFallback, AvatarImage } from "@/components/shadcn/avatar" +import { Button } from "@/components/shadcn/button" +import { Codearea } from "@/components/shadcn/codearea" +import { Input } from "@/components/shadcn/input" +import { Sidebar, SidebarContent, SidebarHeader, SidebarProvider } from "@/components/shadcn/sidebar" +import MenuButton from "@/components/ui/menu-button" +import { Modal } from "@/components/ui/modal" +import { ProfileDropdown } from "@/components/ui/profile-dropdown" +import TooltipShortcut, { TooltipShortcutTrigger } from "@/components/ui/tooltip-shortcut" +import { getLanguage } from "@/lib/language" +import { FileCodeIcon, LucidePencil, PlusIcon } from "lucide-react" +import { useState } from "react" interface GistLayoutProps { username: string @@ -22,11 +22,19 @@ interface GistLayoutProps { onLogout: () => void } -export default function GistLayout({ avatar, children, username, onMyGists, onCreateOrg, onCreateGist, onLogout }: GistLayoutProps) { - const [gistName, setGistName] = useState('') - const [gistContent, setGistContent] = useState('') +export default function GistLayout({ + avatar, + children, + username, + onMyGists, + onCreateOrg, + onCreateGist, + onLogout, +}: GistLayoutProps) { + const [gistName, setGistName] = useState("") + const [gistContent, setGistContent] = useState("") const [isGistModalOpen, setIsGistModalOpen] = useState(false) - const [orgName, setOrgName] = useState('') + const [orgName, setOrgName] = useState("") const [isOrgModalOpen, setIsOrgModalOpen] = useState(false) const language = getLanguage(gistName) @@ -124,10 +132,24 @@ function AppSidebar({
- } variant="menu" size="menu" letter="M" onClick={onMyGists} href="/mygist" className="w-full"> + } + variant="menu" + size="menu" + letter="M" + onClick={onMyGists} + href="/mygist" + className="w-full" + > My Gists - +
@@ -147,7 +169,16 @@ interface CreateGistModalProps { language: string } -function CreateGistModal({ gistName, setGistName, isGistModalOpen, setIsGistModalOpen, onCreateGist, gistContent, setGistContent, language }: CreateGistModalProps) { +function CreateGistModal({ + gistName, + setGistName, + isGistModalOpen, + setIsGistModalOpen, + onCreateGist, + gistContent, + setGistContent, + language, +}: CreateGistModalProps) { return ( - + - @@ -166,9 +197,20 @@ function CreateGistModal({ gistName, setGistName, isGistModalOpen, setIsGistModa } content={
- setGistName(e.target.value)} /> + setGistName(e.target.value)} + />
- setGistContent(e.target.value)} /> + setGistContent(e.target.value)} + />
} @@ -178,7 +220,7 @@ function CreateGistModal({ gistName, setGistName, isGistModalOpen, setIsGistModa size="sm" onClick={() => { onCreateGist(gistName, gistContent) - setGistName('') + setGistName("") setIsGistModalOpen(false) }} > @@ -210,7 +252,12 @@ function CreateOrgModal({ orgName, setOrgName, setIsOrgModalOpen, onCreateOrg, i title="Create Org" content={
- setOrgName(e.target.value)} /> + setOrgName(e.target.value)} + />
} footer={ @@ -219,7 +266,7 @@ function CreateOrgModal({ orgName, setOrgName, setIsOrgModalOpen, onCreateOrg, i size="sm" onClick={() => { onCreateOrg(orgName) - setOrgName('') + setOrgName("") setIsOrgModalOpen(false) }} > diff --git a/src/app/(gistLayout)/layout.tsx b/src/app/(gistLayout)/layout.tsx index 043bc6f..1833ae0 100644 --- a/src/app/(gistLayout)/layout.tsx +++ b/src/app/(gistLayout)/layout.tsx @@ -1,12 +1,12 @@ -'use client' +"use client" -import { ReactNode, useCallback } from 'react' -import GistLayout from './layout-ui' -import { useMe } from '@/lib/queries/user.queries' -import { useToast } from '@/components/shadcn/use-toast' -import { useCreateGist } from '@/lib/queries/gists.queries' -import { useCreateOrg } from '@/lib/queries/orgs.queries' -import { useLogout } from '@/lib/queries/auth.queries' +import { ReactNode, useCallback } from "react" +import GistLayout from "./layout-ui" +import { useMe } from "@/lib/queries/user.queries" +import { useToast } from "@/components/shadcn/use-toast" +import { useCreateGist } from "@/lib/queries/gists.queries" +import { useCreateOrg } from "@/lib/queries/orgs.queries" +import { useLogout } from "@/lib/queries/auth.queries" export default function GistLayoutFeature({ children }: { children: ReactNode }) { const { data, error } = useMe() @@ -14,16 +14,16 @@ export default function GistLayoutFeature({ children }: { children: ReactNode }) const { mutate: createGist } = useCreateGist({ onSuccess: () => { toast({ - title: 'Gist Created', - description: 'Your gist has been created successfully', + title: "Gist Created", + description: "Your gist has been created successfully", }) }, }) const { mutate: createOrg } = useCreateOrg({ onSuccess: () => { toast({ - title: 'Organization Created', - description: 'Your org has been created successfully', + title: "Organization Created", + description: "Your org has been created successfully", }) }, }) @@ -31,10 +31,10 @@ export default function GistLayoutFeature({ children }: { children: ReactNode }) const { mutate: logout } = useLogout({ onSuccess: () => { toast({ - title: 'Logged Out', - description: 'You have been logged out successfully', + title: "Logged Out", + description: "You have been logged out successfully", }) - window.location.href = '/' //sorry but couldn't find a way to redirect to the login page + window.location.href = "/" //sorry but couldn't find a way to redirect to the login page }, }) @@ -59,7 +59,14 @@ export default function GistLayoutFeature({ children }: { children: ReactNode }) } return ( - + {children} ) diff --git a/src/app/(gistLayout)/mygist/[gistId]/page-ui.tsx b/src/app/(gistLayout)/mygist/[gistId]/page-ui.tsx index bb32bec..c24fa4f 100644 --- a/src/app/(gistLayout)/mygist/[gistId]/page-ui.tsx +++ b/src/app/(gistLayout)/mygist/[gistId]/page-ui.tsx @@ -1,5 +1,5 @@ -import GistDetails from '@/components/ui/gist-details' -import { Gist } from '@/types' +import GistDetails from "@/components/ui/gist-details" +import { Gist } from "@/types" interface MyGistIdPageProps { gist: Gist @@ -10,5 +10,15 @@ interface MyGistIdPageProps { } export default function MyGistIdPage({ gist, onDownload, onSave, onDelete, onShare }: MyGistIdPageProps) { - return + return ( + + ) } diff --git a/src/app/(gistLayout)/mygist/[gistId]/page.tsx b/src/app/(gistLayout)/mygist/[gistId]/page.tsx index 4ca2b18..a404d84 100644 --- a/src/app/(gistLayout)/mygist/[gistId]/page.tsx +++ b/src/app/(gistLayout)/mygist/[gistId]/page.tsx @@ -1,9 +1,9 @@ -'use client' -import React from 'react' -import MyGistIdPage from './page-ui' -import { useGist, usePatchGistContent, usePatchGistName } from '@/lib/queries/gists.queries' -import { useToast } from '@/components/shadcn/use-toast' -import { useKeyPress } from '@/lib/hook/use-key-press' +"use client" +import React from "react" +import MyGistIdPage from "./page-ui" +import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries" +import { useToast } from "@/components/shadcn/use-toast" +import { useKeyPress } from "@/lib/hook/use-key-press" interface MyGistIdFeaturePageProps { params: { @@ -19,8 +19,8 @@ export default function MyGistIdFeaturePage({ params }: MyGistIdFeaturePageProps const { mutate: updateName } = usePatchGistName({ onSuccess: () => { toast({ - title: 'Gist Saved', - description: 'Your gist has been saved successfully', + title: "Gist Saved", + description: "Your gist has been saved successfully", }) }, }) @@ -31,16 +31,16 @@ export default function MyGistIdFeaturePage({ params }: MyGistIdFeaturePageProps const onDownload = () => { toast({ - title: 'Gist Downloaded', - description: 'Your gist has been downloaded successfully', + title: "Gist Downloaded", + description: "Your gist has been downloaded successfully", }) } const onSave = (name: string, code: string) => { updateContent({ id: gistId, content: code }) updateName({ id: gistId, name }) toast({ - title: 'Gist Saved', - description: 'Your gist has been saved successfully', + title: "Gist Saved", + description: "Your gist has been saved successfully", }) } @@ -49,7 +49,7 @@ export default function MyGistIdFeaturePage({ params }: MyGistIdFeaturePageProps } const onShare = () => { - console.log('Share') + console.log("Share") } if (!data) { diff --git a/src/app/(gistLayout)/mygist/page-ui.tsx b/src/app/(gistLayout)/mygist/page-ui.tsx index bc65ef9..fa72e54 100644 --- a/src/app/(gistLayout)/mygist/page-ui.tsx +++ b/src/app/(gistLayout)/mygist/page-ui.tsx @@ -1,12 +1,10 @@ -import { PaginationProvider } from "@/components/contexts/pagination"; -import { MyGistListFeature } from "@/components/logic/mygist-list-logic"; -import { SidebarTrigger } from "@/components/shadcn/sidebar"; -import MenuButton from "@/components/ui/menu-button"; -import { PaginationComponent } from "@/components/ui/pagination"; -import TooltipShortcut, { - TooltipShortcutTrigger, -} from "@/components/ui/tooltip-shortcut"; -import { TornadoIcon } from "lucide-react"; +import { PaginationProvider } from "@/components/contexts/pagination" +import { MyGistListFeature } from "@/components/logic/mygist-list-logic" +import { SidebarTrigger } from "@/components/shadcn/sidebar" +import MenuButton from "@/components/ui/menu-button" +import { PaginationComponent } from "@/components/ui/pagination" +import TooltipShortcut, { TooltipShortcutTrigger } from "@/components/ui/tooltip-shortcut" +import { TornadoIcon } from "lucide-react" interface MyGistPageProps {} @@ -21,10 +19,7 @@ export default function MyGistsPage({}: MyGistPageProps) { - } - variant={"menu"} - > + } variant={"menu"}> Sort by @@ -40,5 +35,5 @@ export default function MyGistsPage({}: MyGistPageProps) { - ); + ) } diff --git a/src/app/(gistLayout)/mygist/page.tsx b/src/app/(gistLayout)/mygist/page.tsx index ae115f1..3df3006 100644 --- a/src/app/(gistLayout)/mygist/page.tsx +++ b/src/app/(gistLayout)/mygist/page.tsx @@ -1,4 +1,4 @@ -import MyGistsPage from './page-ui' +import MyGistsPage from "./page-ui" interface MyGistPageProps {} diff --git a/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page-ui.tsx b/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page-ui.tsx index dd66a7a..2064803 100644 --- a/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page-ui.tsx +++ b/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page-ui.tsx @@ -1,5 +1,5 @@ -import GistDetails from '@/components/ui/gist-details' -import { Gist } from '@/types' +import GistDetails from "@/components/ui/gist-details" +import { Gist } from "@/types" interface MyOrgGistIdPageProps { gist: Gist @@ -10,6 +10,22 @@ interface MyOrgGistIdPageProps { onShare: () => void } -export default function MyOrgGistIdPage({ orgName, gist, onDownload, onSave, onDelete, onShare }: MyOrgGistIdPageProps) { - return +export default function MyOrgGistIdPage({ + orgName, + gist, + onDownload, + onSave, + onDelete, + onShare, +}: MyOrgGistIdPageProps) { + return ( + + ) } diff --git a/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx b/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx index 83cb43c..8081401 100644 --- a/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx +++ b/src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx @@ -1,9 +1,9 @@ -'use client' -import { useToast } from '@/components/shadcn/use-toast' -import GistDetails from '@/components/ui/gist-details' -import { useGist, usePatchGistContent, usePatchGistName } from '@/lib/queries/gists.queries' -import { useOrg } from '@/lib/queries/orgs.queries' -import React from 'react' +"use client" +import { useToast } from "@/components/shadcn/use-toast" +import GistDetails from "@/components/ui/gist-details" +import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries" +import { useOrg } from "@/lib/queries/orgs.queries" +import React from "react" interface MyOrgGistIdFeaturePageProps { params: { @@ -20,8 +20,8 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag const { mutate: updateName } = usePatchGistName({ onSuccess: () => { toast({ - title: 'Gist Saved', - description: 'Your gist has been saved successfully a ', + title: "Gist Saved", + description: "Your gist has been saved successfully a ", }) }, }) @@ -32,8 +32,8 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag const onDownload = () => { toast({ - title: 'Gist Downloaded', - description: 'Your gist has been downloaded successfully', + title: "Gist Downloaded", + description: "Your gist has been downloaded successfully", }) } @@ -41,13 +41,13 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag updateContent({ id: gistId, content: code }) updateName({ id: gistId, name }) toast({ - title: 'Gist Saved', - description: 'Your gist has been saved successfully', + title: "Gist Saved", + description: "Your gist has been saved successfully", }) } const onShare = () => { - console.log('Share') + console.log("Share") } const onDelete = (id: string) => { @@ -58,5 +58,14 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag return null } - return + return ( + + ) } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 068a44e..12ca66b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,53 +1,53 @@ -import { Inter as FontSans } from 'next/font/google' -import './globals.css' -import { cn } from '@/lib/utils' -import BlurBackground from '@/components/ui/blur-background' -import ThemeWrapper from '@/components/theme/theme-wrapper' -import { Toaster } from '@/components/shadcn/toaster' -import { Providers } from '@/components/theme/theme-provider' -import QueryProvider from '@/components/api/api-provider' -import Script from 'next/script' -import { Metadata } from 'next' +import { Inter as FontSans } from "next/font/google" +import "./globals.css" +import { cn } from "@/lib/utils" +import BlurBackground from "@/components/ui/blur-background" +import ThemeWrapper from "@/components/theme/theme-wrapper" +import { Toaster } from "@/components/shadcn/toaster" +import { Providers } from "@/components/theme/theme-provider" +import QueryProvider from "@/components/api/api-provider" +import Script from "next/script" +import { Metadata } from "next" -const fontSans = FontSans({ subsets: ['latin'] }) +const fontSans = FontSans({ subsets: ["latin"] }) export const metadata: Metadata = { - title: 'Create and share secure code snippets - Gists', - description: 'Gists lets developers create, share, and collaborate on secure code snippets.', - metadataBase: new URL('https://gists.app'), + title: "Create and share secure code snippets - Gists", + description: "Gists lets developers create, share, and collaborate on secure code snippets.", + metadataBase: new URL("https://gists.app"), icons: { - icon: '/favicon.png', + icon: "/favicon.png", }, keywords: [ - 'gists', - 'app', - 'code snippets', - 'code sharing', - 'developer tools', - 'programming', - 'collaboration', - 'open source', - 'project management', - 'code editor', - 'gist platform', - 'coding platform', - 'software development', - 'team collaboration', - 'version control', - 'code storage', + "gists", + "app", + "code snippets", + "code sharing", + "developer tools", + "programming", + "collaboration", + "open source", + "project management", + "code editor", + "gist platform", + "coding platform", + "software development", + "team collaboration", + "version control", + "code storage", ], openGraph: { - title: 'Create and share secure code snippets - Gists', - description: 'Gists lets developers create, share, and collaborate on secure code snippets.', - type: 'website', - url: 'https://gists.app', - siteName: 'Gists', + title: "Create and share secure code snippets - Gists", + description: "Gists lets developers create, share, and collaborate on secure code snippets.", + type: "website", + url: "https://gists.app", + siteName: "Gists", images: [ { - url: 'https://gists.app/og-card.png', + url: "https://gists.app/og-card.png", width: 1200, height: 630, - alt: 'Preview image for Gists.app', + alt: "Preview image for Gists.app", }, ], }, diff --git a/src/app/login/page-ui.tsx b/src/app/login/page-ui.tsx index 7bbb7c0..bc9860b 100644 --- a/src/app/login/page-ui.tsx +++ b/src/app/login/page-ui.tsx @@ -1,15 +1,15 @@ -import React, { useRef, useEffect, useState } from 'react' -import { gsap } from 'gsap' -import { Button } from '@/components/shadcn/button' -import { Input } from '@/components/shadcn/input' -import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from '@/components/shadcn/input-otp' -import { UseFormRegisterReturn } from 'react-hook-form' -import { Icon } from '@iconify/react' -import { useKeyPress } from '@/lib/hook/use-key-press' +import React, { useRef, useEffect, useState } from "react" +import { gsap } from "gsap" +import { Button } from "@/components/shadcn/button" +import { Input } from "@/components/shadcn/input" +import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "@/components/shadcn/input-otp" +import { UseFormRegisterReturn } from "react-hook-form" +import { Icon } from "@iconify/react" +import { useKeyPress } from "@/lib/hook/use-key-press" interface LoginProps { - step: 'initial' | 'emailInput' | 'otpInput' - email: UseFormRegisterReturn<'email'> + step: "initial" | "emailInput" | "otpInput" + email: UseFormRegisterReturn<"email"> otpValue: string onEmailClick: () => void onGitHubClick: () => void @@ -49,16 +49,24 @@ export default function Login({ useEffect(() => { if (!shouldAnimate) return - if (step === 'emailInput' && inputRef.current) { - gsap.fromTo(inputRef.current, { opacity: 0, y: -20 }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }) + if (step === "emailInput" && inputRef.current) { + gsap.fromTo(inputRef.current, { opacity: 0, y: -20 }, { opacity: 1, y: 0, duration: 0.5, ease: "power2.out" }) } - if (step === 'otpInput' && otpContainerRef.current) { - gsap.fromTo(otpContainerRef.current, { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }) + if (step === "otpInput" && otpContainerRef.current) { + gsap.fromTo( + otpContainerRef.current, + { opacity: 0, y: 20 }, + { opacity: 1, y: 0, duration: 0.5, ease: "power2.out" } + ) } - if (step === 'initial' && loginContainerRef.current) { - gsap.fromTo(loginContainerRef.current, { opacity: 0, y: 20 }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }) + if (step === "initial" && loginContainerRef.current) { + gsap.fromTo( + loginContainerRef.current, + { opacity: 0, y: 20 }, + { opacity: 1, y: 0, duration: 0.5, ease: "power2.out" } + ) } }, [step, shouldAnimate]) @@ -68,7 +76,7 @@ export default function Login({ opacity: 0, y: 20, duration: 0.5, - ease: 'power2.in', + ease: "power2.in", onComplete: () => { onBackToLoginClick() setIsAnimating(false) @@ -77,7 +85,7 @@ export default function Login({ } const renderContent = () => { - if (step === 'otpInput') { + if (step === "otpInput") { return (

Check your email

@@ -109,12 +117,18 @@ export default function Login({
- Nothing received ?{' '} - - @@ -125,22 +139,22 @@ export default function Login({

Log in to Gists

- {step === 'emailInput' && ( + {step === "emailInput" && (
{emailError &&

{emailError}

}
)} - - {step === 'emailInput' &&
} + {step === "emailInput" &&
} - - @@ -151,9 +165,7 @@ export default function Login({ return (
-
- {/* */} -
+
{/* */}
{renderContent()}
) diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index ab90942..1c2290f 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,21 +1,21 @@ -'use client' +"use client" -import { useEffect, useState, useCallback } from 'react' -import { useForm, UseFormRegisterReturn } from 'react-hook-form' -import { useToast } from '@/components/shadcn/use-toast' -import { getBackendURL } from '@/lib/utils' -import { useLocalAuth, useLocalAuthVerify } from '@/lib/queries/auth.queries' -import Login from './page-ui' -import { redirect, useRouter } from 'next/navigation' -import { useKeyPress } from '@/lib/hook/use-key-press' +import { useEffect, useState, useCallback } from "react" +import { useForm, UseFormRegisterReturn } from "react-hook-form" +import { useToast } from "@/components/shadcn/use-toast" +import { getBackendURL } from "@/lib/utils" +import { useLocalAuth, useLocalAuthVerify } from "@/lib/queries/auth.queries" +import Login from "./page-ui" +import { redirect, useRouter } from "next/navigation" +import { useKeyPress } from "@/lib/hook/use-key-press" interface FormData { email: string } export default function LoginFeature() { - const [step, setStep] = useState<'initial' | 'emailInput' | 'otpInput'>('initial') - const [otpValue, setOtpValue] = useState('') + const [step, setStep] = useState<"initial" | "emailInput" | "otpInput">("initial") + const [otpValue, setOtpValue] = useState("") const { toast } = useToast() const router = useRouter() @@ -27,40 +27,40 @@ export default function LoginFeature() { handleSubmit, formState: { errors, isValid }, } = useForm({ - mode: 'onChange', + mode: "onChange", }) - const emailRegister = register('email', { - required: 'Email is required', + const emailRegister = register("email", { + required: "Email is required", pattern: { value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, - message: 'Invalid email address', + message: "Invalid email address", }, }) const onSubmit = useCallback( (data: FormData) => { sendEmail(data.email) - localStorage.setItem('email', data.email) - setStep('otpInput') + localStorage.setItem("email", data.email) + setStep("otpInput") }, [sendEmail] ) const handleEmailClick = useCallback(() => { - if (step === 'initial') { - setStep('emailInput') - } else if (step === 'emailInput' && isValid) { + if (step === "initial") { + setStep("emailInput") + } else if (step === "emailInput" && isValid) { handleSubmit(onSubmit)() } }, [step, isValid, handleSubmit, onSubmit]) const handleGitHubClick = useCallback(() => { - window.location.href = getBackendURL() + '/auth/github' + window.location.href = getBackendURL() + "/auth/github" }, []) const handleGoogleClick = useCallback(() => { - window.location.href = getBackendURL() + '/auth/google' + window.location.href = getBackendURL() + "/auth/google" }, []) const handleOtpChange = useCallback((value: string) => { @@ -68,51 +68,51 @@ export default function LoginFeature() { }, []) const handleContinueClick = useCallback(() => { - const email = localStorage.getItem('email') + const email = localStorage.getItem("email") if (!email) { - console.error('Email not found in local storage.') + console.error("Email not found in local storage.") return } - localStorage.removeItem('email') + localStorage.removeItem("email") verifyEmail({ email: email, token: otpValue }) }, [otpValue, verifyEmail]) const handleTryAgainClick = useCallback(() => { toast({ - title: 'A new one time password has been sent.', - description: 'Please check your email.', + title: "A new one time password has been sent.", + description: "Please check your email.", }) }, [toast]) const handleBackToLoginClick = useCallback(() => { - setStep('initial') - setOtpValue('') + setStep("initial") + setOtpValue("") }, []) const handleEscapeKeyPress = useCallback( (e: KeyboardEvent) => { e.preventDefault() - router.push('/') + router.push("/") }, [router] ) - useKeyPress('Escape', handleEscapeKeyPress); + useKeyPress("Escape", handleEscapeKeyPress) useEffect(() => { if (verified) { toast({ - title: 'You have been verified.', + title: "You have been verified.", }) - redirect('/mygist') + redirect("/mygist") } }, [verified, toast]) return ( } + email={emailRegister as UseFormRegisterReturn<"email">} otpValue={otpValue} onEmailClick={handleEmailClick} onGitHubClick={handleGitHubClick} diff --git a/src/app/page.tsx b/src/app/page.tsx index 1043dcc..0b8df6f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,4 @@ -import GistsLandingLogic from '@/components/logic/gists-landing-logic' +import GistsLandingLogic from "@/components/logic/gists-landing-logic" export default function HomePage() { return ( diff --git a/src/app/robots.ts b/src/app/robots.ts index f93caf1..f2c2674 100644 --- a/src/app/robots.ts +++ b/src/app/robots.ts @@ -1,13 +1,13 @@ -import type { MetadataRoute } from 'next' +import type { MetadataRoute } from "next" export default function robots(): MetadataRoute.Robots { - const baseUrl = 'https://gists.app' + const baseUrl = "https://gists.app" return { rules: [ { - userAgent: '*', - allow: ['/', '/login'], - disallow: ['/mygist/', '/org/'], + userAgent: "*", + allow: ["/", "/login"], + disallow: ["/mygist/", "/org/"], }, ], sitemap: `${baseUrl}/sitemap.xml`, diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 4d28f28..ddbb372 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,5 +1,5 @@ export default async function sitemap() { - const baseUrl = 'https://gists.app' + const baseUrl = "https://gists.app" return [ { url: baseUrl, diff --git a/src/components/api/api-provider.tsx b/src/components/api/api-provider.tsx index 57705e2..f11e85b 100644 --- a/src/components/api/api-provider.tsx +++ b/src/components/api/api-provider.tsx @@ -1,17 +1,9 @@ -"use client"; +"use client" -import getQueryClient from "@/lib/queries/queries"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { useState } from "react"; +import getQueryClient from "@/lib/queries/queries" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" +import { useState } from "react" -export default function QueryProvider({ - children, -}: { - children: React.ReactNode; -}) { - return ( - - {children} - - ); +export default function QueryProvider({ children }: { children: React.ReactNode }) { + return {children} } diff --git a/src/components/contexts/pagination.tsx b/src/components/contexts/pagination.tsx index 20166cf..e468ec7 100644 --- a/src/components/contexts/pagination.tsx +++ b/src/components/contexts/pagination.tsx @@ -1,20 +1,14 @@ -"use client"; -import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { - createContext, - ReactNode, - useCallback, - useEffect, - useState, -} from "react"; +"use client" +import { usePathname, useRouter, useSearchParams } from "next/navigation" +import { createContext, ReactNode, useCallback, useEffect, useState } from "react" interface PaginationContextContent { - offset: number; - limit: number; - nb_pages?: number; - setOffset: (offset: number) => void; - setLimit: (limit: number) => void; - setNbPages: (nb_pages: number) => void; + offset: number + limit: number + nb_pages?: number + setOffset: (offset: number) => void + setLimit: (limit: number) => void + setNbPages: (nb_pages: number) => void } const PaginationInitialState = { @@ -24,59 +18,51 @@ const PaginationInitialState = { setOffset: (offset: number) => {}, setLimit: (limit: number) => {}, setNbPages: (nb_pages: number) => {}, -}; +} -export const PaginationContext = createContext( - PaginationInitialState, -); +export const PaginationContext = createContext(PaginationInitialState) -export function PaginationProvider({ - children, - fromUrl, -}: { - children: ReactNode; - fromUrl: boolean; -}) { - const [offset, setOffset] = useState(PaginationInitialState.offset); - const [limit, setLimit] = useState(PaginationInitialState.limit); - const [nb_pages, setNbPages] = useState(PaginationInitialState.nb_pages); - const searchParams = useSearchParams(); - const pathname = usePathname(); - const router = useRouter(); +export function PaginationProvider({ children, fromUrl }: { children: ReactNode; fromUrl: boolean }) { + const [offset, setOffset] = useState(PaginationInitialState.offset) + const [limit, setLimit] = useState(PaginationInitialState.limit) + const [nb_pages, setNbPages] = useState(PaginationInitialState.nb_pages) + const searchParams = useSearchParams() + const pathname = usePathname() + const router = useRouter() const checkOffset = useCallback( (offset: number) => { if (offset >= 0 && offset <= nb_pages * limit) { - return true; + return true } - return false; + return false }, - [nb_pages, limit], - ); + [nb_pages, limit] + ) const setOffsetHandler = useCallback( (offset: number) => { if (checkOffset(offset)) { if (fromUrl) { - const page = Math.floor(offset / limit) + 1; - router.push(`${pathname}?page=${page}`); + const page = Math.floor(offset / limit) + 1 + router.push(`${pathname}?page=${page}`) } - setOffset(offset); + setOffset(offset) } }, - [checkOffset, fromUrl, limit, pathname, router], - ); + [checkOffset, fromUrl, limit, pathname, router] + ) useEffect(() => { - if (!fromUrl) return; + if (!fromUrl) return if (searchParams.has("page")) { - const page = parseInt(searchParams.get("page") as string); - const offset = (page - 1) * limit; - console.log("offset", offset); - if (!checkOffset(offset)) return; - setOffset(offset); + const page = parseInt(searchParams.get("page") as string) + const offset = (page - 1) * limit + console.log("offset", offset) + if (!checkOffset(offset)) return + setOffset(offset) } - }, [searchParams, fromUrl, setOffset, limit, setOffsetHandler, checkOffset]); + }, [searchParams, fromUrl, setOffset, limit, setOffsetHandler, checkOffset]) return ( {children} - ); + ) } diff --git a/src/components/logic/gists-landing-logic.tsx b/src/components/logic/gists-landing-logic.tsx index b277428..10763cb 100644 --- a/src/components/logic/gists-landing-logic.tsx +++ b/src/components/logic/gists-landing-logic.tsx @@ -1,11 +1,11 @@ -'use client' +"use client" -import { useState, useEffect, useCallback, useRef } from 'react' -import { Gist } from '@/types' -import GistLanding from '@/components/ui/gist-landing' -import { toast } from '../shadcn/use-toast' -import { useRouter } from 'next/navigation' -import { useKeyPress } from '@/lib/hook/use-key-press' +import { useState, useEffect, useCallback, useRef } from "react" +import { Gist } from "@/types" +import GistLanding from "@/components/ui/gist-landing" +import { toast } from "../shadcn/use-toast" +import { useRouter } from "next/navigation" +import { useKeyPress } from "@/lib/hook/use-key-press" console.log(` _______ ________ ______ _________ ______ ________ ______ ______ @@ -22,16 +22,16 @@ console.log(` export default function GistsLandingLogic() { const router = useRouter() const [gist, setGist] = useState({ - id: 'example', - name: 'Welcome to Gists.app', - code: '', + id: "example", + name: "Welcome to Gists.app", + code: "", }) const fileInputRef = useRef(null) const [isShareDialogOpen, setIsShareDialogOpen] = useState(false) useEffect(() => { - const storedGistName = localStorage.getItem('gistName') || 'Welcome to Gists.app' - const storedGistCode = localStorage.getItem('gistCode') || '' + const storedGistName = localStorage.getItem("gistName") || "Welcome to Gists.app" + const storedGistCode = localStorage.getItem("gistCode") || "" setGist((prevGist) => ({ ...prevGist, name: storedGistName, @@ -40,7 +40,7 @@ export default function GistsLandingLogic() { }, []) const handleShare = useCallback(() => { - console.log('Share') + console.log("Share") }, []) const handleShareDialog = useCallback(() => { @@ -49,17 +49,17 @@ export default function GistsLandingLogic() { const handleGistNameChange = useCallback((newName: string) => { setGist((prevGist) => ({ ...prevGist, name: newName })) - localStorage.setItem('gistName', newName) + localStorage.setItem("gistName", newName) }, []) const handleGistCodeChange = useCallback((newCode: string) => { setGist((prevGist) => ({ ...prevGist, code: newCode })) - localStorage.setItem('gistCode', newCode) + localStorage.setItem("gistCode", newCode) }, []) const handleOpenFile = useCallback(() => { - const fileInput = document.createElement('input') - fileInput.type = 'file' + const fileInput = document.createElement("input") + fileInput.type = "file" fileInput.onchange = (event: Event) => { const target = event.target as HTMLInputElement const file = target.files?.[0] @@ -79,22 +79,22 @@ export default function GistsLandingLogic() { const handleKeyPressLogin = useCallback( (e: KeyboardEvent) => { e.preventDefault() - router.push('/login') + router.push("/login") }, [router] ) const handleDownload = useCallback((name: string, code: string) => { - const element = document.createElement('a') - const file = new Blob([code], { type: 'text/plain' }) + const element = document.createElement("a") + const file = new Blob([code], { type: "text/plain" }) element.href = URL.createObjectURL(file) element.download = name document.body.appendChild(element) element.click() document.body.removeChild(element) toast({ - title: 'Gist Downloaded', - description: 'Your gist has been downloaded successfully', + title: "Gist Downloaded", + description: "Your gist has been downloaded successfully", }) }, []) @@ -114,10 +114,10 @@ export default function GistsLandingLogic() { [handleOpenFile] ) - useKeyPress('d', handleKeyPressDownload, ['ctrlKey']) - useKeyPress('l', handleKeyPressLogin, ['ctrlKey']) - useKeyPress('o', handleKeyPressOpenFile, ['ctrlKey']) - useKeyPress('s', handleShareDialog, ['ctrlKey', 'shiftKey']) + useKeyPress("d", handleKeyPressDownload, ["ctrlKey"]) + useKeyPress("l", handleKeyPressLogin, ["ctrlKey"]) + useKeyPress("o", handleKeyPressOpenFile, ["ctrlKey"]) + useKeyPress("s", handleShareDialog, ["ctrlKey", "shiftKey"]) return ( { - setNbPages(nb_pages || 0); - }, [nb_pages, setNbPages]); + setNbPages(nb_pages || 0) + }, [nb_pages, setNbPages]) const { mutate: deleteGist } = useDeleteGist({ onSuccess: (id) => { - console.log(`Deleting gist with ID: ${id}`); + console.log(`Deleting gist with ID: ${id}`) }, - }); + }) const handleDeleteGist = (id: string) => { - deleteGist(id); - }; + deleteGist(id) + } - return ; + return } diff --git a/src/components/logic/org-list-logic.tsx b/src/components/logic/org-list-logic.tsx index 248c653..98ac730 100644 --- a/src/components/logic/org-list-logic.tsx +++ b/src/components/logic/org-list-logic.tsx @@ -1,16 +1,16 @@ -import { OrgList } from '../ui/org-list' -import { useDeleteOrgs, useOrgs } from '@/lib/queries/orgs.queries' +import { OrgList } from "../ui/org-list" +import { useDeleteOrgs, useOrgs } from "@/lib/queries/orgs.queries" export function OrgListFeature() { const { data } = useOrgs() - const { mutate } = useDeleteOrgs({ onSuccess: () => console.log('Deleted') }) + const { mutate } = useDeleteOrgs({ onSuccess: () => console.log("Deleted") }) const onDeleteTeam = (id: string) => { mutate(id) } const onGistOrg = () => { - console.log('Gist Org Clicked') + console.log("Gist Org Clicked") } const onDeleteGist = (id: string) => { @@ -21,5 +21,13 @@ export function OrgListFeature() { console.log(`Updating org with ID: ${id} and name: ${name}`) } - return + return ( + + ) } diff --git a/src/components/shadcn/accordion.tsx b/src/components/shadcn/accordion.tsx index dcc2921..1dcb08c 100644 --- a/src/components/shadcn/accordion.tsx +++ b/src/components/shadcn/accordion.tsx @@ -1,41 +1,53 @@ -'use client' +"use client" -import * as React from 'react' -import * as AccordionPrimitive from '@radix-ui/react-accordion' -import { ChevronDown } from 'lucide-react' +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" const Accordion = AccordionPrimitive.Root -const AccordionItem = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( - +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + )) -AccordionItem.displayName = 'AccordionItem' - -const AccordionTrigger = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - - svg]:rotate-180', className)} - {...props} - > - {children} - - - - ) -) AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName -const AccordionContent = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - -
{children}
-
- ) -) +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) AccordionContent.displayName = AccordionPrimitive.Content.displayName diff --git a/src/components/shadcn/avatar.tsx b/src/components/shadcn/avatar.tsx index 51e507b..9946eec 100644 --- a/src/components/shadcn/avatar.tsx +++ b/src/components/shadcn/avatar.tsx @@ -11,10 +11,7 @@ const Avatar = React.forwardRef< >(({ className, ...props }, ref) => ( )) @@ -24,11 +21,7 @@ const AvatarImage = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) AvatarImage.displayName = AvatarPrimitive.Image.displayName @@ -38,10 +31,7 @@ const AvatarFallback = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/src/components/shadcn/badge.tsx b/src/components/shadcn/badge.tsx index eedc701..747f7e2 100644 --- a/src/components/shadcn/badge.tsx +++ b/src/components/shadcn/badge.tsx @@ -1,23 +1,28 @@ -import * as React from 'react' -import { cva, type VariantProps } from 'class-variance-authority' +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" -const badgeVariants = cva('inline-flex items-center rounded-lg border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', { - variants: { - variant: { - default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', - secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', - destructive: 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', - outline: 'text-foreground', - title: 'group-hover:bg-primary group-hover:border-primary group-hover:text-primary-foreground bg-secondary text-secondary-foreground h-7', - section: 'group-focus-within:bg-primary group-focus-within:border-primary group-focus-within:text-primary-foreground bg-secondary text-secondary-foreground h-7', +const badgeVariants = cva( + "inline-flex items-center rounded-lg border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + title: + "group-hover:bg-primary group-hover:border-primary group-hover:text-primary-foreground bg-secondary text-secondary-foreground h-7", + section: + "group-focus-within:bg-primary group-focus-within:border-primary group-focus-within:text-primary-foreground bg-secondary text-secondary-foreground h-7", + }, }, - }, - defaultVariants: { - variant: 'default', - }, -}) + defaultVariants: { + variant: "default", + }, + } +) export interface BadgeProps extends React.HTMLAttributes, VariantProps {} diff --git a/src/components/shadcn/button.tsx b/src/components/shadcn/button.tsx index 48c9cce..385a217 100644 --- a/src/components/shadcn/button.tsx +++ b/src/components/shadcn/button.tsx @@ -1,8 +1,8 @@ -import * as React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import { cva, type VariantProps } from "class-variance-authority"; +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils"; +import { cn } from "@/lib/utils" const buttonVariants = cva( "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", @@ -10,15 +10,11 @@ const buttonVariants = cva( variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-light-background hover:text-foreground", - disabled: - "hover:bg-light-background hover:text-foreground opacity-50 cursor-not-allowed", + disabled: "hover:bg-light-background hover:text-foreground opacity-50 cursor-not-allowed", link: "text-primary text-base underline-offset-4 hover:underline", icon: "text-foreground bg-icon hover:bg-icon/80", menu: "text-primary-foreground hover:bg-primary hover:text-primary-foreground", @@ -37,27 +33,21 @@ const buttonVariants = cva( variant: "default", size: "default", }, - }, -); + } +) export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { - asChild?: boolean; + asChild?: boolean } const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button"; - return ( - - ); - }, -); -Button.displayName = "Button"; + const Comp = asChild ? Slot : "button" + return + } +) +Button.displayName = "Button" -export { Button, buttonVariants }; +export { Button, buttonVariants } diff --git a/src/components/shadcn/codearea.tsx b/src/components/shadcn/codearea.tsx index d933bbe..f3da5e3 100644 --- a/src/components/shadcn/codearea.tsx +++ b/src/components/shadcn/codearea.tsx @@ -1,6 +1,6 @@ -import React from 'react' -import CodeEditor from '@uiw/react-textarea-code-editor' -import { cn } from '@/lib/utils' +import React from "react" +import CodeEditor from "@uiw/react-textarea-code-editor" +import { cn } from "@/lib/utils" export interface CodeareaProps extends React.TextareaHTMLAttributes { className?: string @@ -14,19 +14,18 @@ const Codearea = ({ className, language, ...props }: CodeareaProps) => { language={language} onChange={props.onChange} className={cn( - 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', + "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className )} placeholder={props.placeholder} style={{ - backgroundColor: '#0C0D0E', - fontFamily: 'ui-monospace, SFMono-Regular, SF Mono, Consolas, Liberation Mono, Menlo, monospace' + backgroundColor: "#0C0D0E", + fontFamily: "ui-monospace, SFMono-Regular, SF Mono, Consolas, Liberation Mono, Menlo, monospace", }} /> ) } - -Codearea.displayName = 'Codearea' +Codearea.displayName = "Codearea" export { Codearea } diff --git a/src/components/shadcn/context-menu.tsx b/src/components/shadcn/context-menu.tsx index 55c2f41..3d2cb0e 100644 --- a/src/components/shadcn/context-menu.tsx +++ b/src/components/shadcn/context-menu.tsx @@ -1,10 +1,10 @@ -'use client' +"use client" -import * as React from 'react' -import * as ContextMenuPrimitive from '@radix-ui/react-context-menu' -import { Check, ChevronRight, Circle } from 'lucide-react' +import * as React from "react" +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" +import { Check, ChevronRight, Circle } from "lucide-react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" const ContextMenu = ContextMenuPrimitive.Root @@ -27,8 +27,8 @@ const ContextMenuSubTrigger = React.forwardRef< , React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => ( - , + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +const ContextMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + - ) -) -ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName - -const ContextMenuContent = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => ( - - - - ) -) + +)) ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName const ContextMenuItem = React.forwardRef< @@ -78,8 +80,8 @@ const ContextMenuItem = React.forwardRef< , React.ComponentPropsWithoutRef>( - ({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - - ) -) +const ContextMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName -const ContextMenuRadioItem = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - - - - - - - {children} - - ) -) +const ContextMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName const ContextMenuLabel = React.forwardRef< @@ -135,18 +139,27 @@ const ContextMenuLabel = React.forwardRef< React.ComponentPropsWithoutRef & { inset?: boolean } ->(({ className, inset, ...props }, ref) => ) +>(({ className, inset, ...props }, ref) => ( + +)) ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName -const ContextMenuSeparator = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => -) +const ContextMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return + return } -ContextMenuShortcut.displayName = 'ContextMenuShortcut' +ContextMenuShortcut.displayName = "ContextMenuShortcut" export { ContextMenu, diff --git a/src/components/shadcn/dialog.tsx b/src/components/shadcn/dialog.tsx index c48972b..13ee8e6 100644 --- a/src/components/shadcn/dialog.tsx +++ b/src/components/shadcn/dialog.tsx @@ -1,10 +1,10 @@ -'use client' +"use client" -import * as React from 'react' -import * as DialogPrimitive from '@radix-ui/react-dialog' -import { X } from 'lucide-react' +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" const Dialog = DialogPrimitive.Root @@ -14,22 +14,31 @@ const DialogPortal = DialogPrimitive.Portal const DialogClose = DialogPrimitive.Close -const DialogOverlay = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( )) DialogOverlay.displayName = DialogPrimitive.Overlay.displayName -const DialogContent = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, children, ...props }, ref) => ( +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( ) =>
-DialogHeader.displayName = 'DialogHeader' +const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" -const DialogFooter = ({ className, ...props }: React.HTMLAttributes) =>
-DialogFooter.displayName = 'DialogFooter' +const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" -const DialogTitle = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( - +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + )) DialogTitle.displayName = DialogPrimitive.Title.displayName -const DialogDescription = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, ...props }, ref) => ( - +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + )) DialogDescription.displayName = DialogPrimitive.Description.displayName -export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/src/components/shadcn/dropdown-menu.tsx b/src/components/shadcn/dropdown-menu.tsx index 1bd0691..2d8a21c 100644 --- a/src/components/shadcn/dropdown-menu.tsx +++ b/src/components/shadcn/dropdown-menu.tsx @@ -1,10 +1,10 @@ -'use client' +"use client" -import * as React from 'react' -import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' -import { Check, ChevronRight, Circle } from 'lucide-react' +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" const DropdownMenu = DropdownMenuPrimitive.Root @@ -26,7 +26,11 @@ const DropdownMenuSubTrigger = React.forwardRef< >(({ className, inset, children, ...props }, ref) => ( {children} @@ -35,35 +39,37 @@ const DropdownMenuSubTrigger = React.forwardRef< )) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName -const DropdownMenuSubContent = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => ( - , + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + - ) -) -DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName - -const DropdownMenuContent = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, sideOffset = 4, ...props }, ref) => ( - - - - ) -) + +)) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const DropdownMenuItem = React.forwardRef< @@ -75,8 +81,8 @@ const DropdownMenuItem = React.forwardRef< , React.ComponentPropsWithoutRef>( - ({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - - ) -) +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName -const DropdownMenuRadioItem = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, children, ...props }, ref) => ( - - - - - - - {children} - - ) -) +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const DropdownMenuLabel = React.forwardRef< @@ -132,18 +140,27 @@ const DropdownMenuLabel = React.forwardRef< React.ComponentPropsWithoutRef & { inset?: boolean } ->(({ className, inset, ...props }, ref) => ) +>(({ className, inset, ...props }, ref) => ( + +)) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName -const DropdownMenuSeparator = React.forwardRef, React.ComponentPropsWithoutRef>( - ({ className, ...props }, ref) => -) +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return + return } -DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" export { DropdownMenu, diff --git a/src/components/shadcn/input-otp.tsx b/src/components/shadcn/input-otp.tsx index dbade18..b5ccffc 100644 --- a/src/components/shadcn/input-otp.tsx +++ b/src/components/shadcn/input-otp.tsx @@ -1,22 +1,34 @@ -'use client' +"use client" -import * as React from 'react' -import { OTPInput, OTPInputContext } from 'input-otp' -import { Dot } from 'lucide-react' +import * as React from "react" +import { OTPInput, OTPInputContext } from "input-otp" +import { Dot } from "lucide-react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" -const InputOTP = React.forwardRef, React.ComponentPropsWithoutRef>(({ className, containerClassName, ...props }, ref) => ( - -)) -InputOTP.displayName = 'InputOTP' +const InputOTP = React.forwardRef, React.ComponentPropsWithoutRef>( + ({ className, containerClassName, ...props }, ref) => ( + + ) +) +InputOTP.displayName = "InputOTP" -const InputOTPGroup = React.forwardRef, React.ComponentPropsWithoutRef<'div'>>(({ className, ...props }, ref) => ( -
-)) -InputOTPGroup.displayName = 'InputOTPGroup' +const InputOTPGroup = React.forwardRef, React.ComponentPropsWithoutRef<"div">>( + ({ className, ...props }, ref) => ( +
+ ) +) +InputOTPGroup.displayName = "InputOTPGroup" -const InputOTPSlot = React.forwardRef, React.ComponentPropsWithoutRef<'div'> & { index: number }>(({ index, className, ...props }, ref) => { +const InputOTPSlot = React.forwardRef< + React.ElementRef<"div">, + React.ComponentPropsWithoutRef<"div"> & { index: number } +>(({ index, className, ...props }, ref) => { const inputOTPContext = React.useContext(OTPInputContext) const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] @@ -24,8 +36,8 @@ const InputOTPSlot = React.forwardRef, React.ComponentPr
, React.ComponentPr
) }) -InputOTPSlot.displayName = 'InputOTPSlot' - -const InputOTPSeparator = React.forwardRef, React.ComponentPropsWithoutRef<'div'>>(({ ...props }, ref) => ( -
- -
-)) -InputOTPSeparator.displayName = 'InputOTPSeparator' +InputOTPSlot.displayName = "InputOTPSlot" + +const InputOTPSeparator = React.forwardRef, React.ComponentPropsWithoutRef<"div">>( + ({ ...props }, ref) => ( +
+ +
+ ) +) +InputOTPSeparator.displayName = "InputOTPSeparator" export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } diff --git a/src/components/shadcn/input.tsx b/src/components/shadcn/input.tsx index 589dde8..4a8b350 100644 --- a/src/components/shadcn/input.tsx +++ b/src/components/shadcn/input.tsx @@ -1,6 +1,6 @@ -import * as React from 'react' +import * as React from "react" -import { cn } from '@/lib/utils' +import { cn } from "@/lib/utils" export interface InputProps extends React.InputHTMLAttributes {} @@ -9,7 +9,7 @@ const Input = React.forwardRef(({ className, type, (({ className, type, /> ) }) -Input.displayName = 'Input' +Input.displayName = "Input" export { Input } diff --git a/src/components/shadcn/label.tsx b/src/components/shadcn/label.tsx index 5341821..14be101 100644 --- a/src/components/shadcn/label.tsx +++ b/src/components/shadcn/label.tsx @@ -6,20 +6,13 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" -const labelVariants = cva( - "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" -) +const labelVariants = cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70") const Label = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps + React.ComponentPropsWithoutRef & VariantProps >(({ className, ...props }, ref) => ( - + )) Label.displayName = LabelPrimitive.Root.displayName diff --git a/src/components/shadcn/pagination.tsx b/src/components/shadcn/pagination.tsx index 1f4c286..40fedac 100644 --- a/src/components/shadcn/pagination.tsx +++ b/src/components/shadcn/pagination.tsx @@ -1,8 +1,8 @@ -import * as React from "react"; -import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"; +import * as React from "react" +import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react" -import { cn } from "@/lib/utils"; -import { ButtonProps, buttonVariants } from "./button"; +import { cn } from "@/lib/utils" +import { ButtonProps, buttonVariants } from "./button" const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (