From 29fc82c104983ae3728fb3e855044fe415e94f25 Mon Sep 17 00:00:00 2001 From: PlatyPuspus <23h46.shovin@sjec.ac.in> Date: Sat, 21 Feb 2026 15:02:57 +0530 Subject: [PATCH] Updated Frontend --- app/components/CTA.tsx | 75 + app/components/Categories.tsx | 131 ++ app/components/Footer.tsx | 111 ++ app/components/Hero.tsx | 191 +++ app/components/HowItWorks.tsx | 101 ++ app/components/Navbar.tsx | 112 ++ app/components/Stats.tsx | 38 + app/globals.css | 81 +- app/layout.tsx | 10 +- app/page.tsx | 76 +- package-lock.json | 2910 +++++++++++++++++++++++++++++++++ package.json | 3 + 12 files changed, 3767 insertions(+), 72 deletions(-) create mode 100644 app/components/CTA.tsx create mode 100644 app/components/Categories.tsx create mode 100644 app/components/Footer.tsx create mode 100644 app/components/Hero.tsx create mode 100644 app/components/HowItWorks.tsx create mode 100644 app/components/Navbar.tsx create mode 100644 app/components/Stats.tsx create mode 100644 package-lock.json diff --git a/app/components/CTA.tsx b/app/components/CTA.tsx new file mode 100644 index 0000000..688cca7 --- /dev/null +++ b/app/components/CTA.tsx @@ -0,0 +1,75 @@ +"use client"; + +import { motion } from "framer-motion"; +import { ArrowRight, Sparkles } from "lucide-react"; +import Link from "next/link"; + +export default function CTA() { + return ( +
+ {/* Background Elements */} +
+
+
+
+ +
+ +
+ + LIMITED TIME +
+ +

+ Ready to Showcase +
+ + Your Masterpiece? + +

+ +

+ Join hundreds of talented artists from SJEC in this creative + celebration. Submit your artwork and let the world vote for your + talent. +

+ +
+ + REGISTER NOW + + + + VIEW RULES + +
+ + {/* Deadline Notice */} + + + + Submissions close on February 28, 2026 + + +
+
+
+ ); +} diff --git a/app/components/Categories.tsx b/app/components/Categories.tsx new file mode 100644 index 0000000..ad6a9c8 --- /dev/null +++ b/app/components/Categories.tsx @@ -0,0 +1,131 @@ +"use client"; + +import { motion } from "framer-motion"; +import { Palette, Monitor, FileImage, ArrowRight } from "lucide-react"; +import Link from "next/link"; + +const categories = [ + { + icon: Monitor, + title: "Digital Art", + description: + "Create stunning digital masterpieces using any software of your choice. From illustrations to photo manipulations.", + color: "from-violet-500 to-purple-600", + bgColor: "bg-violet-50", + }, + { + icon: Palette, + title: "Paintings", + description: + "Traditional paintings in any medium - oil, acrylic, watercolor. Capture the essence of classic artistry.", + color: "from-orange-500 to-red-500", + bgColor: "bg-orange-50", + }, + { + icon: FileImage, + title: "Poster Making", + description: + "Design impactful posters that communicate powerful messages. Blend creativity with purpose.", + color: "from-lime-500 to-green-500", + bgColor: "bg-lime-50", + }, +]; + +const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + }, + }, +}; + +const itemVariants = { + hidden: { opacity: 0, y: 30 }, + visible: { + opacity: 1, + y: 0, + transition: { + duration: 0.6, + }, + }, +}; + +export default function Categories() { + return ( +
+
+ {/* Section Header */} + + + CATEGORIES + +

+ Three Ways to + + {" "} + Express + +

+

+ Choose your canvas, unleash your creativity. Each category offers a + unique way to showcase your artistic vision. +

+
+ + {/* Categories Grid */} + + {categories.map((category) => ( + + {/* Background Gradient on Hover */} +
+ + {/* Icon */} +
+ +
+ + {/* Content */} +

+ {category.title} +

+

+ {category.description} +

+ + {/* Link */} + + Submit Now + + + + ))} + +
+
+ ); +} diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx new file mode 100644 index 0000000..d43601f --- /dev/null +++ b/app/components/Footer.tsx @@ -0,0 +1,111 @@ +"use client"; + +import Link from "next/link"; +import { Diamond, Mail, Instagram, Twitter } from "lucide-react"; + +const footerLinks = { + competition: [ + { href: "/register", label: "Register" }, + { href: "/submit", label: "Submit Art" }, + { href: "/gallery", label: "Gallery" }, + { href: "/rules", label: "Rules" }, + ], + information: [ + { href: "/about", label: "About" }, + { href: "/faq", label: "FAQ" }, + { href: "/contact", label: "Contact" }, + ], +}; + +export default function Footer() { + return ( + + ); +} diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx new file mode 100644 index 0000000..d5f1a19 --- /dev/null +++ b/app/components/Hero.tsx @@ -0,0 +1,191 @@ +"use client"; + +import { useEffect, useRef, useCallback } from "react"; +import Link from "next/link"; +import gsap from "gsap"; + +const GRID_COLS = 20; +const GRID_ROWS = 12; + +function TileGrid() { + const gridRef = useRef(null); + const tilesRef = useRef<(HTMLDivElement | null)[]>([]); + + const handleMouseEnter = useCallback((index: number) => { + const tile = tilesRef.current[index]; + if (tile) { + gsap.to(tile, { + rotateY: 180, + duration: 0.4, + ease: "power2.out", + }); + } + }, []); + + const handleMouseLeave = useCallback((index: number) => { + const tile = tilesRef.current[index]; + if (tile) { + gsap.to(tile, { + rotateY: 0, + duration: 0.4, + ease: "power2.out", + }); + } + }, []); + + return ( +
+ {Array.from({ length: GRID_COLS * GRID_ROWS }).map((_, index) => ( +
handleMouseEnter(index)} + onMouseLeave={() => handleMouseLeave(index)} + className="cursor-pointer" + style={{ perspective: "500px" }} + > +
{ tilesRef.current[index] = el; }} + className="w-full h-full relative" + style={{ transformStyle: "preserve-3d" }} + > + {/* Front - Black */} +
+ {/* Back - White */} +
+
+
+ ))} +
+ ); +} + +export default function Hero() { + const headingRef = useRef(null); + const contentRef = useRef(null); + + useEffect(() => { + // Animate heading on mount + if (headingRef.current) { + gsap.fromTo( + headingRef.current, + { opacity: 0, y: 50 }, + { opacity: 1, y: 0, duration: 1, ease: "power3.out", delay: 0.3 } + ); + } + + if (contentRef.current) { + gsap.fromTo( + contentRef.current.children, + { opacity: 0, y: 30 }, + { opacity: 1, y: 0, duration: 0.8, stagger: 0.15, ease: "power3.out", delay: 0.5 } + ); + } + }, []); + + return ( +
+ {/* Tile Grid Background */} + + +
+
+ {/* Center Content */} +
+
+ + FEBRUARY 2026 +
+ +

+ UNLEASH + + YOUR ART + +

+ +
+

+ From canvas to screen, showcase your creativity and let your + artwork speak to the world. +

+ +
+ + JOIN COMPETITION + + + EXPLORE GALLERY + +
+
+
+
+ + {/* Scroll Indicator - positioned above the marquee */} +
+ Scroll +
+
+
+ + {/* Bottom Marquee */} +
+
+ {Array(8) + .fill(null) + .map((_, i) => ( +
+ + ArtSplash + + + + SJEC + + + + 2026 + + +
+ ))} +
+
+
+ ); +} diff --git a/app/components/HowItWorks.tsx b/app/components/HowItWorks.tsx new file mode 100644 index 0000000..605e1f8 --- /dev/null +++ b/app/components/HowItWorks.tsx @@ -0,0 +1,101 @@ +"use client"; + +import { motion } from "framer-motion"; +import { UserPlus, Upload, Shield, Vote, Trophy } from "lucide-react"; + +const steps = [ + { + icon: UserPlus, + step: "01", + title: "Register", + description: "Sign up with your SJEC email to participate in the competition.", + }, + { + icon: Upload, + step: "02", + title: "Submit", + description: "Upload your artwork with title, description, and category details.", + }, + { + icon: Shield, + step: "03", + title: "Review", + description: "Moderators review submissions to ensure guidelines are met.", + }, + { + icon: Vote, + step: "04", + title: "Public Voting", + description: "The public votes for their favorite artworks in each category.", + }, + { + icon: Trophy, + step: "05", + title: "Results", + description: "Winners are announced and celebrated across all categories.", + }, +]; + +export default function HowItWorks() { + return ( +
+
+ {/* Section Header */} + + + HOW IT WORKS + +

+ Your Journey to + Victory +

+

+ From registration to winning, here's how ArtSplash works. +

+
+ + {/* Steps Timeline */} +
+ {/* Connection Line */} +
+ +
+ {steps.map((step, index) => ( + + {/* Card */} +
+ {/* Step Number */} +
+ {step.step} +
+ + {/* Icon */} + + + {/* Content */} +

{step.title}

+

+ {step.description} +

+
+
+ ))} +
+
+
+
+ ); +} diff --git a/app/components/Navbar.tsx b/app/components/Navbar.tsx new file mode 100644 index 0000000..c4fddb9 --- /dev/null +++ b/app/components/Navbar.tsx @@ -0,0 +1,112 @@ +"use client"; + +import { useState } from "react"; +import Link from "next/link"; +import { Menu, X, Diamond } from "lucide-react"; +import { motion, AnimatePresence } from "framer-motion"; + +const navLinks = [ + { href: "/gallery", label: "GALLERY" }, + { href: "/submit", label: "SUBMIT ART" }, + { href: "/about", label: "ABOUT" }, + { href: "/rules", label: "RULES" }, + { href: "/faq", label: "FAQ" }, + { href: "/contact", label: "CONTACT" }, +]; + +export default function Navbar() { + const [isOpen, setIsOpen] = useState(false); + + return ( + + ); +} diff --git a/app/components/Stats.tsx b/app/components/Stats.tsx new file mode 100644 index 0000000..2d826eb --- /dev/null +++ b/app/components/Stats.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { motion } from "framer-motion"; + +const stats = [ + { value: "3", label: "Categories" }, + { value: "∞", label: "Possibilities" }, + { value: "1", label: "Winner Per Category" }, + { value: "100%", label: "Free Entry" }, +]; + +export default function Stats() { + return ( +
+
+
+ {stats.map((stat, index) => ( + +
+ {stat.value} +
+
+ {stat.label} +
+
+ ))} +
+
+
+ ); +} diff --git a/app/globals.css b/app/globals.css index a2dc41e..ac773a5 100644 --- a/app/globals.css +++ b/app/globals.css @@ -3,24 +3,89 @@ :root { --background: #ffffff; --foreground: #171717; + --lime: #c5ff00; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); + --color-lime-400: #c5ff00; --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - body { background: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif; +} + +/* Custom Animations */ +@keyframes marquee { + 0% { + transform: translateX(0%); + } + 100% { + transform: translateX(-50%); + } +} + +@keyframes marquee-slow { + 0% { + transform: translateX(0%); + } + 100% { + transform: translateX(-50%); + } +} + +.animate-marquee { + animation: marquee 20s linear infinite; +} + +.animate-marquee-slow { + animation: marquee-slow 30s linear infinite; +} + +/* Smooth scrolling */ +html { + scroll-behavior: smooth; +} + +/* Custom scrollbar */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c5ff00; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #a8e000; +} + +/* Selection color */ +::selection { + background-color: #c5ff00; + color: #000000; +} + +/* Focus styles */ +*:focus-visible { + outline: 2px solid #c5ff00; + outline-offset: 2px; +} + +/* Gradient text utility */ +.gradient-text { + background: linear-gradient(135deg, #c5ff00 0%, #84cc16 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; } diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..e911418 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -13,8 +13,10 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "ArtSplash | SJEC Art Competition 2026", + description: + "Join SJEC's premier art competition featuring Digital Art, Paintings, and Poster Making. Register now and showcase your creativity!", + keywords: ["art competition", "SJEC", "digital art", "paintings", "poster making", "ArtSplash"], }; export default function RootLayout({ @@ -24,9 +26,7 @@ export default function RootLayout({ }>) { return ( - + {children} diff --git a/app/page.tsx b/app/page.tsx index 295f8fd..1942d78 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,65 +1,23 @@ -import Image from "next/image"; +import Navbar from "./components/Navbar"; +import Hero from "./components/Hero"; +import Categories from "./components/Categories"; +import HowItWorks from "./components/HowItWorks"; +import Stats from "./components/Stats"; +import CTA from "./components/CTA"; +import Footer from "./components/Footer"; export default function Home() { return ( -
-
- Next.js logo -
-

- To get started, edit the page.tsx file. -

-

- Looking for a starting point or more instructions? Head over to{" "} - - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -

-
- + <> + +
+ + + + +
-
+