From 25d49d04f05a45f4e5f9c0adfb5d1a284267da82 Mon Sep 17 00:00:00 2001 From: UltraLionFr Date: Sun, 7 Dec 2025 00:11:21 +0100 Subject: [PATCH] feat: ajout structure projet + config Node 20 --- .gitignore | 2 + .vscode/settings.json | 5 + app/api/auth/[...nextauth]/route.ts | 3 + .../_components/DashboardSidebar.tsx | 93 ++++ app/dashboard/_components/tutorial-form.tsx | 524 ++++++++++++++++++ app/dashboard/categories/page.tsx | 314 +++++++++++ app/dashboard/editer/[id]/page.tsx | 108 ++++ app/dashboard/layout.tsx | 37 ++ app/dashboard/nouveau/page.tsx | 101 ++++ app/dashboard/page.tsx | 207 +++++++ app/favicon.ico | Bin 25931 -> 0 bytes app/layout.tsx | 41 +- app/login/actions.ts | 7 + app/login/page.tsx | 25 + app/page.tsx | 110 ++-- app/providers.tsx | 7 + app/tutos/[slug]/markdown-renderer.tsx | 233 ++++++++ app/tutos/[slug]/page.tsx | 110 ++++ app/tutos/page.tsx | 66 +++ components/auth/LoginContent.tsx | 213 +++++++ components/home/HomeContent.tsx | 92 +++ components/home/index.ts | 1 + components/index.ts | 3 + components/layout/BackgroundEffects.tsx | 14 + components/layout/Footer.tsx | 197 +++++++ components/layout/Header.tsx | 327 +++++++++++ components/layout/index.ts | 3 + components/tutorials/CategoryFilters.tsx | 77 +++ components/tutorials/DifficultyBadge.tsx | 21 + components/tutorials/TutorialCard.tsx | 125 +++++ components/tutorials/TutorialsGrid.tsx | 24 + components/tutorials/index.ts | 4 + components/ui/HeroSection.tsx | 159 ++++++ components/ui/LogoutButton.tsx | 62 +++ components/ui/back-button.tsx | 23 + components/ui/index.ts | 3 + config/site.ts | 24 + lib/auth.ts | 60 ++ lib/prisma.ts | 18 + lib/tutorials.ts | 314 +++++++++++ middleware.ts | 17 + package.json | 57 +- pnpm-lock.yaml | 511 +++++++++++++++-- prisma/prisma/dev.db | Bin 0 -> 32768 bytes prisma/schema.prisma | 31 ++ public/android-chrome-192x192.png | Bin 0 -> 53877 bytes public/android-chrome-512x512.png | Bin 0 -> 226910 bytes public/apple-touch-icon.png | Bin 0 -> 48508 bytes public/favicon-16x16.png | Bin 0 -> 884 bytes public/favicon-32x32.png | Bin 0 -> 2763 bytes public/favicon.ico | Bin 0 -> 884 bytes public/file.svg | 1 - public/globe.svg | 1 - public/logo.webp | Bin 0 -> 2630 bytes public/next.svg | 1 - public/og-image.png | Bin 0 -> 130127 bytes public/robots.txt | 11 + public/site.webmanifest | 28 + public/vercel.svg | 1 - public/window.svg | 1 - 60 files changed, 4260 insertions(+), 157 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 app/api/auth/[...nextauth]/route.ts create mode 100644 app/dashboard/_components/DashboardSidebar.tsx create mode 100644 app/dashboard/_components/tutorial-form.tsx create mode 100644 app/dashboard/categories/page.tsx create mode 100644 app/dashboard/editer/[id]/page.tsx create mode 100644 app/dashboard/layout.tsx create mode 100644 app/dashboard/nouveau/page.tsx create mode 100644 app/dashboard/page.tsx delete mode 100644 app/favicon.ico create mode 100644 app/login/actions.ts create mode 100644 app/login/page.tsx create mode 100644 app/providers.tsx create mode 100644 app/tutos/[slug]/markdown-renderer.tsx create mode 100644 app/tutos/[slug]/page.tsx create mode 100644 app/tutos/page.tsx create mode 100644 components/auth/LoginContent.tsx create mode 100644 components/home/HomeContent.tsx create mode 100644 components/home/index.ts create mode 100644 components/index.ts create mode 100644 components/layout/BackgroundEffects.tsx create mode 100644 components/layout/Footer.tsx create mode 100644 components/layout/Header.tsx create mode 100644 components/layout/index.ts create mode 100644 components/tutorials/CategoryFilters.tsx create mode 100644 components/tutorials/DifficultyBadge.tsx create mode 100644 components/tutorials/TutorialCard.tsx create mode 100644 components/tutorials/TutorialsGrid.tsx create mode 100644 components/tutorials/index.ts create mode 100644 components/ui/HeroSection.tsx create mode 100644 components/ui/LogoutButton.tsx create mode 100644 components/ui/back-button.tsx create mode 100644 components/ui/index.ts create mode 100644 config/site.ts create mode 100644 lib/auth.ts create mode 100644 lib/prisma.ts create mode 100644 lib/tutorials.ts create mode 100644 middleware.ts create mode 100644 prisma/prisma/dev.db create mode 100644 prisma/schema.prisma create mode 100644 public/android-chrome-192x192.png create mode 100644 public/android-chrome-512x512.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon-16x16.png create mode 100644 public/favicon-32x32.png create mode 100644 public/favicon.ico delete mode 100644 public/file.svg delete mode 100644 public/globe.svg create mode 100644 public/logo.webp delete mode 100644 public/next.svg create mode 100644 public/og-image.png create mode 100644 public/robots.txt create mode 100644 public/site.webmanifest delete mode 100644 public/vercel.svg delete mode 100644 public/window.svg diff --git a/.gitignore b/.gitignore index 5ef6a52..62fcee8 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +/lib/generated/prisma diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f3d19b5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "WillLuke.nextjs.addTypesOnSave": true, + "WillLuke.nextjs.hasPrompted": true +} diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..c55a45e --- /dev/null +++ b/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,3 @@ +import { handlers } from "@/lib/auth"; + +export const { GET, POST } = handlers; diff --git a/app/dashboard/_components/DashboardSidebar.tsx b/app/dashboard/_components/DashboardSidebar.tsx new file mode 100644 index 0000000..9900c12 --- /dev/null +++ b/app/dashboard/_components/DashboardSidebar.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { + Book1Outlined, + Folder1Outlined, + PlusOutlined, +} from "@lineiconshq/free-icons"; +import { Lineicons } from "@lineiconshq/react-lineicons"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; + +const navItems = [ + { + href: "/dashboard", + label: "Tutoriels", + icon: Book1Outlined, + exact: true, + }, + { + href: "/dashboard/nouveau", + label: "Nouveau", + icon: PlusOutlined, + }, + { + href: "/dashboard/categories", + label: "Catégories", + icon: Folder1Outlined, + }, +]; + +export function DashboardSidebar() { + const pathname = usePathname(); + + const isActive = (href: string, exact?: boolean) => { + if (exact) return pathname === href; + return pathname.startsWith(href); + }; + + return ( + + ); +} diff --git a/app/dashboard/_components/tutorial-form.tsx b/app/dashboard/_components/tutorial-form.tsx new file mode 100644 index 0000000..57263d7 --- /dev/null +++ b/app/dashboard/_components/tutorial-form.tsx @@ -0,0 +1,524 @@ +"use client"; + +import { MarkdownRenderer } from "@/app/tutos/[slug]/markdown-renderer"; +import type { Category, Tutorial } from "@/lib/tutorials"; +import { + AlignTextLeftOutlined, + Books2Outlined, + CheckCircle1Outlined, + Code1Outlined, + EyeOutlined, + Folder1Outlined, + KeyboardOutlined, + Layers1Outlined, + Pencil1Outlined, + StopwatchOutlined, +} from "@lineiconshq/free-icons"; +import { Lineicons } from "@lineiconshq/react-lineicons"; +import { useCallback, useEffect, useRef, useState } from "react"; + +type TutorialFormProps = { + categories: Category[]; + action: (formData: FormData) => Promise; + submitLabel: string; + initialData?: Partial; +}; + +// Wrapper pour simplifier l'utilisation des icônes LineIcons +function Icon({ + icon, + size = 16, + className = "", +}: { + icon: React.ComponentType>; + size?: number; + className?: string; +}) { + return ; +} + +// Composant pour les labels avec icône +function FormLabel({ + icon, + children, + required, +}: { + icon: React.ComponentType>; + children: React.ReactNode; + required?: boolean; +}) { + return ( + + ); +} + +// Composant input stylisé +function FormInput({ + className = "", + ...props +}: React.InputHTMLAttributes) { + return ( + + ); +} + +// Composant select stylisé +function FormSelect({ + children, + className = "", + ...props +}: React.SelectHTMLAttributes) { + return ( + + ); +} + +// Composant textarea stylisé +function FormTextarea({ + className = "", + ...props +}: React.TextareaHTMLAttributes) { + return ( +