From 09e2716e4645bc14adc0762d19f22f980a45b252 Mon Sep 17 00:00:00 2001 From: cdricms <36056008+cdricms@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:31:01 +0100 Subject: [PATCH 1/4] Reduced docker image size --- .dockerignore | 1 + Dockerfile | 10 +++++++++- latosa-frontend/next.config.ts | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ce2c29a --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +./latosa-frontend/node_modules/ diff --git a/Dockerfile b/Dockerfile index f32490b..cd099dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,13 +7,21 @@ WORKDIR /app # Copy project files COPY ./latosa-frontend/ . +ENV NODE_ENV=production RUN deno install # Install Next.js dependencies RUN deno task build +# Move everything to the standalone +RUN cp -r public .next/standalone/public +RUN cp -r .next/static .next/standalone/.next/static +RUN mv .next/standalone/server.js .next/standalone/server.cjs + +RUN rm -r ./node_modules + # Expose the default Next.js port EXPOSE 3000 # Start the Next.js app -CMD ["deno", "task", "start"] +CMD ["deno", "run", "--allow-env", "--allow-read", "--allow-sys", "--allow-net", ".next/standalone/server.cjs"] diff --git a/latosa-frontend/next.config.ts b/latosa-frontend/next.config.ts index 7921f35..4119f6e 100644 --- a/latosa-frontend/next.config.ts +++ b/latosa-frontend/next.config.ts @@ -2,6 +2,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + output: "standalone", }; export default nextConfig; From fa3dd398e0f96fa4f370d5f97eb885264e282db5 Mon Sep 17 00:00:00 2001 From: cdricms <36056008+cdricms@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:48:41 +0100 Subject: [PATCH 2/4] Added dashboard --- latosa-frontend/app/(auth)/dashboard/page.tsx | 57 ++ latosa-frontend/app/(auth)/layout.tsx | 34 + .../app/{ => (main)}/contact/page.tsx | 0 .../app/{ => (main)}/gallery/page.tsx | 6 +- .../app/(main)/history/[slug]/page.tsx | 80 ++ .../app/{ => (main)}/history/page.tsx | 6 +- latosa-frontend/app/{ => (main)}/layout.tsx | 2 +- .../app/{ => (main)}/login/page.tsx | 0 latosa-frontend/app/{ => (main)}/page.tsx | 0 latosa-frontend/app/globals.css | 18 +- latosa-frontend/app/history/[slug]/page.tsx | 63 -- latosa-frontend/components/app-sidebar.tsx | 175 ++++ latosa-frontend/components/nav-main.tsx | 73 ++ latosa-frontend/components/nav-projects.tsx | 89 ++ latosa-frontend/components/nav-user.tsx | 128 +++ latosa-frontend/components/team-switcher.tsx | 95 +++ latosa-frontend/components/ui/breadcrumb.tsx | 115 +++ latosa-frontend/components/ui/collapsible.tsx | 11 + .../components/ui/dropdown-menu.tsx | 204 +++++ latosa-frontend/components/ui/separator.tsx | 33 + latosa-frontend/components/ui/sidebar.tsx | 788 ++++++++++++++++++ latosa-frontend/components/ui/skeleton.tsx | 15 + latosa-frontend/components/ui/tooltip.tsx | 32 + latosa-frontend/hooks/use-mobile.tsx | 23 + latosa-frontend/package-lock.json | 169 +++- latosa-frontend/package.json | 6 +- latosa-frontend/tailwind.config.ts | 16 +- 27 files changed, 2157 insertions(+), 81 deletions(-) create mode 100644 latosa-frontend/app/(auth)/dashboard/page.tsx create mode 100644 latosa-frontend/app/(auth)/layout.tsx rename latosa-frontend/app/{ => (main)}/contact/page.tsx (100%) rename latosa-frontend/app/{ => (main)}/gallery/page.tsx (60%) create mode 100644 latosa-frontend/app/(main)/history/[slug]/page.tsx rename latosa-frontend/app/{ => (main)}/history/page.tsx (81%) rename latosa-frontend/app/{ => (main)}/layout.tsx (96%) rename latosa-frontend/app/{ => (main)}/login/page.tsx (100%) rename latosa-frontend/app/{ => (main)}/page.tsx (100%) delete mode 100644 latosa-frontend/app/history/[slug]/page.tsx create mode 100644 latosa-frontend/components/app-sidebar.tsx create mode 100644 latosa-frontend/components/nav-main.tsx create mode 100644 latosa-frontend/components/nav-projects.tsx create mode 100644 latosa-frontend/components/nav-user.tsx create mode 100644 latosa-frontend/components/team-switcher.tsx create mode 100644 latosa-frontend/components/ui/breadcrumb.tsx create mode 100644 latosa-frontend/components/ui/collapsible.tsx create mode 100644 latosa-frontend/components/ui/dropdown-menu.tsx create mode 100644 latosa-frontend/components/ui/separator.tsx create mode 100644 latosa-frontend/components/ui/sidebar.tsx create mode 100644 latosa-frontend/components/ui/skeleton.tsx create mode 100644 latosa-frontend/components/ui/tooltip.tsx create mode 100644 latosa-frontend/hooks/use-mobile.tsx diff --git a/latosa-frontend/app/(auth)/dashboard/page.tsx b/latosa-frontend/app/(auth)/dashboard/page.tsx new file mode 100644 index 0000000..36e2957 --- /dev/null +++ b/latosa-frontend/app/(auth)/dashboard/page.tsx @@ -0,0 +1,57 @@ +import { AppSidebar } from "@/components/app-sidebar"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; +import { + SidebarInset, + SidebarProvider, + SidebarTrigger, +} from "@/components/ui/sidebar"; + +export default function Page() { + return ( + + + +
+
+ + + {/* + + + + Building Your Application + + + + + + Data Fetching + + + + */} +
+
+
+
+
+
+
+
+
+
+ + + ); +} diff --git a/latosa-frontend/app/(auth)/layout.tsx b/latosa-frontend/app/(auth)/layout.tsx new file mode 100644 index 0000000..87abb96 --- /dev/null +++ b/latosa-frontend/app/(auth)/layout.tsx @@ -0,0 +1,34 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "@/app/globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/latosa-frontend/app/contact/page.tsx b/latosa-frontend/app/(main)/contact/page.tsx similarity index 100% rename from latosa-frontend/app/contact/page.tsx rename to latosa-frontend/app/(main)/contact/page.tsx diff --git a/latosa-frontend/app/gallery/page.tsx b/latosa-frontend/app/(main)/gallery/page.tsx similarity index 60% rename from latosa-frontend/app/gallery/page.tsx rename to latosa-frontend/app/(main)/gallery/page.tsx index 0c12a83..5a9a15b 100644 --- a/latosa-frontend/app/gallery/page.tsx +++ b/latosa-frontend/app/(main)/gallery/page.tsx @@ -1,7 +1,3 @@ export default function Gallery() { - return ( - <> - - - ) + return <>; } diff --git a/latosa-frontend/app/(main)/history/[slug]/page.tsx b/latosa-frontend/app/(main)/history/[slug]/page.tsx new file mode 100644 index 0000000..bea6a2e --- /dev/null +++ b/latosa-frontend/app/(main)/history/[slug]/page.tsx @@ -0,0 +1,80 @@ +"use server"; + +export default async function HistoryDetails({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + const default_img: string = + "https://shadcnblocks.com/images/block/placeholder-dark-1.svg"; + const default_style: string = + "blog-paragraph mb-5 text-muted-foreground md:text-base lg:max-w-2xl lg:text-lg"; + const sub_header_style: string = + "py-12 mb-3 text-pretty text-xl font-semibold md:mb-4 md:text-4xl lg:mb-6 lg:max-w-3xl lg:text-3xl"; + + return ( +
+
+
+

