feat: initialize project structure with core UI components including Navbar, Footer, and Hero sections
This commit is contained in:
@@ -5,7 +5,7 @@ import Footer from './components/Footer';
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-[#0a0c10] text-slate-300 font-sans selection:bg-purple-500/30 selection:text-white flex flex-col">
|
<div className="min-h-screen bg-brutal-bg text-black font-sans selection:bg-brutal-pink selection:text-black flex flex-col">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className="flex-1 flex flex-col">
|
<main className="flex-1 flex flex-col">
|
||||||
|
|||||||
@@ -22,24 +22,24 @@ export default function EventCard({
|
|||||||
isAvailable = true,
|
isAvailable = true,
|
||||||
}: EventCardProps) {
|
}: EventCardProps) {
|
||||||
return (
|
return (
|
||||||
<div className="group flex flex-col bg-slate-900 border border-slate-800 rounded-3xl overflow-hidden hover:border-slate-700 hover:shadow-2xl hover:shadow-purple-500/10 transition-all duration-300">
|
<div className="group flex flex-col bg-white brutal-card h-full">
|
||||||
|
|
||||||
{/* Image Container */}
|
{/* Image Container */}
|
||||||
<div className="relative h-48 sm:h-56 overflow-hidden">
|
<div className="relative h-56 overflow-hidden brutal-border m-2 border-b-4">
|
||||||
<div className="absolute inset-0 bg-slate-800 animate-pulse" /> {/* Placeholder background */}
|
<div className="absolute inset-0 bg-brutal-yellow animate-pulse" />
|
||||||
<img
|
<img
|
||||||
src={image}
|
src={image}
|
||||||
alt={title}
|
alt={title}
|
||||||
className={`absolute inset-0 w-full h-full object-cover transition-transform duration-500 group-hover:scale-105 ${!isAvailable ? 'grayscale opacity-60' : ''}`}
|
className={`absolute inset-0 w-full h-full object-cover grayscale contrast-125 transition-transform duration-500 group-hover:scale-110 group-hover:grayscale-0 ${!isAvailable ? 'opacity-70' : ''}`}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Status Badge */}
|
{/* Status Badge */}
|
||||||
<div className="absolute top-4 left-4 z-10">
|
<div className="absolute top-4 left-4 z-10">
|
||||||
<span className={`px-3 py-1 text-xs font-bold rounded-full backdrop-blur-md ${
|
<span className={`px-4 py-2 text-sm font-black uppercase brutal-border ${
|
||||||
isAvailable
|
isAvailable
|
||||||
? 'bg-purple-600/80 text-white border border-purple-500/50'
|
? 'bg-brutal-pink text-black brutal-shadow-sm'
|
||||||
: 'bg-slate-800/80 text-slate-300 border border-slate-600/50'
|
: 'bg-white text-black brutal-shadow-sm'
|
||||||
}`}>
|
}`}>
|
||||||
{status}
|
{status}
|
||||||
</span>
|
</span>
|
||||||
@@ -48,46 +48,46 @@ export default function EventCard({
|
|||||||
|
|
||||||
{/* Content Container */}
|
{/* Content Container */}
|
||||||
<div className="flex flex-col flex-1 p-5 sm:p-6">
|
<div className="flex flex-col flex-1 p-5 sm:p-6">
|
||||||
<h3 className="font-display text-xl font-bold text-white mb-4 line-clamp-2 leading-tight">
|
<h3 className="font-display text-2xl font-black text-black mb-4 line-clamp-2 leading-tight uppercase group-hover:text-brutal-pink transition-colors">
|
||||||
{title}
|
{title}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="space-y-2 mb-6 mt-auto">
|
<div className="space-y-3 mb-6 mt-auto">
|
||||||
<div className="flex items-center gap-2 text-slate-400 text-sm">
|
<div className="flex items-center gap-3 text-black font-bold text-sm uppercase">
|
||||||
<MapPin className="w-4 h-4 shrink-0" />
|
<MapPin className="w-5 h-5 shrink-0 stroke-[3]" />
|
||||||
<span className="truncate">{location}</span>
|
<span className="truncate">{location}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-slate-400 text-sm">
|
<div className="flex items-center gap-3 text-black font-bold text-sm uppercase">
|
||||||
<Calendar className="w-4 h-4 shrink-0" />
|
<Calendar className="w-5 h-5 shrink-0 stroke-[3]" />
|
||||||
<span>{date}</span>
|
<span>{date}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer Area */}
|
{/* Footer Area */}
|
||||||
<div className="pt-4 mt-auto border-t border-slate-800 flex items-center justify-between">
|
<div className="pt-4 mt-auto border-t-4 border-black flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs text-slate-500 mb-0.5">START FROM</p>
|
<p className="text-sm font-black text-black mb-1 uppercase">START FROM</p>
|
||||||
{isAvailable ? (
|
{isAvailable ? (
|
||||||
<p className="font-display font-bold text-lg text-white">
|
<p className="font-display font-black text-xl text-black">
|
||||||
{price}
|
{price}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm font-medium text-slate-400">
|
<p className="text-sm font-bold text-gray-500 uppercase">
|
||||||
Ticket Belum Tersedia
|
Habis
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="text-xs text-slate-500 mt-0.5">By: {organizer}</p>
|
<p className="text-xs font-bold text-black mt-1 uppercase">BY: {organizer}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-semibold transition-all ${
|
className={`flex items-center gap-2 px-5 py-3 text-sm uppercase ${
|
||||||
isAvailable
|
isAvailable
|
||||||
? 'bg-slate-800 text-white hover:bg-slate-700'
|
? 'bg-brutal-blue brutal-btn'
|
||||||
: 'bg-transparent border border-slate-800 text-slate-500 cursor-not-allowed'
|
: 'bg-gray-200 border-4 border-black font-bold text-gray-500 cursor-not-allowed'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{isAvailable ? 'Beli' : 'Close'}
|
{isAvailable ? 'BELI TIKET' : 'CLOSE'}
|
||||||
<ArrowRight className="w-4 h-4" />
|
<ArrowRight className="w-5 h-5 stroke-[3]" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const MOCK_EVENTS = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
title: 'Tamasya lebaran',
|
title: 'TAMASYA LEBARAN',
|
||||||
image: 'https://images.unsplash.com/photo-1493225457124-a1a2a5956093?q=80&w=1000&auto=format&fit=crop',
|
image: 'https://images.unsplash.com/photo-1493225457124-a1a2a5956093?q=80&w=1000&auto=format&fit=crop',
|
||||||
date: '2024-04-18 18:00',
|
date: '2024-04-18 18:00',
|
||||||
location: 'PRSU, Medan',
|
location: 'PRSU, Medan',
|
||||||
@@ -50,42 +50,41 @@ const MOCK_EVENTS = [
|
|||||||
|
|
||||||
export default function EventSection() {
|
export default function EventSection() {
|
||||||
return (
|
return (
|
||||||
<section className="bg-[#0a0c10] py-24 px-4 sm:px-6 lg:px-8">
|
<section className="bg-brutal-bg py-24 px-4 sm:px-6 lg:px-8 border-b-4 border-black">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
|
|
||||||
{/* Section Header */}
|
{/* Brutalist Section Header */}
|
||||||
<div className="flex flex-col md:flex-row md:items-end justify-between mb-12 gap-6">
|
<div className="flex flex-col md:flex-row md:items-end justify-between mb-16 gap-8">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center gap-3 mb-3">
|
<div className="inline-block bg-brutal-yellow brutal-border px-4 py-1 mb-4 brutal-shadow-sm">
|
||||||
<div className="w-8 h-1 bg-purple-500 rounded-full"></div>
|
<span className="text-black font-black tracking-widest text-sm uppercase">Event Terbaru</span>
|
||||||
<span className="text-purple-400 font-semibold tracking-wider text-sm uppercase">Event Terbaru</span>
|
|
||||||
</div>
|
</div>
|
||||||
<h2 className="font-display text-3xl md:text-5xl font-bold text-white tracking-tight">
|
<h2 className="font-display text-5xl md:text-7xl font-black text-black tracking-tight uppercase leading-none">
|
||||||
Temukan Acaramu
|
TEMUKAN<br/>ACARAMU
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-slate-400 mt-3 text-lg">
|
<p className="text-black font-bold mt-6 text-xl max-w-xl uppercase">
|
||||||
Temukan acara favorit Anda, dan mari bersenang-senang
|
Jelajahi berbagai event spektakuler dan jangan lewatkan keseruannya!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className="hidden md:flex items-center gap-2 px-6 py-3 rounded-full border border-slate-700 text-slate-300 hover:text-white hover:border-slate-500 hover:bg-slate-800 transition-all text-sm font-medium shrink-0">
|
<button className="hidden md:flex items-center gap-3 px-8 py-4 bg-brutal-pink text-black text-lg font-black uppercase brutal-btn shrink-0">
|
||||||
View All Events
|
LIHAT SEMUA
|
||||||
<ArrowRight className="w-4 h-4" />
|
<ArrowRight className="w-6 h-6 stroke-[3]" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Events Grid */}
|
{/* Events Grid */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
||||||
{MOCK_EVENTS.map((event) => (
|
{MOCK_EVENTS.map((event) => (
|
||||||
<EventCard key={event.id} {...event} />
|
<EventCard key={event.id} {...event} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile View All Button */}
|
{/* Mobile View All Button */}
|
||||||
<div className="mt-10 flex justify-center md:hidden">
|
<div className="mt-12 flex justify-center md:hidden">
|
||||||
<button className="flex items-center gap-2 px-6 py-3 rounded-full border border-slate-700 text-slate-300 hover:text-white hover:border-slate-500 transition-all text-sm font-medium">
|
<button className="flex items-center gap-3 px-8 py-4 bg-brutal-pink text-black text-lg font-black uppercase brutal-btn">
|
||||||
View All Events
|
LIHAT SEMUA
|
||||||
<ArrowRight className="w-4 h-4" />
|
<ArrowRight className="w-6 h-6 stroke-[3]" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +1,139 @@
|
|||||||
import { Facebook, Instagram, Mail, MessageCircle } from 'lucide-react';
|
import { Facebook, Instagram, Mail, MessageCircle } from "lucide-react";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className="bg-[#0f111a] border-t border-white/5 pt-16 pb-8 px-4 sm:px-6 lg:px-8">
|
<footer className="bg-brutal-blue border-t-4 border-black pt-20 pb-10 px-4 sm:px-6 lg:px-8">
|
||||||
<div className="max-w-7xl mx-auto">
|
<div className="max-w-7xl mx-auto">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
|
||||||
|
|
||||||
{/* Brand Col */}
|
{/* Brand Col */}
|
||||||
<div className="col-span-1 md:col-span-2">
|
<div className="col-span-1 md:col-span-2">
|
||||||
<div className="flex items-center gap-2 mb-6">
|
<div className="flex items-center mb-6">
|
||||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center">
|
<span className="font-display font-black text-4xl text-black tracking-tight uppercase bg-white brutal-border px-4 py-2 brutal-shadow-sm inline-block">
|
||||||
<span className="text-white font-bold text-lg font-display">ST</span>
|
SMART
|
||||||
</div>
|
<span className="text-brutal-pink brutal-text-shadow">
|
||||||
<span className="font-display font-bold text-2xl text-white tracking-tight">
|
TICKET
|
||||||
Smart<span className="text-purple-400">Ticketing</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-slate-400 text-sm leading-relaxed max-w-sm mb-8">
|
<p className="text-black font-bold text-lg leading-relaxed max-w-sm mb-8 p-4 bg-brutal-yellow brutal-border brutal-shadow-sm">
|
||||||
Platform tiket konser dan event terpercaya di Indonesia. Pembayaran online lebih gampang.
|
PLATFORM TIKET KONSER DAN EVENT TERPERCAYA DI INDONESIA.
|
||||||
|
PEMBAYARAN ONLINE LEBIH GAMPANG, CEPAT, DAN AMAN.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<a href="#" className="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center text-slate-400 hover:bg-purple-600 hover:text-white transition-all">
|
<a
|
||||||
<Facebook className="w-5 h-5" />
|
href="#"
|
||||||
|
className="w-14 h-14 bg-brutal-pink text-black flex items-center justify-center brutal-btn hover:bg-white transition-colors"
|
||||||
|
>
|
||||||
|
<Facebook className="w-6 h-6 stroke-[3]" />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center text-slate-400 hover:bg-purple-600 hover:text-white transition-all">
|
<a
|
||||||
<Instagram className="w-5 h-5" />
|
href="#"
|
||||||
|
className="w-14 h-14 bg-brutal-yellow text-black flex items-center justify-center brutal-btn hover:bg-white transition-colors"
|
||||||
|
>
|
||||||
|
<Instagram className="w-6 h-6 stroke-[3]" />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center text-slate-400 hover:bg-purple-600 hover:text-white transition-all">
|
<a
|
||||||
<Mail className="w-5 h-5" />
|
href="#"
|
||||||
|
className="w-14 h-14 bg-white text-black flex items-center justify-center brutal-btn hover:bg-brutal-pink transition-colors"
|
||||||
|
>
|
||||||
|
<Mail className="w-6 h-6 stroke-[3]" />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center text-slate-400 hover:bg-purple-600 hover:text-white transition-all">
|
<a
|
||||||
<MessageCircle className="w-5 h-5" />
|
href="#"
|
||||||
|
className="w-14 h-14 bg-brutal-orange text-black flex items-center justify-center brutal-btn hover:bg-white transition-colors"
|
||||||
|
>
|
||||||
|
<MessageCircle className="w-6 h-6 stroke-[3]" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Links Col 1 */}
|
{/* Links Col 1 */}
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-display font-bold text-white mb-6 uppercase tracking-wider text-sm">Platform</h4>
|
<h4 className="font-display font-black text-white text-2xl mb-6 uppercase tracking-widest brutal-text-shadow">
|
||||||
|
PLATFORM
|
||||||
|
</h4>
|
||||||
<ul className="space-y-4">
|
<ul className="space-y-4">
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Beranda</a></li>
|
<li>
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Event Terbaru</a></li>
|
<a
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Semua Event</a></li>
|
href="#"
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Kategori</a></li>
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
BERANDA
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
EVENT TERBARU
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
SEMUA EVENT
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
KATEGORI
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Links Col 2 */}
|
{/* Links Col 2 */}
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-display font-bold text-white mb-6 uppercase tracking-wider text-sm">Bantuan</h4>
|
<h4 className="font-display font-black text-white text-2xl mb-6 uppercase tracking-widest brutal-text-shadow">
|
||||||
|
BANTUAN
|
||||||
|
</h4>
|
||||||
<ul className="space-y-4">
|
<ul className="space-y-4">
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Hubungi Kami</a></li>
|
<li>
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Syarat & Ketentuan</a></li>
|
<a
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">Kebijakan Privasi</a></li>
|
href="#"
|
||||||
<li><a href="#" className="text-slate-400 hover:text-purple-400 transition-colors text-sm">FAQ</a></li>
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
HUBUNGI KAMI
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
SYARAT KETENTUAN
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
PRIVASI
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
className="text-black hover:text-white transition-colors text-lg font-bold uppercase underline decoration-4 underline-offset-4 hover:bg-black px-2 py-1 inline-block"
|
||||||
|
>
|
||||||
|
FAQ
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="pt-8 border-t border-slate-800 flex flex-col md:flex-row items-center justify-between gap-4">
|
<div className="pt-8 border-t-4 border-black flex flex-col md:flex-row items-center justify-between gap-6">
|
||||||
<p className="text-slate-500 text-xs">
|
<p className="text-black text-lg font-black uppercase bg-white px-4 py-2 brutal-border">
|
||||||
© {new Date().getFullYear()} Smart Ticketing. All rights reserved.
|
© {new Date().getFullYear()} SMART TICKET. ALL RIGHTS RESERVED.
|
||||||
</p>
|
|
||||||
<p className="text-slate-500 text-xs">
|
|
||||||
Made with love in Indonesia
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,40 +1,18 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from "react";
|
||||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
||||||
|
|
||||||
const SLIDES = [
|
const SLIDES = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
title1: "Music Festival",
|
videoId: "Fpn1imb9qZg",
|
||||||
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,
|
id: 2,
|
||||||
title1: "Standup Comedy",
|
videoId: "PN7Pv23FrWg",
|
||||||
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,
|
id: 3,
|
||||||
title1: "E-Sports",
|
videoId: "YsJqKjD2sXE",
|
||||||
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() {
|
export default function Hero() {
|
||||||
@@ -44,89 +22,56 @@ export default function Hero() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
setCurrentSlide((prev) => (prev + 1) % SLIDES.length);
|
setCurrentSlide((prev) => (prev + 1) % SLIDES.length);
|
||||||
}, 5000);
|
}, 6000);
|
||||||
return () => clearInterval(timer);
|
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 (
|
return (
|
||||||
<div className="relative min-h-[90vh] flex items-center justify-center overflow-hidden bg-slate-950 pt-20 transition-colors duration-1000">
|
<div className="relative bg-white pt-32 pb-20 lg:pt-40 lg:pb-32 overflow-hidden border-b-4 border-black min-h-[90vh] flex items-center">
|
||||||
{/* Abstract Backgrounds (Dynamic based on slide) */}
|
{/* Absolute light blue background block on the left */}
|
||||||
<div className="absolute inset-0 w-full h-full transition-all duration-1000">
|
<div className="absolute left-0 top-1/2 -translate-y-1/2 w-1/3 h-[300px] bg-[#c2e2ff] hidden lg:block z-0 border-y-4 border-r-4 border-black"></div>
|
||||||
<div className={`absolute top-0 left-1/4 w-[800px] h-[800px] ${slide.blob1} rounded-full blur-[150px] mix-blend-screen animate-pulse transition-colors duration-1000`} />
|
|
||||||
<div className={`absolute bottom-0 right-1/4 w-[600px] h-[600px] ${slide.blob2} rounded-full blur-[120px] mix-blend-screen transition-colors duration-1000`} />
|
|
||||||
<div className={`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[1000px] h-[500px] ${slide.blob3} rounded-full blur-[150px] transition-colors duration-1000`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Content Container */}
|
<div className="max-w-[1440px] mx-auto px-4 sm:px-6 lg:px-8 relative z-10 w-full">
|
||||||
<div className="relative z-10 text-center px-4 max-w-5xl mx-auto flex flex-col items-center">
|
<div className="lg:grid lg:grid-cols-12 lg:gap-8 items-center">
|
||||||
|
{/* Left Content */}
|
||||||
{/* Large Decorative Text */}
|
<div className="lg:col-span-5 mb-16 lg:mb-0 relative z-10">
|
||||||
<h1
|
<h1 className="text-6xl lg:text-7xl xl:text-8xl font-display font-black text-black tracking-tighter leading-[0.9] mb-8 uppercase flex flex-col items-start">
|
||||||
key={`title1-${slide.id}`}
|
<span>ACCESS</span>
|
||||||
className={`font-display font-black text-6xl md:text-8xl lg:text-9xl text-transparent bg-clip-text bg-gradient-to-r ${slide.gradientText} drop-shadow-2xl mb-2 tracking-tighter uppercase animate-in fade-in slide-in-from-bottom-4 duration-700`}
|
<span className="inline-block px-4 py-1 bg-[#7cb9ff] brutal-border shadow-[6px_6px_0_0_#000] rotate-[-2deg] mt-2 ml-4">
|
||||||
>
|
THE GRID
|
||||||
{slide.title1}
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<h2
|
<p className="text-lg font-bold text-black mb-12 max-w-md">
|
||||||
key={`title2-${slide.id}`}
|
Next-generation ticketing for the brutalist era. No hidden fees.
|
||||||
className="font-display font-black text-6xl md:text-8xl lg:text-9xl text-slate-100 drop-shadow-2xl tracking-tighter uppercase mb-8 animate-in fade-in slide-in-from-bottom-4 duration-700 delay-100 fill-mode-backwards"
|
No scalpers. Just raw access.
|
||||||
>
|
</p>
|
||||||
{slide.title2}
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{/* Subtitle Call to action */}
|
<button className="px-8 py-4 bg-[#7cb9ff] brutal-border shadow-[8px_8px_0_0_#000] hover:shadow-[4px_4px_0_0_#000] hover:translate-x-1 hover:translate-y-1 transition-all text-black font-black text-xl tracking-wider uppercase">
|
||||||
<div className="inline-block relative animate-in fade-in slide-in-from-bottom-4 duration-700 delay-200 fill-mode-backwards" key={`sub-${slide.id}`}>
|
EXPLORE EVENTS
|
||||||
<div className={`absolute inset-0 bg-gradient-to-r ${slide.gradientSub} blur-xl opacity-30 transition-colors duration-1000`}></div>
|
</button>
|
||||||
<h3 className={`relative font-display font-extrabold text-3xl md:text-5xl text-transparent bg-clip-text bg-gradient-to-r ${slide.gradientSub} tracking-tight uppercase transition-colors duration-1000`}>
|
</div>
|
||||||
{slide.subtitle}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Decorative Elements */}
|
{/* Right Content - Wide Video Container */}
|
||||||
<div className="absolute top-1/4 left-10 md:left-20 animate-bounce delay-100 hidden lg:block">
|
<div className="lg:col-span-7 relative">
|
||||||
<div className="w-16 h-16 rounded-3xl bg-gradient-to-tr from-cyan-400 to-blue-500 rotate-12 shadow-[0_0_30px_rgba(34,211,238,0.4)]" />
|
<div className="relative w-full aspect-video bg-black brutal-border shadow-[12px_12px_0_0_#000] lg:shadow-[16px_16px_0_0_#000] overflow-hidden">
|
||||||
</div>
|
{/* Render ALL iframes at once to keep them playing, just toggle opacity */}
|
||||||
<div className="absolute bottom-1/4 right-10 md:right-20 animate-bounce delay-300 hidden lg:block">
|
{SLIDES.map((slide, idx) => (
|
||||||
<div className="w-20 h-20 rounded-full bg-gradient-to-tr from-yellow-400 to-orange-500 shadow-[0_0_30px_rgba(250,204,21,0.4)]" />
|
<iframe
|
||||||
|
key={`video-${slide.id}`}
|
||||||
|
src={`https://www.youtube.com/embed/${slide.videoId}?autoplay=1&mute=1&controls=0&loop=1&playlist=${slide.videoId}&modestbranding=1&playsinline=1&rel=0&showinfo=0&disablekb=1`}
|
||||||
|
className={`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[150%] h-[150%] max-w-none pointer-events-none transition-opacity duration-700 ease-in-out ${
|
||||||
|
currentSlide === idx ? "opacity-100 z-10" : "opacity-0 z-0"
|
||||||
|
}`}
|
||||||
|
allow="autoplay; encrypted-media; fullscreen"
|
||||||
|
frameBorder="0"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="absolute inset-0 bg-blue-900 mix-blend-multiply opacity-20 pointer-events-none z-20"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Slide Indicators */}
|
|
||||||
<div className="absolute bottom-10 left-1/2 -translate-x-1/2 flex items-center gap-3 z-20">
|
|
||||||
{SLIDES.map((_, index) => (
|
|
||||||
<button
|
|
||||||
key={index}
|
|
||||||
onClick={() => setCurrentSlide(index)}
|
|
||||||
className={`w-3 h-3 rounded-full transition-all duration-300 ${
|
|
||||||
currentSlide === index ? 'bg-white w-8' : 'bg-white/30 hover:bg-white/60'
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Carousel Controls */}
|
|
||||||
<button
|
|
||||||
onClick={prevSlide}
|
|
||||||
className="absolute left-4 md:left-10 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white/50 hover:text-white hover:bg-white/10 transition-all backdrop-blur-md z-20"
|
|
||||||
>
|
|
||||||
<ChevronLeft className="w-6 h-6" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={nextSlide}
|
|
||||||
className="absolute right-4 md:right-10 top-1/2 -translate-y-1/2 w-12 h-12 rounded-full bg-white/5 border border-white/10 flex items-center justify-center text-white/50 hover:text-white hover:bg-white/10 transition-all backdrop-blur-md z-20"
|
|
||||||
>
|
|
||||||
<ChevronRight className="w-6 h-6" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,38 @@
|
|||||||
import { Search, User } from 'lucide-react';
|
import { Ticket } from "lucide-react";
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
<nav className="fixed top-0 w-full z-50 bg-[#0f111a]/80 backdrop-blur-md border-b border-white/5 transition-all">
|
<nav className="fixed top-0 w-full z-50 bg-white brutal-border transition-all border-b-[6px]">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-[1440px] mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="flex items-center justify-between h-20">
|
<div className="flex items-center justify-between h-20">
|
||||||
|
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<div className="flex-shrink-0 flex items-center gap-2 cursor-pointer">
|
<div className="flex-shrink-0 flex items-center cursor-pointer gap-3">
|
||||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center">
|
<div className="p-1 border-4 border-black bg-white">
|
||||||
<span className="text-white font-bold text-lg font-display">ST</span>
|
<Ticket className="w-6 h-6 stroke-[3]" />
|
||||||
</div>
|
</div>
|
||||||
<span className="font-display font-bold text-2xl text-white tracking-tight">
|
<span className="font-display font-black text-2xl md:text-3xl text-black tracking-tighter uppercase">
|
||||||
Smart<span className="text-purple-400">Ticketing</span>
|
SMART TICKET
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Search Bar */}
|
{/* Centered Navigation Links */}
|
||||||
<div className="hidden md:flex flex-1 max-w-xl mx-8">
|
<div className="hidden md:flex flex-1 justify-center space-x-8 items-center">
|
||||||
<div className="relative w-full">
|
<a
|
||||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
href="#"
|
||||||
<Search className="h-4 w-4 text-slate-400" />
|
className="bg-[#7cb9ff] text-black font-black uppercase text-sm px-6 py-2 border-4 border-black brutal-shadow-sm hover:-translate-y-1 hover:shadow-[6px_6px_0_0_#000] transition-all"
|
||||||
</div>
|
>
|
||||||
<input
|
Tickets
|
||||||
type="text"
|
</a>
|
||||||
className="block w-full pl-10 pr-3 py-2.5 border-transparent rounded-2xl bg-slate-800/50 text-slate-300 placeholder-slate-400 focus:outline-none focus:bg-slate-800 focus:ring-2 focus:ring-purple-500/50 sm:text-sm transition-all"
|
<a
|
||||||
placeholder="Cari event, konser, festival..."
|
href="#"
|
||||||
/>
|
className="text-black font-bold uppercase text-sm hover:underline decoration-4 underline-offset-4"
|
||||||
<div className="absolute inset-y-1 right-1">
|
>
|
||||||
<button className="h-full px-4 rounded-xl bg-purple-600 hover:bg-purple-500 text-white text-xs font-semibold transition-colors">
|
Events
|
||||||
Search
|
</a>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="hidden md:flex items-center">
|
||||||
{/* Right Navigation */}
|
<button className="bg-[#ffd700] text-black font-black text-sm px-6 py-3 brutal-btn">
|
||||||
<div className="flex items-center gap-4">
|
Find Your Event
|
||||||
<button className="flex items-center gap-2 text-slate-300 hover:text-white transition-colors px-4 py-2 rounded-xl hover:bg-slate-800/50 font-medium text-sm">
|
|
||||||
<User className="w-4 h-4" />
|
|
||||||
Sign In
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,18 +1,59 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
/* Set Up Custom Google Fonts */
|
--font-sans: 'Space Grotesk', 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif;
|
||||||
--font-sans: 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
--font-display: 'Space Grotesk', 'Outfit', ui-sans-serif, system-ui, sans-serif;
|
||||||
--font-display: 'Outfit', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
||||||
|
/* Brutalist color palette */
|
||||||
/* Custom Neon/Vibrant Gradients or Colors if needed later */
|
--color-brutal-yellow: #FFD800;
|
||||||
--color-brand-neon: #10B981;
|
--color-brutal-pink: #FF90E8;
|
||||||
--color-brand-electric: #6366F1;
|
--color-brutal-blue: #23A094;
|
||||||
|
--color-brutal-orange: #FF5A5F;
|
||||||
|
--color-brutal-bg: #F4F0E6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.brutal-border {
|
||||||
|
border: 4px solid #000;
|
||||||
|
}
|
||||||
|
.brutal-shadow {
|
||||||
|
box-shadow: 8px 8px 0px 0px #000;
|
||||||
|
}
|
||||||
|
.brutal-shadow-sm {
|
||||||
|
box-shadow: 4px 4px 0px 0px #000;
|
||||||
|
}
|
||||||
|
.brutal-text-shadow {
|
||||||
|
text-shadow: 3px 3px 0px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brutal-btn {
|
||||||
|
border: 4px solid #000;
|
||||||
|
box-shadow: 6px 6px 0px 0px #000;
|
||||||
|
font-weight: 800;
|
||||||
|
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.brutal-btn:hover {
|
||||||
|
transform: translate(-2px, -2px);
|
||||||
|
box-shadow: 8px 8px 0px 0px #000;
|
||||||
|
}
|
||||||
|
.brutal-btn:active {
|
||||||
|
box-shadow: 0px 0px 0px 0px #000;
|
||||||
|
transform: translate(6px, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.brutal-card {
|
||||||
|
border: 4px solid #000;
|
||||||
|
box-shadow: 8px 8px 0px 0px #000;
|
||||||
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.brutal-card:hover {
|
||||||
|
box-shadow: 12px 12px 0px 0px #000;
|
||||||
|
transform: translate(-4px, -4px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom baseline styling if desired */
|
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
background-color: var(--color-brutal-bg);
|
||||||
padding: 0;
|
color: #000;
|
||||||
min-height: 100vh;
|
font-family: var(--font-sans);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user