diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f32490b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Use Deno image -FROM denoland/deno:alpine - -# Set working directory -WORKDIR /app - -# Copy project files -COPY ./latosa-frontend/ . - -RUN deno install - -# Install Next.js dependencies -RUN deno task build - -# Expose the default Next.js port -EXPOSE 3000 - -# Start the Next.js app -CMD ["deno", "task", "start"] diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..3fc3480 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:alpine + +WORKDIR /app + +COPY . . + +RUN go mod download +RUN go mod tidy + +RUN go build main.go + +CMD ["./main"] diff --git a/backend/go.mod b/backend/go.mod new file mode 100644 index 0000000..dfc90c4 --- /dev/null +++ b/backend/go.mod @@ -0,0 +1,14 @@ +module fr.latosa-escrima + +go 1.23.4 + +require ( + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/uptrace/bun v1.2.8 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/sys v0.29.0 // indirect +) diff --git a/backend/go.sum b/backend/go.sum new file mode 100644 index 0000000..eeda9ee --- /dev/null +++ b/backend/go.sum @@ -0,0 +1,16 @@ +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= +github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/uptrace/bun v1.2.8 h1:HEiLvy9wc7ehU5S02+O6NdV5BLz48lL4REPhTkMX3Dg= +github.com/uptrace/bun v1.2.8/go.mod h1:JBq0uBKsKqNT0Ccce1IAFZY337Wkf08c6F6qlmfOHE8= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/backend/main.go b/backend/main.go new file mode 100644 index 0000000..0294af1 --- /dev/null +++ b/backend/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + + "github.com/joho/godotenv" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "

Hello, World!

