├── supabase ├── seed.sql ├── .gitignore └── migrations │ ├── 20240112125341_remote_schema.sql │ └── 20240120133127_remote_schema.sql ├── .eslintrc.json ├── components ├── ui │ ├── readme.md │ ├── skeleton.tsx │ ├── label.tsx │ ├── textarea.tsx │ ├── input.tsx │ ├── sonner.tsx │ ├── checkbox.tsx │ ├── switch.tsx │ ├── tooltip.tsx │ ├── popover.tsx │ ├── radio-group.tsx │ ├── scroll-area.tsx │ ├── button.tsx │ └── tabs.tsx ├── editor │ ├── inline-tool │ │ └── inline-code │ │ │ └── index.css │ ├── block-tune │ │ └── alignment │ │ │ └── index.css │ ├── block-tool │ │ ├── list │ │ │ └── index.css │ │ ├── divider │ │ │ └── index.css │ │ ├── heading │ │ │ └── index.css │ │ └── paragraph │ │ │ └── index.css │ ├── tools.ts │ └── core │ │ └── editor.tsx ├── provider │ └── theme.provider.tsx ├── error-block.tsx ├── full-screen-loading.tsx ├── logo.tsx ├── mode-toogle.tsx ├── dialog │ ├── sign-out-dialog.tsx │ └── move-trash-dialog.tsx └── popover │ └── emoji-picker-popover.tsx ├── .vscode ├── extensions.json └── settings.json ├── commitlint.config.js ├── .husky ├── pre-commit └── commit-msg ├── app ├── favicon.ico ├── (main) │ ├── loading.tsx │ ├── doc │ │ ├── [uuid] │ │ │ ├── _components │ │ │ │ ├── dialog │ │ │ │ │ ├── cover-dialog │ │ │ │ │ │ ├── gallery.tsx │ │ │ │ │ │ ├── upload.tsx │ │ │ │ │ │ ├── dialog.tsx │ │ │ │ │ │ └── gradients.tsx │ │ │ │ │ ├── delete-image-dialog.tsx │ │ │ │ │ └── color-gradient-dialog.tsx │ │ │ │ ├── locked.tsx │ │ │ │ ├── retry-save.tsx │ │ │ │ ├── deleted.tsx │ │ │ │ ├── title.tsx │ │ │ │ ├── action.tsx │ │ │ │ └── editor.tsx │ │ │ ├── _schema │ │ │ │ └── index.ts │ │ │ ├── page.tsx │ │ │ └── _hooks │ │ │ │ ├── use-header.ts │ │ │ │ └── use-upload.ts │ │ ├── _components │ │ │ └── header.tsx │ │ └── page.tsx │ ├── settings │ │ ├── _components │ │ │ ├── header.tsx │ │ │ ├── change-email-dialog │ │ │ │ ├── dialog.tsx │ │ │ │ ├── request-dialog-content.tsx │ │ │ │ └── verify-dialog-content.tsx │ │ │ ├── change-password-dialog.tsx │ │ │ └── change-profile-dialog.tsx │ │ ├── _hooks │ │ │ ├── use-verify-email.ts │ │ │ ├── use-reset-password.ts │ │ │ ├── use-change-profile.ts │ │ │ └── use-request-email-change.ts │ │ └── _schema │ │ │ └── index.ts │ ├── _components │ │ ├── header.tsx │ │ ├── toggle-sidebar-button.tsx │ │ ├── sidebar-user.tsx │ │ ├── sidebar-menu.tsx │ │ └── dialog │ │ │ └── delete-dialog.tsx │ ├── _schema │ │ └── index.ts │ ├── layout.tsx │ └── _hooks │ │ ├── use-rename.ts │ │ ├── use-doc-realtime.ts │ │ ├── use-new-doc.ts │ │ ├── use-feedback.ts │ │ └── use-layout-wrapper.ts ├── (auth) │ ├── login │ │ ├── page.tsx │ │ ├── _schema │ │ │ └── index.ts │ │ ├── _hooks │ │ │ └── use-login.ts │ │ └── login.tsx │ ├── signup │ │ ├── page.tsx │ │ ├── _schema │ │ │ └── index.ts │ │ ├── _hooks │ │ │ └── use-signup.ts │ │ └── signup.tsx │ ├── forgot-password │ │ ├── page.tsx │ │ ├── _schema │ │ │ └── index.ts │ │ ├── _hooks │ │ │ └── use-forgot-password.ts │ │ └── forgot-password.tsx │ ├── reset-password │ │ ├── page.tsx │ │ ├── _schema │ │ │ └── index.ts │ │ ├── _hooks │ │ │ └── use-reset-password.ts │ │ └── reset-password.tsx │ ├── _components │ │ ├── footer.test.tsx │ │ ├── footer.tsx │ │ ├── oauth-button.tsx │ │ └── oauth-button.test.tsx │ ├── layout.tsx │ ├── forgot-password-verify │ │ ├── _schema │ │ │ └── index.ts │ │ ├── page.tsx │ │ ├── _hooks │ │ │ └── use-forgot-password-verify.ts │ │ └── forgot-password-verify.tsx │ ├── signup-verify │ │ ├── _schema │ │ │ └── index.ts │ │ ├── page.tsx │ │ ├── _hooks │ │ │ └── use-signup-verify.ts │ │ └── signup-verify.tsx │ └── complete-signup │ │ ├── _schema │ │ └── _index.ts │ │ ├── page.tsx │ │ ├── _hooks │ │ └── use-complete-profile.ts │ │ └── complete-signup.tsx ├── robots.ts ├── layout.tsx ├── not-found.tsx ├── (welcome) │ └── _components │ │ ├── heroes-auth.tsx │ │ ├── heroes-auth.test.tsx │ │ ├── nav-auth.tsx │ │ └── nav-auth.test.tsx ├── sitemap.ts ├── api │ └── v1 │ │ └── oauth │ │ └── callback │ │ └── route.ts ├── manifest.ts └── globals.css ├── constants ├── regex.ts └── color-gradient.ts ├── public └── assets │ ├── heroes.png │ ├── favicon.ico │ ├── reading.png │ ├── documents.png │ ├── logo │ ├── icon.jpg │ ├── icon.png │ ├── logo.jpg │ ├── icon_x48.png │ ├── icon_x72.png │ ├── icon_x96.png │ ├── icon_x128.png │ ├── icon_x192.png │ ├── icon_x384.png │ ├── icon_x512.png │ └── icon_x192_any.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── reading-dark.png │ ├── apple-touch-icon.png │ ├── documents-dark.png │ ├── screenshot-desktop.png │ ├── screenshot-mobile.png │ ├── google.svg │ ├── facebook.svg │ └── emoji │ ├── 1F642.svg │ ├── 1F610.svg │ ├── 2639.svg │ ├── 1F620.svg │ └── 1F600.svg ├── .prettierignore ├── postcss.config.js ├── types └── index.ts ├── lib ├── utils.ts ├── supabase │ ├── client.ts │ ├── server.ts │ └── middleware.ts ├── test │ └── index.ts ├── date.ts ├── toast.tsx └── metadata.ts ├── helper ├── error.helper.ts └── data.helper.ts ├── prettier.config.js ├── next.config.js ├── components.json ├── vitest.config.ts ├── .gitignore ├── hook ├── use-debounce-callback.ts ├── use-scroll-top.ts └── use-image-preview.ts ├── store ├── use-layout-store.ts └── use-search-store.ts ├── tsconfig.json ├── LICENSE ├── middleware.ts ├── __mocks__ └── zustand.ts ├── README.md ├── tailwind.config.ts └── package.json /supabase/seed.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /supabase/.gitignore: -------------------------------------------------------------------------------- 1 | # Supabase 2 | .branches 3 | .temp 4 | .env 5 | -------------------------------------------------------------------------------- /components/ui/readme.md: -------------------------------------------------------------------------------- 1 | #This folder user to hold shadcn ui component only 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["denoland.vscode-deno"] 3 | } 4 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {extends: ['@commitlint/config-conventional']} 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | pnpm test 5 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /constants/regex.ts: -------------------------------------------------------------------------------- 1 | export const PASSWORD_REGEX = new RegExp(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+/) 2 | -------------------------------------------------------------------------------- /public/assets/heroes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/heroes.png -------------------------------------------------------------------------------- /public/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/favicon.ico -------------------------------------------------------------------------------- /public/assets/reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/reading.png -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | build 3 | public 4 | dist 5 | 6 | 7 | # Ignore all HTML files: 8 | **/*.html 9 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/documents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/documents.png -------------------------------------------------------------------------------- /public/assets/logo/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon.jpg -------------------------------------------------------------------------------- /public/assets/logo/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon.png -------------------------------------------------------------------------------- /public/assets/logo/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/logo.jpg -------------------------------------------------------------------------------- /public/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/favicon-16x16.png -------------------------------------------------------------------------------- /public/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/favicon-32x32.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x48.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x72.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x96.png -------------------------------------------------------------------------------- /public/assets/reading-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/reading-dark.png -------------------------------------------------------------------------------- /types/index.ts: -------------------------------------------------------------------------------- 1 | export type ActionStatus = "success" | "failed" 2 | export type EmitActionStatus = (v: ActionStatus) => void 3 | -------------------------------------------------------------------------------- /public/assets/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/apple-touch-icon.png -------------------------------------------------------------------------------- /public/assets/documents-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/documents-dark.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x128.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x192.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x384.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x512.png -------------------------------------------------------------------------------- /public/assets/logo/icon_x192_any.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/logo/icon_x192_any.png -------------------------------------------------------------------------------- /public/assets/screenshot-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/screenshot-desktop.png -------------------------------------------------------------------------------- /public/assets/screenshot-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aldhyx/station-a-notion-clone/HEAD/public/assets/screenshot-mobile.png -------------------------------------------------------------------------------- /supabase/migrations/20240112125341_remote_schema.sql: -------------------------------------------------------------------------------- 1 | alter table "public"."pages" add column "is_locked" boolean; 2 | 3 | drop type "public"."cover_type_enum"; 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /components/editor/inline-tool/inline-code/index.css: -------------------------------------------------------------------------------- 1 | code.cdx-code { 2 | letter-spacing: 0.3px; 3 | @apply inline-block rounded-sm bg-destructive/10 p-1 font-mono text-xs font-normal leading-none text-red-500; 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enablePaths": [ 3 | "supabase/functions" 4 | ], 5 | "deno.lint": true, 6 | "deno.unstable": true, 7 | "[typescript]": { 8 | "editor.defaultFormatter": "esbenp.prettier-vscode" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /helper/error.helper.ts: -------------------------------------------------------------------------------- 1 | export function getErrorMessage(error: Error) { 2 | return error instanceof Error && error.message && typeof error.message === "string" 3 | ? error.message 4 | : "Something went wrong! Please check your internet connection & try again." 5 | } 6 | -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ className, ...props }: React.HTMLAttributes) { 4 | return
5 | } 6 | 7 | export { Skeleton } 8 | -------------------------------------------------------------------------------- /app/(main)/loading.tsx: -------------------------------------------------------------------------------- 1 | import { Loader } from "lucide-react" 2 | 3 | export default function Loading() { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /components/editor/block-tune/alignment/index.css: -------------------------------------------------------------------------------- 1 | .ce-block__content { 2 | /* Apply data aligment on block tools from block tunes */ 3 | @apply data-[alignment=left]:text-left data-[alignment=center]:text-center data-[alignment=right]:text-right data-[alignment=justify]:text-justify; 4 | } 5 | -------------------------------------------------------------------------------- /components/editor/block-tool/list/index.css: -------------------------------------------------------------------------------- 1 | .cdx-list { 2 | @apply ml-5 outline-none selection:bg-muted-foreground/20; 3 | } 4 | 5 | .cdx-list__item { 6 | @apply py-[2px]; 7 | } 8 | 9 | ul.cdx-list { 10 | @apply list-disc; 11 | } 12 | 13 | ol.cdx-list { 14 | @apply list-decimal; 15 | } 16 | -------------------------------------------------------------------------------- /lib/supabase/client.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserClient } from "@supabase/ssr" 2 | import { type Database } from "@/lib/supabase/database.types" 3 | 4 | const client = createBrowserClient( 5 | process.env.NEXT_PUBLIC_SUPABASE_URL!, 6 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, 7 | ) 8 | 9 | export { client } 10 | -------------------------------------------------------------------------------- /app/(auth)/login/page.tsx: -------------------------------------------------------------------------------- 1 | import FullScreenLoading from "@/components/full-screen-loading" 2 | import dynamic from "next/dynamic" 3 | 4 | const LoginPage = dynamic(() => import("./login"), { 5 | loading: () => , 6 | }) 7 | 8 | export default function LoginRootPage() { 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /app/(auth)/signup/page.tsx: -------------------------------------------------------------------------------- 1 | import FullScreenLoading from "@/components/full-screen-loading" 2 | import dynamic from "next/dynamic" 3 | 4 | const SignUpPage = dynamic(() => import("./signup"), { 5 | loading: () => , 6 | }) 7 | 8 | export default function SignUpRootPage() { 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /app/(main)/doc/[uuid]/_components/dialog/cover-dialog/gallery.tsx: -------------------------------------------------------------------------------- 1 | import Gradients from "./gradients" 2 | import Pictures from "./pictures" 3 | 4 | export default function Gallery() { 5 | return ( 6 |
7 | 8 | 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /components/provider/theme.provider.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { ThemeProvider as NextThemesProvider } from "next-themes" 4 | import { type ThemeProviderProps } from "next-themes/dist/types" 5 | 6 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 7 | return {children} 8 | } 9 | -------------------------------------------------------------------------------- /app/(auth)/forgot-password/page.tsx: -------------------------------------------------------------------------------- 1 | import FullScreenLoading from "@/components/full-screen-loading" 2 | import dynamic from "next/dynamic" 3 | 4 | const ForgotPasswordPage = dynamic(() => import("./forgot-password"), { 5 | loading: () => , 6 | }) 7 | 8 | export default function ForgotPasswordRootPage() { 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ['prettier-plugin-tailwindcss'], 3 | tailwindConfig: 'tailwind.config.ts', 4 | tailwindFunctions: ['clsx'], 5 | printWidth: 90, 6 | useTabs: false, 7 | tabWidth: 2, 8 | semi: false, 9 | singleQuote: false, 10 | quoteProps: 'as-needed', 11 | bracketSameLine: false, 12 | arrowParens: 'avoid', 13 | } 14 | -------------------------------------------------------------------------------- /app/(auth)/forgot-password/_schema/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | export const forgotPasswordSchema = z.object({ 4 | email: z 5 | .string() 6 | .min(1, {message: 'Required'}) 7 | .email({ message: "Invalid email address" }) 8 | .toLowerCase() 9 | .trim(), 10 | }) 11 | 12 | export type ForgotPasswordSchema = z.infer 13 | -------------------------------------------------------------------------------- /app/(auth)/reset-password/page.tsx: -------------------------------------------------------------------------------- 1 | import FullScreenLoading from "@/components/full-screen-loading" 2 | import dynamic from "next/dynamic" 3 | 4 | const ResetPasswordPage = dynamic(() => import("./reset-password"), { 5 | loading: () => , 6 | ssr: false, 7 | }) 8 | 9 | export default function ResetPasswordRootPage() { 10 | return 11 | } 12 | -------------------------------------------------------------------------------- /app/(auth)/login/_schema/index.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod" 2 | 3 | export const loginSchema = z.object({ 4 | email: z 5 | .string() 6 | .min(1, { message: 'Required'}) 7 | .email({ message: "Invalid email address" }) 8 | .trim(), 9 | password: z 10 | .string() 11 | .min(1, { message: 'Required' }), 12 | }) 13 | export type LoginSchema = z.infer 14 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: false, 4 | images: { 5 | remotePatterns: [ 6 | { 7 | protocol: "https", 8 | hostname: "kmpkinpcvccsiixmxpaa.supabase.co", 9 | pathname: "/storage/**", 10 | port: "", 11 | }, 12 | ], 13 | }, 14 | } 15 | 16 | module.exports = nextConfig 17 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "stone", 10 | "cssVariables": true 11 | }, 12 | "aliases": { 13 | "components": "@/components", 14 | "utils": "@/lib/utils" 15 | } 16 | } -------------------------------------------------------------------------------- /lib/test/index.ts: -------------------------------------------------------------------------------- 1 | import { afterEach } from "vitest" 2 | import { cleanup } from "@testing-library/react" 3 | import "@testing-library/jest-dom/vitest" 4 | import { loadEnvConfig } from "@next/env" 5 | 6 | // load env.test.local or env.test 7 | loadEnvConfig(process.cwd()) 8 | 9 | // to make it works like Jest (auto-mocking) 10 | vi.mock("zustand") 11 | 12 | afterEach(() => { 13 | cleanup() 14 | }) 15 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config" 2 | import react from "@vitejs/plugin-react" 3 | import { resolve } from "path" 4 | 5 | export default defineConfig({ 6 | plugins: [react()], 7 | test: { 8 | alias: [{ find: "@", replacement: resolve(__dirname, "./") }], 9 | environment: "jsdom", 10 | setupFiles: ["./lib/test/index.ts"], 11 | globals: true, 12 | }, 13 | }) 14 | -------------------------------------------------------------------------------- /app/(auth)/_components/footer.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { render, screen } from "@testing-library/react" 3 | import Footer from "@/app/(auth)/_components/footer" 4 | 5 | it("render without error", () => { 6 | render(