From a8dfc3d2948ae10225c0b3e2996f96d3ca14dcfe Mon Sep 17 00:00:00 2001 From: Kevin Satria D <130447401+kevinnsd1@users.noreply.github.com> Date: Wed, 20 May 2026 11:16:45 +0700 Subject: [PATCH] feat: initialize frontend application with landing page components and event listings --- src/App.tsx | 100 ++++-------------------- src/components/EventCard.tsx | 96 +++++++++++++++++++++++ src/components/EventSection.tsx | 95 +++++++++++++++++++++++ src/components/Footer.tsx | 73 ++++++++++++++++++ src/components/Hero.tsx | 132 ++++++++++++++++++++++++++++++++ src/components/Navbar.tsx | 49 ++++++++++++ vite.config.ts | 11 +++ 7 files changed, 472 insertions(+), 84 deletions(-) create mode 100644 src/components/EventCard.tsx create mode 100644 src/components/EventSection.tsx create mode 100644 src/components/Footer.tsx create mode 100644 src/components/Hero.tsx create mode 100644 src/components/Navbar.tsx create mode 100644 vite.config.ts diff --git a/src/App.tsx b/src/App.tsx index bb7e699..545519c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,89 +1,21 @@ -import { useState } from 'react' -import { CheckCircle2, Terminal, Layers, Sparkles } from 'lucide-react' - -export default function App() { - const [count, setCount] = useState(0) +import Navbar from './components/Navbar'; +import Hero from './components/Hero'; +import EventSection from './components/EventSection'; +import Footer from './components/Footer'; +function App() { return ( -
- {/* Background Glowing Effects */} -
-
+
+ + +
+ + +
- {/* Main Glassmorphic Container */} -
- - {/* Status Badge */} -
- - SETUP SUCCESSFUL (TSX) -
- - {/* Heading using Google Font 'Outfit' */} -

- SmartTiket -

- - {/* Body using Google Font 'Plus Jakarta Sans' */} -

- Welcome to your new development environment. React 19, Tailwind CSS v4, TypeScript, and Google Fonts are successfully configured and ready. -

- - {/* Feature Checkmarks */} -
-
-
- -
- React 19 & Vite 6 Setup -
- -
-
- -
- Tailwind CSS v4 & TypeScript -
- -
-
- -
- Outfit & Plus Jakarta Sans Google Fonts -
-
- - {/* Interactive React Verification State */} -
-
-

Test React State

-

Clicked {count} times

-
- -
- - {/* Console / Start Instructions */} -
- -
-

# Next steps to start coding:

-

1. Open workspace directory

-

2. Run npm install

-

3. Run npm run dev

-
-
- -
- - {/* Footer */} -
- © {new Date().getFullYear()} SmartTiket Setup • Built with Google DeepMind Antigravity -
+
- ) + ); } + +export default App; diff --git a/src/components/EventCard.tsx b/src/components/EventCard.tsx new file mode 100644 index 0000000..eaa7b9a --- /dev/null +++ b/src/components/EventCard.tsx @@ -0,0 +1,96 @@ +import { MapPin, Calendar, ArrowRight } from 'lucide-react'; + +interface EventCardProps { + title: string; + image: string; + date: string; + location: string; + price: string; + organizer: string; + status?: string; + isAvailable?: boolean; +} + +export default function EventCard({ + title, + image, + date, + location, + price, + organizer, + status = "ON SALE", + isAvailable = true, +}: EventCardProps) { + return ( +
+ + {/* Image Container */} +
+
{/* Placeholder background */} + {title} + + {/* Status Badge */} +
+ + {status} + +
+
+ + {/* Content Container */} +
+

+ {title} +

+ +
+
+ + {location} +
+
+ + {date} +
+
+ + {/* Footer Area */} +
+
+

START FROM

+ {isAvailable ? ( +

+ {price} +

+ ) : ( +

+ Ticket Belum Tersedia +

+ )} +

By: {organizer}

+
+ + +
+
+
+ ); +} diff --git a/src/components/EventSection.tsx b/src/components/EventSection.tsx new file mode 100644 index 0000000..9406c8b --- /dev/null +++ b/src/components/EventSection.tsx @@ -0,0 +1,95 @@ +import EventCard from './EventCard'; +import { ArrowRight } from 'lucide-react'; + +const MOCK_EVENTS = [ + { + id: '1', + title: 'PURNAMA BERSANTAI 2026', + image: 'https://images.unsplash.com/photo-1459749411175-04bf5292ceea?q=80&w=1000&auto=format&fit=crop', + date: '2026-08-21 15:00', + location: 'Medan, Sumatera Utara', + price: 'Rp 185.000', + organizer: 'Puber2026', + status: 'ON SALE', + isAvailable: true, + }, + { + id: '2', + title: 'MEDAN GLOWFEST 2024', + image: 'https://images.unsplash.com/photo-1540039155732-6761b54f6cce?q=80&w=1000&auto=format&fit=crop', + date: '2024-12-31 18:30', + location: 'Lakeside Garden Royal...', + price: '-', + organizer: 'Glowfest 2024', + status: 'CLOSE', + isAvailable: false, + }, + { + id: '3', + title: 'HI REV ENDURANCE OTOFEST', + image: 'https://images.unsplash.com/photo-1514525253161-7a46d19cd819?q=80&w=1000&auto=format&fit=crop', + date: '2024-09-13 10:00', + location: 'Jl. Negara, Petapahan...', + price: 'Rp 50.000', + organizer: 'Hirevendurance', + status: 'CLOSE', + isAvailable: false, + }, + { + id: '4', + title: 'Tamasya lebaran', + image: 'https://images.unsplash.com/photo-1493225457124-a1a2a5956093?q=80&w=1000&auto=format&fit=crop', + date: '2024-04-18 18:00', + location: 'PRSU, Medan', + price: 'Rp 100.000', + organizer: 'Tamasya Lebaran', + status: 'CLOSE', + isAvailable: false, + } +]; + +export default function EventSection() { + return ( +
+
+ + {/* Section Header */} +
+
+
+
+ Event Terbaru +
+

+ Temukan Acaramu +

+

+ Temukan acara favorit Anda, dan mari bersenang-senang +

+
+ + +
+ + {/* Events Grid */} +
+ {MOCK_EVENTS.map((event) => ( + + ))} +
+ + {/* Mobile View All Button */} +
+ +
+ +
+
+ ); +} diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx new file mode 100644 index 0000000..7fc79f7 --- /dev/null +++ b/src/components/Footer.tsx @@ -0,0 +1,73 @@ +import { Facebook, Instagram, Mail, MessageCircle } from 'lucide-react'; + +export default function Footer() { + return ( + + ); +} diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx new file mode 100644 index 0000000..4011957 --- /dev/null +++ b/src/components/Hero.tsx @@ -0,0 +1,132 @@ +import { useState, useEffect } from 'react'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; + +const SLIDES = [ + { + id: 1, + title1: "Music Festival", + title2: "Concert", + subtitle: "Jual Ticket di Smart Ticketing Aja", + gradientText: "from-cyan-400 via-indigo-400 to-purple-400", + gradientSub: "from-emerald-400 to-cyan-400", + blob1: "bg-purple-600/30", + blob2: "bg-cyan-500/20", + blob3: "bg-indigo-600/20" + }, + { + id: 2, + title1: "Standup Comedy", + title2: "Special Show", + subtitle: "Pesan Kursi Terbaikmu Sekarang", + gradientText: "from-pink-400 via-rose-400 to-red-500", + gradientSub: "from-orange-400 to-amber-400", + blob1: "bg-pink-600/30", + blob2: "bg-rose-500/20", + blob3: "bg-red-600/20" + }, + { + id: 3, + title1: "E-Sports", + title2: "Tournament", + subtitle: "Dukung Tim Favoritmu Langsung", + gradientText: "from-blue-400 via-cyan-400 to-teal-400", + gradientSub: "from-lime-400 to-emerald-400", + blob1: "bg-blue-600/30", + blob2: "bg-teal-500/20", + blob3: "bg-cyan-600/20" + } +]; + +export default function Hero() { + const [currentSlide, setCurrentSlide] = useState(0); + + // Auto-play + useEffect(() => { + const timer = setInterval(() => { + setCurrentSlide((prev) => (prev + 1) % SLIDES.length); + }, 5000); + return () => clearInterval(timer); + }, []); + + const nextSlide = () => { + setCurrentSlide((prev) => (prev + 1) % SLIDES.length); + }; + + const prevSlide = () => { + setCurrentSlide((prev) => (prev - 1 + SLIDES.length) % SLIDES.length); + }; + + const slide = SLIDES[currentSlide]; + + return ( +
+ {/* Abstract Backgrounds (Dynamic based on slide) */} +
+
+
+
+
+ + {/* Content Container */} +
+ + {/* Large Decorative Text */} +

+ {slide.title1} +

+

+ {slide.title2} +

+ + {/* Subtitle Call to action */} +
+
+

+ {slide.subtitle} +

+
+ + {/* Decorative Elements */} +
+
+
+
+
+
+
+ + {/* Slide Indicators */} +
+ {SLIDES.map((_, index) => ( +
+ + {/* Carousel Controls */} + + +
+ ); +} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx new file mode 100644 index 0000000..e8c9c81 --- /dev/null +++ b/src/components/Navbar.tsx @@ -0,0 +1,49 @@ +import { Search, User } from 'lucide-react'; + +export default function Navbar() { + return ( + + ); +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..05bc19a --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import tailwindcss from '@tailwindcss/vite' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + tailwindcss(), + react() + ], +})