") +} + +func main() { + err := godotenv.Load() + if err != nil { + log.Fatalf("Error loading .env file: %v", err) + } + port := os.Getenv("BACKEND_PORT") + http.HandleFunc("/", handler) + fmt.Printf("Serving on port %s\n", port) + err = http.ListenAndServe(fmt.Sprintf(":%s", port), nil) + if err != nil { + fmt.Printf("Error starting server: %s\n", err) + } +} diff --git a/docker-compose.yaml b/docker-compose.yaml index 67ecbfe..d6a3d93 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,10 +1,44 @@ services: - latosa-escrima: - build: - context: . - dockerfile: Dockerfile + latosa-escrima.fr-frontend: + container_name: latosa-frontend + image: cems.dev:5000/latosa-escrima.fr:latest ports: - - "3000:3000" + - 3000:${FRONTEND_PORT} environment: - NODE_ENV=production + - FRONTEND_PORT=${FRONTEND_PORT} restart: always # Ensures the container restarts on failure or Docker restart + networks: + - le-network + latosa-escrima.fr-backend: + container_name: latosa-backend + build: + context: ./backend/ + dockerfile: Dockerfile + env_file: .env + environment: + - PORT="3001" + ports: + - "3001:${BACKEND_PORT}" + networks: + - le-network + psql: + container_name: latosa-database + image: postgres:17.2-alpine + restart: always + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} + ports: + - "5432:5432" + volumes: + - le-data:/var/lib/postgresql/data + networks: + - le-network + +volumes: + le-data: + +networks: + le-network: diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..ce2c29a --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1 @@ +./latosa-frontend/node_modules/ diff --git a/latosa-frontend/.gitignore b/frontend/.gitignore similarity index 100% rename from latosa-frontend/.gitignore rename to frontend/.gitignore diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..7f6e287 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,27 @@ +# Use Deno image +FROM denoland/deno:alpine + +# Set working directory +WORKDIR /app + +# Copy project files +COPY . . + +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", "run", "--allow-env", "--allow-read", "--allow-sys", "--allow-net", ".next/standalone/server.cjs"] diff --git a/frontend/app/(auth)/dashboard/page.tsx b/frontend/app/(auth)/dashboard/page.tsx new file mode 100644 index 0000000..36e2957 --- /dev/null +++ b/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/frontend/app/(auth)/layout.tsx b/frontend/app/(auth)/layout.tsx new file mode 100644 index 0000000..0bf3e6b --- /dev/null +++ b/frontend/app/(auth)/layout.tsx @@ -0,0 +1,35 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "@/app/globals.css"; +import Navbar from "@/components/nav-bar"; + +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/about/page.tsx b/frontend/app/(main)/about/page.tsx similarity index 90% rename from latosa-frontend/app/about/page.tsx rename to frontend/app/(main)/about/page.tsx index 32b4c1e..85f4e66 100644 --- a/latosa-frontend/app/about/page.tsx +++ b/frontend/app/(main)/about/page.tsx @@ -2,7 +2,7 @@ export default async function About() { return ( -
+
About us will : @@ -11,6 +11,6 @@ export default async function About() { +plannign for what will come next
-
+
) } diff --git a/latosa-frontend/app/contact/page.tsx b/frontend/app/(main)/contact/page.tsx similarity index 100% rename from latosa-frontend/app/contact/page.tsx rename to frontend/app/(main)/contact/page.tsx diff --git a/frontend/app/(main)/history/[slug]/page.tsx b/frontend/app/(main)/history/[slug]/page.tsx new file mode 100644 index 0000000..ee9451c --- /dev/null +++ b/frontend/app/(main)/history/[slug]/page.tsx @@ -0,0 +1,31 @@ +"use server"; + +import { BlogInterface, posts } from "@/components/blog"; +import BlogItem, { BlogItemParams } from "@/components/blogItem"; + +export default async function HistoryDetails({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + + const blog_item: BlogInterface = posts.find( + (value) => value.slug == slug, + ) as BlogInterface; + + const blog_item_params: BlogItemParams = { + slug: slug, + title_style: + "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", + subtitle_style: + "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", + p_style: + "blog-paragraph mb-5 text-muted-foreground md:text-base lg:max-w-2xl lg:text-lg", + default_img: + "https://shadcnblocks.com/images/block/placeholder-dark-1.svg", + blog_content: blog_item, + }; + + return ; +} diff --git a/latosa-frontend/app/history/page.tsx b/frontend/app/(main)/history/page.tsx similarity index 81% rename from latosa-frontend/app/history/page.tsx rename to frontend/app/(main)/history/page.tsx index 893b516..d27089e 100644 --- a/latosa-frontend/app/history/page.tsx +++ b/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/frontend/app/(main)/layout.tsx similarity index 96% rename from latosa-frontend/app/layout.tsx rename to frontend/app/(main)/layout.tsx index 5a322db..798ff81 100644 --- a/latosa-frontend/app/layout.tsx +++ b/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/frontend/app/(main)/login/page.tsx similarity index 100% rename from latosa-frontend/app/login/page.tsx rename to frontend/app/(main)/login/page.tsx diff --git a/latosa-frontend/app/page.tsx b/frontend/app/(main)/page.tsx similarity index 100% rename from latosa-frontend/app/page.tsx rename to frontend/app/(main)/page.tsx diff --git a/latosa-frontend/app/favicon.ico b/frontend/app/favicon.ico similarity index 100% rename from latosa-frontend/app/favicon.ico rename to frontend/app/favicon.ico diff --git a/latosa-frontend/app/globals.css b/frontend/app/globals.css similarity index 70% rename from latosa-frontend/app/globals.css rename to frontend/app/globals.css index 11d8278..296a425 100644 --- a/latosa-frontend/app/globals.css +++ b/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/components.json b/frontend/components.json similarity index 100% rename from latosa-frontend/components.json rename to frontend/components.json diff --git a/frontend/components/app-sidebar.tsx b/frontend/components/app-sidebar.tsx new file mode 100644 index 0000000..5f094b6 --- /dev/null +++ b/frontend/components/app-sidebar.tsx @@ -0,0 +1,110 @@ +"use client"; + +import * as React from "react"; +import { + AudioWaveform, + BookOpen, + Bot, + Command, + Users, + GalleryVerticalEnd, + Settings2, + Calendar, +} 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: "Latosa-Escrima", + logo: GalleryVerticalEnd, + plan: "", + }, + { + name: "Wing-Tsun", + logo: Command, + plan: "", + }, + ], + navMain: [ + { + title: "Membres", + url: "/dashboard/members", + icon: Users, + isActive: true, + items: [ + { + title: "Création d'un membre", + url: "/dashboard/members/new", + }, + ], + }, + { + title: "Planning", + url: "/dashboard/planning", + icon: Calendar, + }, + { + title: "Blogs", + url: "/dashboard/blogs", + icon: BookOpen, + items: [ + { + title: "Catégorie 1", + url: "/dashboard/blogs/categorie-1", + }, + { + title: "Catégorie 2", + url: "/dashboard/blogs/categorie-2", + }, + { + title: "Nouvelle catégorie", + url: "/dashboard/blogs/categories/new", + }, + { + title: "Nouvel article", + url: "/dashboard/blogs/new", + }, + ], + }, + { + title: "Settings", + url: "/dashboard/settings", + icon: Settings2, + }, + ], +}; + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + + + + + + ); +} diff --git a/frontend/components/blog.tsx b/frontend/components/blog.tsx new file mode 100644 index 0000000..a17a798 --- /dev/null +++ b/frontend/components/blog.tsx @@ -0,0 +1,118 @@ +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/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 96% rename from latosa-frontend/components/nav-bar.tsx rename to frontend/components/nav-bar.tsx index cc27832..64e85c8 100644 --- a/latosa-frontend/components/nav-bar.tsx +++ b/frontend/components/nav-bar.tsx @@ -9,9 +9,7 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { Button, buttonVariants } from "@/components/ui/button"; -import { - navigationMenuTriggerStyle, -} from "@/components/ui/navigation-menu"; +import { navigationMenuTriggerStyle } from "@/components/ui/navigation-menu"; import { Sheet, SheetContent, @@ -70,7 +68,7 @@ const subMenuItemsTwo = [ const Navbar = () => { return ( -
+
- ); -}; - -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, -}