+ {slug} +

+
+
+
+

Subtitle 1

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias! +

+
+
+ {slug} +
+
+

Subtitle 2

+

+ Lorem ipsm dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias! +

+
+
+ {slug} +
+
+

Subtitle 3

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias! +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias! +

+
+
+
+
+ ); +} diff --git a/latosa-frontend/app/history/page.tsx b/latosa-frontend/app/(main)/history/page.tsx similarity index 81% rename from latosa-frontend/app/history/page.tsx rename to latosa-frontend/app/(main)/history/page.tsx index 893b516..d27089e 100644 --- a/latosa-frontend/app/history/page.tsx +++ b/latosa-frontend/app/(main)/history/page.tsx @@ -1,9 +1,9 @@ import Blog from "@/components/blog"; export default function History() { - return( + return (
- +
- ) + ); } diff --git a/latosa-frontend/app/layout.tsx b/latosa-frontend/app/(main)/layout.tsx similarity index 96% rename from latosa-frontend/app/layout.tsx rename to latosa-frontend/app/(main)/layout.tsx index 5a322db..798ff81 100644 --- a/latosa-frontend/app/layout.tsx +++ b/latosa-frontend/app/(main)/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; -import "./globals.css"; +import "@/app/globals.css"; import Navbar from "@/components/nav-bar"; import Footer from "@/components/footer"; diff --git a/latosa-frontend/app/login/page.tsx b/latosa-frontend/app/(main)/login/page.tsx similarity index 100% rename from latosa-frontend/app/login/page.tsx rename to latosa-frontend/app/(main)/login/page.tsx diff --git a/latosa-frontend/app/page.tsx b/latosa-frontend/app/(main)/page.tsx similarity index 100% rename from latosa-frontend/app/page.tsx rename to latosa-frontend/app/(main)/page.tsx diff --git a/latosa-frontend/app/globals.css b/latosa-frontend/app/globals.css index 11d8278..296a425 100644 --- a/latosa-frontend/app/globals.css +++ b/latosa-frontend/app/globals.css @@ -8,7 +8,7 @@ body { @layer base { :root { - /* Define your custom padding value */ + /* Define your custom padding value */ --background: 0 0% 100%; --foreground: 0 0% 3.9%; --card: 0 0% 100%; @@ -34,6 +34,14 @@ body { --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; --radius: 0.5rem; + --sidebar-background: 0 0% 98%; + --sidebar-foreground: 240 5.3% 26.1%; + --sidebar-primary: 240 5.9% 10%; + --sidebar-primary-foreground: 0 0% 98%; + --sidebar-accent: 240 4.8% 95.9%; + --sidebar-accent-foreground: 240 5.9% 10%; + --sidebar-border: 220 13% 91%; + --sidebar-ring: 217.2 91.2% 59.8%; } .dark { @@ -61,6 +69,14 @@ body { --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; --chart-5: 340 75% 55%; + --sidebar-background: 240 5.9% 10%; + --sidebar-foreground: 240 4.8% 95.9%; + --sidebar-primary: 224.3 76.3% 48%; + --sidebar-primary-foreground: 0 0% 100%; + --sidebar-accent: 240 3.7% 15.9%; + --sidebar-accent-foreground: 240 4.8% 95.9%; + --sidebar-border: 240 3.7% 15.9%; + --sidebar-ring: 217.2 91.2% 59.8%; } } diff --git a/latosa-frontend/app/history/[slug]/page.tsx b/latosa-frontend/app/history/[slug]/page.tsx deleted file mode 100644 index d37d138..0000000 --- a/latosa-frontend/app/history/[slug]/page.tsx +++ /dev/null @@ -1,63 +0,0 @@ -"use server" - -export default async function HistoryDetails({ - params, -}: { - params: Promise<{ slug: string }>; -}) { - const { slug } = await params; - const default_img: string = "https://shadcnblocks.com/images/block/placeholder-dark-1.svg" - const default_style: string = "blog-paragraph mb-5 text-muted-foreground md:text-base lg:max-w-2xl lg:text-lg" - const sub_header_style: string = "py-12 mb-3 text-pretty text-xl font-semibold md:mb-4 md:text-4xl lg:mb-6 lg:max-w-3xl lg:text-3xl" - - return ( -
-
-
-

- {slug} -

-
-
-
-

Subtitle 1

-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! -

-
-
- {slug} - -
-
-

Subtitle 2

-

- Lorem ipsm dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! -

-
-
- {slug} - -
-
-

Subtitle 3

-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! -

-

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! -

-
-
-
-
- ) -} diff --git a/latosa-frontend/components/app-sidebar.tsx b/latosa-frontend/components/app-sidebar.tsx new file mode 100644 index 0000000..bab033f --- /dev/null +++ b/latosa-frontend/components/app-sidebar.tsx @@ -0,0 +1,175 @@ +"use client"; + +import * as React from "react"; +import { + AudioWaveform, + BookOpen, + Bot, + Command, + Frame, + GalleryVerticalEnd, + Map, + PieChart, + Settings2, + SquareTerminal, +} from "lucide-react"; + +import { NavMain } from "@/components/nav-main"; +import { NavProjects } from "@/components/nav-projects"; +import { NavUser } from "@/components/nav-user"; +import { TeamSwitcher } from "@/components/team-switcher"; +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarRail, +} from "@/components/ui/sidebar"; + +// This is sample data. +const data = { + user: { + name: "shadcn", + email: "m@example.com", + avatar: "/avatars/shadcn.jpg", + }, + teams: [ + { + name: "Acme Inc", + logo: GalleryVerticalEnd, + plan: "Enterprise", + }, + { + name: "Acme Corp.", + logo: AudioWaveform, + plan: "Startup", + }, + { + name: "Evil Corp.", + logo: Command, + plan: "Free", + }, + ], + navMain: [ + { + title: "Playground", + url: "#", + icon: SquareTerminal, + isActive: true, + items: [ + { + title: "History", + url: "#", + }, + { + title: "Starred", + url: "#", + }, + { + title: "Settings", + url: "#", + }, + ], + }, + { + title: "Models", + url: "#", + icon: Bot, + items: [ + { + title: "Genesis", + url: "#", + }, + { + title: "Explorer", + url: "#", + }, + { + title: "Quantum", + url: "#", + }, + ], + }, + { + title: "Documentation", + url: "#", + icon: BookOpen, + items: [ + { + title: "Introduction", + url: "#", + }, + { + title: "Get Started", + url: "#", + }, + { + title: "Tutorials", + url: "#", + }, + { + title: "Changelog", + url: "#", + }, + ], + }, + { + title: "Settings", + url: "#", + icon: Settings2, + items: [ + { + title: "General", + url: "#", + }, + { + title: "Team", + url: "#", + }, + { + title: "Billing", + url: "#", + }, + { + title: "Limits", + url: "#", + }, + ], + }, + ], + projects: [ + { + name: "Design Engineering", + url: "#", + icon: Frame, + }, + { + name: "Sales & Marketing", + url: "#", + icon: PieChart, + }, + { + name: "Travel", + url: "#", + icon: Map, + }, + ], +}; + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + + + + + + + ); +} diff --git a/latosa-frontend/components/nav-main.tsx b/latosa-frontend/components/nav-main.tsx new file mode 100644 index 0000000..902fb43 --- /dev/null +++ b/latosa-frontend/components/nav-main.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { ChevronRight, type LucideIcon } from "lucide-react"; + +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible"; +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, +} from "@/components/ui/sidebar"; + +export function NavMain({ + items, +}: { + items: { + title: string; + url: string; + icon?: LucideIcon; + isActive?: boolean; + items?: { + title: string; + url: string; + }[]; + }[]; +}) { + return ( + + Platform + + {items.map((item) => ( + + + + + {item.icon && } + {item.title} + + + + + + {item.items?.map((subItem) => ( + + + + {subItem.title} + + + + ))} + + + + + ))} + + + ); +} diff --git a/latosa-frontend/components/nav-projects.tsx b/latosa-frontend/components/nav-projects.tsx new file mode 100644 index 0000000..cd27490 --- /dev/null +++ b/latosa-frontend/components/nav-projects.tsx @@ -0,0 +1,89 @@ +"use client"; + +import { + Folder, + Forward, + MoreHorizontal, + Trash2, + type LucideIcon, +} from "lucide-react"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/components/ui/sidebar"; + +export function NavProjects({ + projects, +}: { + projects: { + name: string; + url: string; + icon: LucideIcon; + }[]; +}) { + const { isMobile } = useSidebar(); + + return ( + + Projects + + {projects.map((item) => ( + + + + + {item.name} + + + + + + + More + + + + + + View Project + + + + Share Project + + + + + Delete Project + + + + + ))} + + + + More + + + + + ); +} diff --git a/latosa-frontend/components/nav-user.tsx b/latosa-frontend/components/nav-user.tsx new file mode 100644 index 0000000..018d2dc --- /dev/null +++ b/latosa-frontend/components/nav-user.tsx @@ -0,0 +1,128 @@ +"use client"; + +import { + BadgeCheck, + Bell, + ChevronsUpDown, + CreditCard, + LogOut, + Sparkles, +} from "lucide-react"; + +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/components/ui/sidebar"; + +export function NavUser({ + user, +}: { + user: { + name: string; + email: string; + avatar: string; + }; +}) { + const { isMobile } = useSidebar(); + + return ( + + + + + + + + + CN + + +
+ + {user.name} + + + {user.email} + +
+ +
+
+ + +
+ + + + CN + + +
+ + {user.name} + + + {user.email} + +
+
+
+ + + + + Upgrade to Pro + + + + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
+ ); +} diff --git a/latosa-frontend/components/team-switcher.tsx b/latosa-frontend/components/team-switcher.tsx new file mode 100644 index 0000000..691d254 --- /dev/null +++ b/latosa-frontend/components/team-switcher.tsx @@ -0,0 +1,95 @@ +"use client"; + +import * as React from "react"; +import { ChevronsUpDown, Plus } from "lucide-react"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "@/components/ui/sidebar"; + +export function TeamSwitcher({ + teams, +}: { + teams: { + name: string; + logo: React.ElementType; + plan: string; + }[]; +}) { + const { isMobile } = useSidebar(); + const [activeTeam, setActiveTeam] = React.useState(teams[0]); + + return ( + + + + + +
+ +
+
+ + {activeTeam.name} + + + {activeTeam.plan} + +
+ +
+
+ + + Teams + + {teams.map((team, index) => ( + setActiveTeam(team)} + className="gap-2 p-2" + > +
+ +
+ {team.name} + + ⌘{index + 1} + +
+ ))} + + +
+ +
+
+ Add team +
+
+
+
+
+
+ ); +} diff --git a/latosa-frontend/components/ui/breadcrumb.tsx b/latosa-frontend/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..a35685a --- /dev/null +++ b/latosa-frontend/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>
+ + ); +}; + +export default Blog; diff --git a/latosa-frontend/components/blogItem.tsx b/frontend/components/blogItem.tsx similarity index 50% rename from latosa-frontend/components/blogItem.tsx rename to frontend/components/blogItem.tsx index e20ff0d..58bdec1 100644 --- a/latosa-frontend/components/blogItem.tsx +++ b/frontend/components/blogItem.tsx @@ -1,17 +1,15 @@ import { BlogInterface } from "@/components/blog"; export interface BlogItemParams { - slug: string - title_style: string, - subtitle_style: string, - p_style: string, - default_img: string - blog_content: BlogInterface + slug: string; + title_style: string; + subtitle_style: string; + p_style: string; + default_img: string; + blog_content: BlogInterface; } -export default function BlogItem({ params } - : { params: BlogItemParams } -) { +export default function BlogItem({ params }: { params: BlogItemParams }) { return (
@@ -24,7 +22,11 @@ export default function BlogItem({ params }

Subtitle 1

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! + Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias!

@@ -33,33 +35,43 @@ export default function BlogItem({ params } alt={params.slug} className="aspect-[16/9] mb-5 rounded-sm h-full w-full object-cover object-center" /> -

Subtitle 2

- Lorem ipsm dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! + Lorem ipsm dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias!

{params.slug} -

Subtitle 3

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! + Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias!

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti architecto incidunt, hic in consectetur eligendi nobis numquam tenetur sit repellat et unde, maxime ducimus autem esse temporibus omnis eum molestias! + Lorem ipsum dolor sit amet, consectetur adipisicing + elit. Deleniti architecto incidunt, hic in + consectetur eligendi nobis numquam tenetur sit + repellat et unde, maxime ducimus autem esse + temporibus omnis eum molestias!

- ) + ); } diff --git a/latosa-frontend/components/contact.tsx b/frontend/components/contact.tsx similarity index 100% rename from latosa-frontend/components/contact.tsx rename to frontend/components/contact.tsx diff --git a/latosa-frontend/components/features.tsx b/frontend/components/features.tsx similarity index 100% rename from latosa-frontend/components/features.tsx rename to frontend/components/features.tsx diff --git a/latosa-frontend/components/footer.tsx b/frontend/components/footer.tsx similarity index 100% rename from latosa-frontend/components/footer.tsx rename to frontend/components/footer.tsx diff --git a/latosa-frontend/components/gallery.tsx b/frontend/components/gallery.tsx similarity index 100% rename from latosa-frontend/components/gallery.tsx rename to frontend/components/gallery.tsx diff --git a/latosa-frontend/components/hero.tsx b/frontend/components/hero.tsx similarity index 100% rename from latosa-frontend/components/hero.tsx rename to frontend/components/hero.tsx diff --git a/latosa-frontend/components/login-form.tsx b/frontend/components/login-form.tsx similarity index 100% rename from latosa-frontend/components/login-form.tsx rename to frontend/components/login-form.tsx diff --git a/latosa-frontend/components/nav-bar.tsx b/frontend/components/nav-bar.tsx similarity index 100% rename from latosa-frontend/components/nav-bar.tsx rename to frontend/components/nav-bar.tsx diff --git a/latosa-frontend/components/nav-main.tsx b/frontend/components/nav-main.tsx similarity index 100% rename from latosa-frontend/components/nav-main.tsx rename to frontend/components/nav-main.tsx diff --git a/latosa-frontend/components/nav-projects.tsx b/frontend/components/nav-projects.tsx similarity index 100% rename from latosa-frontend/components/nav-projects.tsx rename to frontend/components/nav-projects.tsx diff --git a/latosa-frontend/components/nav-user.tsx b/frontend/components/nav-user.tsx similarity index 100% rename from latosa-frontend/components/nav-user.tsx rename to frontend/components/nav-user.tsx diff --git a/latosa-frontend/components/team-switcher.tsx b/frontend/components/team-switcher.tsx similarity index 100% rename from latosa-frontend/components/team-switcher.tsx rename to frontend/components/team-switcher.tsx diff --git a/latosa-frontend/components/testimonial.tsx b/frontend/components/testimonial.tsx similarity index 100% rename from latosa-frontend/components/testimonial.tsx rename to frontend/components/testimonial.tsx diff --git a/latosa-frontend/components/ui/accordion.tsx b/frontend/components/ui/accordion.tsx similarity index 100% rename from latosa-frontend/components/ui/accordion.tsx rename to frontend/components/ui/accordion.tsx diff --git a/latosa-frontend/components/ui/avatar.tsx b/frontend/components/ui/avatar.tsx similarity index 100% rename from latosa-frontend/components/ui/avatar.tsx rename to frontend/components/ui/avatar.tsx diff --git a/latosa-frontend/components/ui/badge.tsx b/frontend/components/ui/badge.tsx similarity index 100% rename from latosa-frontend/components/ui/badge.tsx rename to frontend/components/ui/badge.tsx diff --git a/latosa-frontend/components/ui/breadcrumb.tsx b/frontend/components/ui/breadcrumb.tsx similarity index 100% rename from latosa-frontend/components/ui/breadcrumb.tsx rename to frontend/components/ui/breadcrumb.tsx diff --git a/latosa-frontend/components/ui/button.tsx b/frontend/components/ui/button.tsx similarity index 100% rename from latosa-frontend/components/ui/button.tsx rename to frontend/components/ui/button.tsx diff --git a/latosa-frontend/components/ui/card.tsx b/frontend/components/ui/card.tsx similarity index 100% rename from latosa-frontend/components/ui/card.tsx rename to frontend/components/ui/card.tsx diff --git a/frontend/components/ui/carousel.tsx b/frontend/components/ui/carousel.tsx new file mode 100644 index 0000000..c72835e --- /dev/null +++ b/frontend/components/ui/carousel.tsx @@ -0,0 +1,263 @@ +"use client"; + +import * as React from "react"; +import useEmblaCarousel, { + type UseEmblaCarouselType, +} from "embla-carousel-react"; +import { ArrowLeft, ArrowRight } from "lucide-react"; + +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; + +type CarouselApi = UseEmblaCarouselType[1]; +type UseCarouselParameters = Parameters; +type CarouselOptions = UseCarouselParameters[0]; +type CarouselPlugin = UseCarouselParameters[1]; + +type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugin; + orientation?: "horizontal" | "vertical"; + setApi?: (api: CarouselApi) => void; +}; + +type CarouselContextProps = { + carouselRef: ReturnType[0]; + api: ReturnType[1]; + scrollPrev: () => void; + scrollNext: () => void; + canScrollPrev: boolean; + canScrollNext: boolean; +} & CarouselProps; + +const CarouselContext = React.createContext(null); + +function useCarousel() { + const context = React.useContext(CarouselContext); + + if (!context) { + throw new Error("useCarousel must be used within a "); + } + + return context; +} + +const Carousel = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & CarouselProps +>( + ( + { + orientation = "horizontal", + opts, + setApi, + plugins, + className, + children, + ...props + }, + ref, + ) => { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins, + ); + const [canScrollPrev, setCanScrollPrev] = React.useState(false); + const [canScrollNext, setCanScrollNext] = React.useState(false); + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) { + return; + } + + setCanScrollPrev(api.canScrollPrev()); + setCanScrollNext(api.canScrollNext()); + }, []); + + const scrollPrev = React.useCallback(() => { + api?.scrollPrev(); + }, [api]); + + const scrollNext = React.useCallback(() => { + api?.scrollNext(); + }, [api]); + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "ArrowLeft") { + event.preventDefault(); + scrollPrev(); + } else if (event.key === "ArrowRight") { + event.preventDefault(); + scrollNext(); + } + }, + [scrollPrev, scrollNext], + ); + + React.useEffect(() => { + if (!api || !setApi) { + return; + } + + setApi(api); + }, [api, setApi]); + + React.useEffect(() => { + if (!api) { + return; + } + + onSelect(api); + api.on("reInit", onSelect); + api.on("select", onSelect); + + return () => { + api?.off("select", onSelect); + }; + }, [api, onSelect]); + + return ( + +
+ {children} +
+
+ ); + }, +); +Carousel.displayName = "Carousel"; + +const CarouselContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { carouselRef, orientation } = useCarousel(); + + return ( +
+
+
+ ); +}); +CarouselContent.displayName = "CarouselContent"; + +const CarouselItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const { orientation } = useCarousel(); + + return ( +
+ ); +}); +CarouselItem.displayName = "CarouselItem"; + +const CarouselPrevious = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel(); + + return ( + + ); +}); +CarouselPrevious.displayName = "CarouselPrevious"; + +const CarouselNext = React.forwardRef< + HTMLButtonElement, + React.ComponentProps +>(({ className, variant = "outline", size = "icon", ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel(); + + return ( + + ); +}); +CarouselNext.displayName = "CarouselNext"; + +export { + type CarouselApi, + Carousel, + CarouselContent, + CarouselItem, + CarouselPrevious, + CarouselNext, +}; diff --git a/latosa-frontend/components/ui/collapsible.tsx b/frontend/components/ui/collapsible.tsx similarity index 100% rename from latosa-frontend/components/ui/collapsible.tsx rename to frontend/components/ui/collapsible.tsx diff --git a/latosa-frontend/components/ui/dropdown-menu.tsx b/frontend/components/ui/dropdown-menu.tsx similarity index 100% rename from latosa-frontend/components/ui/dropdown-menu.tsx rename to frontend/components/ui/dropdown-menu.tsx diff --git a/latosa-frontend/components/ui/input.tsx b/frontend/components/ui/input.tsx similarity index 100% rename from latosa-frontend/components/ui/input.tsx rename to frontend/components/ui/input.tsx diff --git a/latosa-frontend/components/ui/label.tsx b/frontend/components/ui/label.tsx similarity index 100% rename from latosa-frontend/components/ui/label.tsx rename to frontend/components/ui/label.tsx diff --git a/latosa-frontend/components/ui/navigation-menu.tsx b/frontend/components/ui/navigation-menu.tsx similarity index 100% rename from latosa-frontend/components/ui/navigation-menu.tsx rename to frontend/components/ui/navigation-menu.tsx diff --git a/latosa-frontend/components/ui/select.tsx b/frontend/components/ui/select.tsx similarity index 100% rename from latosa-frontend/components/ui/select.tsx rename to frontend/components/ui/select.tsx diff --git a/latosa-frontend/components/ui/separator.tsx b/frontend/components/ui/separator.tsx similarity index 100% rename from latosa-frontend/components/ui/separator.tsx rename to frontend/components/ui/separator.tsx diff --git a/latosa-frontend/components/ui/sheet.tsx b/frontend/components/ui/sheet.tsx similarity index 100% rename from latosa-frontend/components/ui/sheet.tsx rename to frontend/components/ui/sheet.tsx diff --git a/latosa-frontend/components/ui/sidebar.tsx b/frontend/components/ui/sidebar.tsx similarity index 100% rename from latosa-frontend/components/ui/sidebar.tsx rename to frontend/components/ui/sidebar.tsx diff --git a/latosa-frontend/components/ui/skeleton.tsx b/frontend/components/ui/skeleton.tsx similarity index 100% rename from latosa-frontend/components/ui/skeleton.tsx rename to frontend/components/ui/skeleton.tsx diff --git a/latosa-frontend/components/ui/textarea.tsx b/frontend/components/ui/textarea.tsx similarity index 100% rename from latosa-frontend/components/ui/textarea.tsx rename to frontend/components/ui/textarea.tsx diff --git a/latosa-frontend/components/ui/tooltip.tsx b/frontend/components/ui/tooltip.tsx similarity index 100% rename from latosa-frontend/components/ui/tooltip.tsx rename to frontend/components/ui/tooltip.tsx diff --git a/latosa-frontend/dashboard.yaml b/frontend/dashboard.yaml similarity index 100% rename from latosa-frontend/dashboard.yaml rename to frontend/dashboard.yaml diff --git a/latosa-frontend/deno.json b/frontend/deno.json similarity index 100% rename from latosa-frontend/deno.json rename to frontend/deno.json diff --git a/latosa-frontend/deno.lock b/frontend/deno.lock similarity index 100% rename from latosa-frontend/deno.lock rename to frontend/deno.lock diff --git a/latosa-frontend/eslint.config.mjs b/frontend/eslint.config.mjs similarity index 100% rename from latosa-frontend/eslint.config.mjs rename to frontend/eslint.config.mjs diff --git a/latosa-frontend/hooks/use-mobile.tsx b/frontend/hooks/use-mobile.tsx similarity index 100% rename from latosa-frontend/hooks/use-mobile.tsx rename to frontend/hooks/use-mobile.tsx diff --git a/latosa-frontend/lib/utils.ts b/frontend/lib/utils.ts similarity index 100% rename from latosa-frontend/lib/utils.ts rename to frontend/lib/utils.ts diff --git a/latosa-frontend/next.config.ts b/frontend/next.config.ts similarity index 100% rename from latosa-frontend/next.config.ts rename to frontend/next.config.ts diff --git a/latosa-frontend/package-lock.json b/frontend/package-lock.json similarity index 100% rename from latosa-frontend/package-lock.json rename to frontend/package-lock.json diff --git a/latosa-frontend/package.json b/frontend/package.json similarity index 96% rename from latosa-frontend/package.json rename to frontend/package.json index d0dcc32..2d85ca9 100644 --- a/latosa-frontend/package.json +++ b/frontend/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", + "dev": "next dev --turbopack -p 8000", "build": "next build", "start": "next start", "lint": "next lint" diff --git a/latosa-frontend/postcss.config.mjs b/frontend/postcss.config.mjs similarity index 100% rename from latosa-frontend/postcss.config.mjs rename to frontend/postcss.config.mjs diff --git a/latosa-frontend/public/file.svg b/frontend/public/file.svg similarity index 100% rename from latosa-frontend/public/file.svg rename to frontend/public/file.svg diff --git a/latosa-frontend/public/globe.svg b/frontend/public/globe.svg similarity index 100% rename from latosa-frontend/public/globe.svg rename to frontend/public/globe.svg diff --git a/latosa-frontend/public/next.svg b/frontend/public/next.svg similarity index 100% rename from latosa-frontend/public/next.svg rename to frontend/public/next.svg diff --git a/latosa-frontend/public/vercel.svg b/frontend/public/vercel.svg similarity index 100% rename from latosa-frontend/public/vercel.svg rename to frontend/public/vercel.svg diff --git a/latosa-frontend/public/window.svg b/frontend/public/window.svg similarity index 100% rename from latosa-frontend/public/window.svg rename to frontend/public/window.svg diff --git a/latosa-frontend/tailwind.config.ts b/frontend/tailwind.config.ts similarity index 100% rename from latosa-frontend/tailwind.config.ts rename to frontend/tailwind.config.ts diff --git a/latosa-frontend/tsconfig.json b/frontend/tsconfig.json similarity index 100% rename from latosa-frontend/tsconfig.json rename to frontend/tsconfig.json diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..acd3dad --- /dev/null +++ b/init.sh @@ -0,0 +1,4 @@ +#!/usr/bin/sh +printf "POSTGRES_USER=\nPOSTGRES_PASSWORD=\nPOSTGRES_DB=\n# Docker inner port container\nPOSTGRES_PORT=5432\nBACKEND_PORT=3000\nFRONTEND_PORT=3000\n" > .env +ln $(pwd)/.env $(pwd)/backend +ln $(pwd)/.env $(pwd)/frontend diff --git a/latosa-frontend/components/blog.tsx b/latosa-frontend/components/blog.tsx deleted file mode 100644 index a898b63..0000000 --- a/latosa-frontend/components/blog.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { ArrowRight } from "lucide-react"; - -import { Button } from "@/components/ui/button"; - -export interface BlogInterface { - id: string, - slug: string, - title: string, - content: string, - label: string, - author: string, - published: string, -} - -export interface BlogSummaryInterface extends BlogInterface { - summary: string, - image: string, - href: string -} - -export const posts: BlogSummaryInterface[] = [ - { - id: 'a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6', - slug: 'tech-advancements-2025', - title: 'Tech Advancements in 2025', - content: 'The year 2025 promises groundbreaking technologies that will reshape industries. In this article, we explore the key advancements that could transform how we work, live, and communicate.', - label: 'Technology', - author: 'd3f5e6g7-h8i9j0k1-l2m3n4o5p6q7', - published: '2025-01-14', - summary: 'A look at the tech trends to expect in 2025 and beyond, from AI to quantum computing.', - image: 'https://via.placeholder.com/600x400?text=Tech+2025', - href: 'history/tech-advancements-2025' - }, - { - id: 'f7g8h9i0-j1k2l3m4-n5o6p7q8r9s0t1u2v3', - slug: 'sustainable-fashion-2025', - title: 'Sustainable Fashion in 2025', - content: 'Sustainability is no longer a trend, but a movement within the fashion industry. This article discusses how eco-friendly practices are influencing fashion designs and consumer behavior in 2025.', - label: 'Fashion', - author: 'w4x5y6z7-a8b9c0d1-e2f3g4h5i6j7', - published: '2025-01-12', - summary: 'Exploring how sustainable fashion is evolving in 2025 with innovative materials and ethical brands.', - image: 'https://via.placeholder.com/600x400?text=Sustainable+Fashion', - href: 'history/sustainable-fashion-2025' - }, - { - id: 'v1w2x3y4-z5a6b7c8-d9e0f1g2h3i4j5k6l7', - slug: 'mental-health-awareness-2025', - title: 'Mental Health Awareness in 2025', - content: 'As mental health awareness continues to grow, 2025 brings new challenges and opportunities to address psychological well-being. This article focuses on emerging trends in mental health support and public perception.', - label: 'Health', - author: 'm8n9o0p1-q2r3s4t5-u6v7w8x9y0z1a2b3', - published: '2025-01-10', - summary: 'Highlighting the importance of mental health awareness in 2025, focusing on new treatments and societal changes.', - image: 'https://via.placeholder.com/600x400?text=Mental+Health+2025', - href: '/history/mental-health-awareness-2025' - } -]; - -const Blog = () => { - return ( -
-
-
-

- En savoir plus sur ce sport -

-

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Elig - doloremque mollitia fugiat omnis! Porro facilis quo animi - consequatur. Explicabo. -

- -
- -
-
- ); -}; - -export default Blog; diff --git a/latosa-frontend/components/ui/carousel.tsx b/latosa-frontend/components/ui/carousel.tsx deleted file mode 100644 index ec505d0..0000000 --- a/latosa-frontend/components/ui/carousel.tsx +++ /dev/null @@ -1,262 +0,0 @@ -"use client" - -import * as React from "react" -import useEmblaCarousel, { - type UseEmblaCarouselType, -} from "embla-carousel-react" -import { ArrowLeft, ArrowRight } from "lucide-react" - -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" - -type CarouselApi = UseEmblaCarouselType[1] -type UseCarouselParameters = Parameters -type CarouselOptions = UseCarouselParameters[0] -type CarouselPlugin = UseCarouselParameters[1] - -type CarouselProps = { - opts?: CarouselOptions - plugins?: CarouselPlugin - orientation?: "horizontal" | "vertical" - setApi?: (api: CarouselApi) => void -} - -type CarouselContextProps = { - carouselRef: ReturnType[0] - api: ReturnType[1] - scrollPrev: () => void - scrollNext: () => void - canScrollPrev: boolean - canScrollNext: boolean -} & CarouselProps - -const CarouselContext = React.createContext(null) - -function useCarousel() { - const context = React.useContext(CarouselContext) - - if (!context) { - throw new Error("useCarousel must be used within a ") - } - - return context -} - -const Carousel = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & CarouselProps ->( - ( - { - orientation = "horizontal", - opts, - setApi, - plugins, - className, - children, - ...props - }, - ref - ) => { - const [carouselRef, api] = useEmblaCarousel( - { - ...opts, - axis: orientation === "horizontal" ? "x" : "y", - }, - plugins - ) - const [canScrollPrev, setCanScrollPrev] = React.useState(false) - const [canScrollNext, setCanScrollNext] = React.useState(false) - - const onSelect = React.useCallback((api: CarouselApi) => { - if (!api) { - return - } - - setCanScrollPrev(api.canScrollPrev()) - setCanScrollNext(api.canScrollNext()) - }, []) - - const scrollPrev = React.useCallback(() => { - api?.scrollPrev() - }, [api]) - - const scrollNext = React.useCallback(() => { - api?.scrollNext() - }, [api]) - - const handleKeyDown = React.useCallback( - (event: React.KeyboardEvent) => { - if (event.key === "ArrowLeft") { - event.preventDefault() - scrollPrev() - } else if (event.key === "ArrowRight") { - event.preventDefault() - scrollNext() - } - }, - [scrollPrev, scrollNext] - ) - - React.useEffect(() => { - if (!api || !setApi) { - return - } - - setApi(api) - }, [api, setApi]) - - React.useEffect(() => { - if (!api) { - return - } - - onSelect(api) - api.on("reInit", onSelect) - api.on("select", onSelect) - - return () => { - api?.off("select", onSelect) - } - }, [api, onSelect]) - - return ( - -
- {children} -
-
- ) - } -) -Carousel.displayName = "Carousel" - -const CarouselContent = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { carouselRef, orientation } = useCarousel() - - return ( -
-
-
- ) -}) -CarouselContent.displayName = "CarouselContent" - -const CarouselItem = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { orientation } = useCarousel() - - return ( -
- ) -}) -CarouselItem.displayName = "CarouselItem" - -const CarouselPrevious = React.forwardRef< - HTMLButtonElement, - React.ComponentProps ->(({ className, variant = "outline", size = "icon", ...props }, ref) => { - const { orientation, scrollPrev, canScrollPrev } = useCarousel() - - return ( - - ) -}) -CarouselPrevious.displayName = "CarouselPrevious" - -const CarouselNext = React.forwardRef< - HTMLButtonElement, - React.ComponentProps ->(({ className, variant = "outline", size = "icon", ...props }, ref) => { - const { orientation, scrollNext, canScrollNext } = useCarousel() - - return ( - - ) -}) -CarouselNext.displayName = "CarouselNext" - -export { - type CarouselApi, - Carousel, - CarouselContent, - CarouselItem, - CarouselPrevious, - CarouselNext, -}