SameerArz commited on
Commit
d82c543
·
verified ·
1 Parent(s): 18d5060

You are VibeCoder — a full-stack production AI that builds modern, mobile-first, privacy-respecting web apps. Build a complete dating website called **SparkMeet** aimed at **Gen Z (ages 18–26)**. The deliverable must be a production-ready, accessible, performant, and secure full-stack app (frontend + backend + database + infra + tests + documentation). Use modern tech: React + TypeScript (Next.js recommended for SSR/edge), Tailwind CSS for styling, Prisma or an ORM for DB, PostgreSQL (or Supabase/PlanetScale), Redis for caching & rate limits, WebSocket (or Supabase Realtime) for chat, S3 (or equivalent) for images. Provide a runnable repo layout, README, and end-to-end tests.

Browse files

--- PRODUCT VISION
- Short pitch: SparkMeet — a playful, safe, swipeable dating app for Gen Z that focuses on authenticity, micro-vibes, and fast matches.
- Tone & Branding: playful, concise, inclusive. Use short microcopy and emojis sparingly. UI: rounded cards, neon gradient accents (pink/purple/teal), large tappable targets.
- Target: mobile-first progressive web app (works on desktop & mobile).

--- CORE MVP FEATURES (must implement)
1. Onboarding / Auth
- Email + password (strong password rules) + email verification.
- OAuth 2.0 options: Google & Apple (if available).
- Phone number + OTP or passwordless email as an option.
- Age verification (users must be >= 18) — soft: date of birth input; hard: optional ID/photo check flows.
2. Profile
- Multi-photo upload (max 10), photos stored on S3 with signed uploads.
- Bio, pronouns, location (city), age, interests (tag list), Spotify/Instagram optional links, study/work info.
- "Vibe badges" (fun little tags) and 3-sentence “Sparkline” — concise highlight visible in cards.
3. Discovery
- Swipe interface + grid/list mode.
- Filters: distance, age range, interests, online now.
- “Spark” mechanic: a paid or earned boost that increases visibility.
4. Matching
- Mutual likes create a Match — open match chat.
- Notification on match + celebratory modal/UI.
5. Chat
- Real-time messaging via WebSocket or WebRTC data channels.
- Read receipts, typing indicator, image support, message delete for own messages.
- Safety commands: report, block, mute.
6. Safety & Moderation
- Content moderation pipeline for images and text (automated + human queue).
- Report/Block flows, rate limiting, anti-spam heuristics.
7. Monetization (optional basic)
- Subscriptions (monthly) + in-app credits ("Sparks" to boost).
- Stripe integration for payments.
8. Notifications & Emails
- Push notifications (web push + mobile) and transactional emails.
9. Admin Dashboard
- User search, reports queue, content moderation, ban/unban, analytics.
10. Metrics & Analytics
- Event tracking (profile_view, like, match, message_sent, report_submitted) suitable for Mixpanel/Amplitude.

--- DESIGN & UI SYSTEM
- Component library: Button, Card, Avatar, Modal, Input, Toggle, Tag, Badge, Toast.
- Responsive breakpoints; mobile-first.
- Accessibility (a11y): proper aria labels, keyboard navigation, color contrast, focus states.
- Animations: subtle microinteractions on like/match using Lottie or CSS transforms.

--- DETAILED PAGE & UI COMPONENTS (with **every** button + exact behavior)

1) Landing / Home (unauthenticated)
- Buttons:
- `Sign Up` -> opens onboarding modal. Behavior: opens `/signup` route. Track event: `cta_signup_clicked`.
- `Log In` -> opens login modal. Behavior: `/login`. Track `cta_login_clicked`.
- `Learn More` -> scroll or route to features section. Track `cta_learn_more`.
- SEO meta tags and social preview.

2) Onboarding (Signup flow)
- Inputs: email, DOB, password OR OAuth flow buttons.
- Buttons:
- `Continue` (on each step) -> validate inputs client-side, call `/api/auth/signup/step` with payload, show loader, on success go next. Analytics `onboarding_step_completed` with properties {step, method}.
- `Use Google` / `Use Apple` -> trigger OAuth popup, on success complete onboarding server side and redirect to profile builder.
- `Back` -> navigate to previous step, save partial state in localStorage.
- `Skip` (for optional steps) -> store default values and continue.
- Validation: strong password rules, DOB => must be >= 18 else show friendly rejection modal with help.

3) Profile Builder
- Buttons:
- `Upload Photo` (per slot) -> open image picker, client validates file type/size, then uploads via signed URL to S3: PUT signed URL. After upload, POST `/api/users/{id}/photos` to register. Show progress and allow reorder. Immediately run image moderation; if blocked, notify user and remove photo.
- `Save Profile` -> PUT `/api/users/{id}` with full profile JSON. On success show toast "Profile saved".
- `Add Badge` -> opens tag selector modal; PUT update profile interests.
- `Preview Profile` -> open public view page; track `profile_preview`.
- Edge cases: network failure -> retry modal with retry/back options.

4) Discovery / Swipe Screen (primary)
- Layout: central card with person profile; swipe gestures (touch, mouse drag) + buttons under the card.
- Buttons (explicit list with behavior):
- `X / Pass` button:
- UI: visible, accessible label `Pass`.
- Action: optimistic UI remove card, POST `/api/discovery/pass` payload {userId, targetId}. If response error, revert card and show error toast. Track `discovery_pass`.
- `Like` (heart):
- UI: toggleable, triggers animation.
- Action: optimistic UI mark liked. POST `/api/matches/like` with {fromUserId, toUserId}. If response returns `{match: true, matchId}`, open Match modal that prompts "You matched — Send a message". Create a conversation in DB and navigate to chat if user clicks. Track `discovery_like` with property {match: boolean}.
- `SuperSpark` (special):
- UI: uses Sparks credit or subscription. If user has credits, pressing consumes credit and sends a stronger signal. POST `/api/matches/superspark`. Show confirmation modal with microcopy and animation. Track `discovery_superspark`.
- `Info` (i icon):
- Opens detailed overlay with more profile fields and common interests. Track `discovery_info_open`.
- Swipe gestures:
- Right = Like, Left = Pass, Up = SuperSpark. On each gesture, call the same endpoints as corresponding buttons. Debounce swipes to prevent accidental repeats.

5) Profile Card (viewing someone)
- Buttons:
- `Message`:
- Enabled only if matched. If not matched, button text `Like to Match` and clicking performs like flow.
- If matched, opens chat window, focus input. Track `profile_message_open`.
- `Spark` icon on card:
- Behavior same as SuperSpark.
- `Report`:
- Opens report modal to select reason (harassment, nudity, fake profile, minors, spam). On submit: POST `/api/reports` with last messages & last 5 photos metadata. Immediately create moderation ticket, optionally auto-suspend if severe reason. Track `profile_report_submitted`.
- `Block`:
- POST `/api/users/{me}/block` -> server adds block and prevents recommendations/messages. Client hides the user and shows undo toast `User blocked`.
- `Follow` (if you want social features) — optional.

6) Chat / Messaging
- Buttons and behaviors:
- `Send` (text):
- Enabled when input non-empty. Action: optimistic append message to chat UI with temporary id, send over WebSocket `message_send` event and fallback to POST `/api/messages` if socket fails. On ACK replace temp id with real id. Track `message_sent` with length properties.
- Validation: check for banned words; block sending or flag if present.
- `Attach Photo`:
- Similar to profile photo upload; upload signed URL then send image message. Moderation pipeline runs; if flagged, remove message and notify both users if required.
- `Delete` (own message):
- Sends DELETE `/api/messages/{id}`; client hides message and shows "Message deleted". Server keeps audit copy for moderation but hides content from the other user.
- `Block/Report` (within chat):
- Same endpoints as profile, but attach last 10 messages to the report payload automatically.
- `Start Video Date`:
- If both agree, start WebRTC flow via signaling server. Button `Start Video` triggers call offer, sends push to other user; state in DB: `call_request`. Track `video_call_requested`.

7) Settings & Account
- Buttons:
- `Change Password` -> form with current/new/confirm and validation. POST `/api/auth/change-password`.
- `Delete Account` -> requires password confirm and shows 2-step modal. DELETE `/api/users/{id}` (soft delete: mark as deleted, anonymize). Provide grace period before permanent deletion.
- `Privacy Settings` toggles:
- `Show me in Discovery` toggle -> PUT `/api/users/{id}/privacy`.
- `Allow message from non-matches` toggle -> PUT.
- `Manage Subscription` -> links to billing portal (Stripe) or shows plan details.
- `Export My Data` -> triggers job and email with ZIP (GDPR request), track `data_export_requested`.

--- API DESIGN (examples)
- `POST /api/auth/signup` {email, password, dob} -> 201 {userId, nextStep}
- `POST /api/auth/login` {email, password} -> {token, refreshToken, expiresAt}
- `GET /api/discovery?cursor=...&filters=...` -> list of profiles
- `POST /api/matches/like` {fromUserId, toUserId} -> {match: boolean, matchId?: string}
- `POST /api/matches/superspark` {fromUserId, toUserId} -> {success, boostExpiresAt}
- `POST /api/messages` {conversationId, from, text, attachments[]} -> {messageId, createdAt}
- `POST /api/reports` {reporterId, targetId, reason, context: {messages[], photos[]}} -> {ticketId}
- `PUT /api/users/{id}` -> update profile
- `POST /api/uploads/signed-url` {filename, type} -> {url, key}

Include auth middleware (JWT + refresh tokens), RBAC for admin endpoints.

--- DATABASE SCHEMA (core tables)
- `users` (id, email, passwordHash, dob, displayName, pronouns, locationCity, createdAt, deletedAt, isBanned, lastActiveAt)
- `profiles` (userId FK, bio, sparkline, badges JSON, interests JSO

Files changed (5) hide show
  1. README.md +9 -5
  2. index.html +492 -18
  3. login.html +121 -0
  4. profile-builder.html +62 -0
  5. signup.html +171 -0
README.md CHANGED
@@ -1,10 +1,14 @@
1
  ---
2
- title: Undefined
3
- emoji: 📈
4
- colorFrom: purple
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: undefined
3
+ colorFrom: pink
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
14
+
index.html CHANGED
@@ -1,19 +1,493 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SparkMeet - Discover Events</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <style>
10
+ .event-card:hover {
11
+ transform: translateY(-5px);
12
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
13
+ }
14
+ .category-filter.active {
15
+ background-color: #6366f1;
16
+ color: white;
17
+ }
18
+ .modal {
19
+ transition: all 0.3s ease;
20
+ }
21
+ </style>
22
+ </head>
23
+ <body class="bg-gray-50 font-sans">
24
+ <!-- Navigation -->
25
+ <nav class="bg-white shadow-lg sticky top-0 z-50">
26
+ <div class="max-w-6xl mx-auto px-4">
27
+ <div class="flex justify-between items-center py-4">
28
+ <div class="flex items-center space-x-4">
29
+ <a href="#" class="flex items-center space-x-2">
30
+ <span class="text-2xl font-bold text-indigo-600">SparkMeet</span>
31
+ </a>
32
+ </div>
33
+ <div class="hidden md:flex items-center space-x-8">
34
+ <a href="#" class="text-indigo-600 font-medium flex items-center">
35
+ <i data-feather="home" class="mr-2"></i> Home
36
+ </a>
37
+ <a href="#" class="text-gray-600 hover:text-indigo-600 font-medium flex items-center">
38
+ <i data-feather="calendar" class="mr-2"></i> Create Event
39
+ </a>
40
+ <a href="#" class="text-gray-600 hover:text-indigo-600 font-medium flex items-center">
41
+ <i data-feather="message-square" class="mr-2"></i> Messages
42
+ </a>
43
+ <div class="relative">
44
+ <button id="user-menu" class="flex items-center space-x-2 focus:outline-none">
45
+ <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Profile" class="w-8 h-8 rounded-full">
46
+ <i data-feather="chevron-down" class="w-4 h-4"></i>
47
+ </button>
48
+ <div id="dropdown-menu" class="hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-50">
49
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-50">Dashboard</a>
50
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-50">Settings</a>
51
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-50">Sign out</a>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ <div class="md:hidden">
56
+ <button id="mobile-menu-button" class="text-gray-600 focus:outline-none">
57
+ <i data-feather="menu"></i>
58
+ </button>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </nav>
63
+
64
+ <!-- Mobile Menu -->
65
+ <div id="mobile-menu" class="hidden md:hidden bg-white shadow-lg">
66
+ <div class="px-2 pt-2 pb-3 space-y-1 sm:px-3">
67
+ <a href="#" class="block px-3 py-2 text-base font-medium text-indigo-600">Home</a>
68
+ <a href="#" class="block px-3 py-2 text-base font-medium text-gray-600 hover:text-indigo-600">Create Event</a>
69
+ <a href="#" class="block px-3 py-2 text-base font-medium text-gray-600 hover:text-indigo-600">Messages</a>
70
+ <a href="#" class="block px-3 py-2 text-base font-medium text-gray-600 hover:text-indigo-600">Dashboard</a>
71
+ </div>
72
+ </div>
73
+
74
+ <!-- Hero Section -->
75
+ <div class="bg-gradient-to-r from-indigo-500 to-purple-600 text-white py-16">
76
+ <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
77
+ <h1 class="text-4xl md:text-5xl font-bold mb-6">Discover Your Next Adventure</h1>
78
+ <p class="text-xl md:text-2xl mb-8">Find and join amazing events happening around you</p>
79
+ <div class="max-w-md mx-auto">
80
+ <div class="relative">
81
+ <input type="text" placeholder="Search for events..." class="w-full px-6 py-4 rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-400 text-gray-800">
82
+ <button class="absolute right-2 top-2 bg-indigo-600 text-white p-2 rounded-full">
83
+ <i data-feather="search"></i>
84
+ </button>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- Category Filters -->
91
+ <div class="max-w-6xl mx-auto px-4 py-8">
92
+ <div class="flex overflow-x-auto space-x-4 pb-4 scrollbar-hide">
93
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium active">
94
+ All Events
95
+ </button>
96
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium">
97
+ Food & Culture
98
+ </button>
99
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium">
100
+ Parties
101
+ </button>
102
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium">
103
+ Workshops
104
+ </button>
105
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium">
106
+ Sports
107
+ </button>
108
+ <button class="category-filter flex-shrink-0 px-6 py-2 rounded-full bg-white shadow text-gray-700 font-medium">
109
+ Networking
110
+ </button>
111
+ </div>
112
+ </div>
113
+
114
+ <!-- Events Grid -->
115
+ <div class="max-w-6xl mx-auto px-4 py-8">
116
+ <h2 class="text-2xl font-bold mb-6">Popular Events Near You</h2>
117
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
118
+ <!-- Event Card 1 -->
119
+ <div class="event-card bg-white rounded-xl shadow-md overflow-hidden transition-all duration-300">
120
+ <div class="h-48 bg-indigo-100 relative">
121
+ <img src="https://images.unsplash.com/photo-1519671482749-fd09be7ccebf?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Event" class="w-full h-full object-cover">
122
+ <div class="absolute top-4 right-4 bg-white rounded-full px-3 py-1 shadow flex items-center">
123
+ <i data-feather="map-pin" class="w-4 h-4 mr-1 text-indigo-600"></i>
124
+ <span class="text-sm font-medium">New York</span>
125
+ </div>
126
+ </div>
127
+ <div class="p-6">
128
+ <div class="flex justify-between items-start mb-2">
129
+ <h3 class="text-xl font-bold">Food Festival 2023</h3>
130
+ <span class="bg-indigo-100 text-indigo-800 text-xs px-2 py-1 rounded-full">Food & Culture</span>
131
+ </div>
132
+ <p class="text-gray-600 mb-4">Join us for the biggest food festival of the year with top chefs and amazing dishes.</p>
133
+ <div class="flex justify-between items-center">
134
+ <div class="flex items-center">
135
+ <i data-feather="calendar" class="w-4 h-4 mr-2 text-indigo-600"></i>
136
+ <span class="text-sm">Oct 15, 2023</span>
137
+ </div>
138
+ <button class="view-details-btn px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
139
+ View Details
140
+ </button>
141
+ </div>
142
+ </div>
143
+ </div>
144
+
145
+ <!-- Event Card 2 -->
146
+ <div class="event-card bg-white rounded-xl shadow-md overflow-hidden transition-all duration-300">
147
+ <div class="h-48 bg-purple-100 relative">
148
+ <img src="https://images.unsplash.com/photo-1492684223066-81342ee5ff30?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Event" class="w-full h-full object-cover">
149
+ <div class="absolute top-4 right-4 bg-white rounded-full px-3 py-1 shadow flex items-center">
150
+ <i data-feather="map-pin" class="w-4 h-4 mr-1 text-indigo-600"></i>
151
+ <span class="text-sm font-medium">Miami</span>
152
+ </div>
153
+ </div>
154
+ <div class="p-6">
155
+ <div class="flex justify-between items-start mb-2">
156
+ <h3 class="text-xl font-bold">Beach Party</h3>
157
+ <span class="bg-purple-100 text-purple-800 text-xs px-2 py-1 rounded-full">Party</span>
158
+ </div>
159
+ <p class="text-gray-600 mb-4">The hottest beach party of the summer with DJs, drinks and amazing vibes.</p>
160
+ <div class="flex justify-between items-center">
161
+ <div class="flex items-center">
162
+ <i data-feather="calendar" class="w-4 h-4 mr-2 text-indigo-600"></i>
163
+ <span class="text-sm">Nov 5, 2023</span>
164
+ </div>
165
+ <button class="view-details-btn px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
166
+ View Details
167
+ </button>
168
+ </div>
169
+ </div>
170
+ </div>
171
+
172
+ <!-- Event Card 3 -->
173
+ <div class="event-card bg-white rounded-xl shadow-md overflow-hidden transition-all duration-300">
174
+ <div class="h-48 bg-green-100 relative">
175
+ <img src="https://images.unsplash.com/photo-1505373877841-8d25f7d46678?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="Event" class="w-full h-full object-cover">
176
+ <div class="absolute top-4 right-4 bg-white rounded-full px-3 py-1 shadow flex items-center">
177
+ <i data-feather="map-pin" class="w-4 h-4 mr-1 text-indigo-600"></i>
178
+ <span class="text-sm font-medium">San Francisco</span>
179
+ </div>
180
+ </div>
181
+ <div class="p-6">
182
+ <div class="flex justify-between items-start mb-2">
183
+ <h3 class="text-xl font-bold">Tech Workshop</h3>
184
+ <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">Workshop</span>
185
+ </div>
186
+ <p class="text-gray-600 mb-4">Learn the latest in web development from industry experts.</p>
187
+ <div class="flex justify-between items-center">
188
+ <div class="flex items-center">
189
+ <i data-feather="calendar" class="w-4 h-4 mr-2 text-indigo-600"></i>
190
+ <span class="text-sm">Dec 12, 2023</span>
191
+ </div>
192
+ <button class="view-details-btn px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
193
+ View Details
194
+ </button>
195
+ </div>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ <!-- Event Details Modal -->
202
+ <div id="event-modal" class="modal fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
203
+ <div class="bg-white rounded-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
204
+ <div class="relative">
205
+ <button id="close-modal" class="absolute top-4 right-4 bg-white rounded-full p-2 shadow-lg">
206
+ <i data-feather="x"></i>
207
+ </button>
208
+ <div class="h-64 bg-indigo-100">
209
+ <img id="modal-event-image" src="" alt="Event" class="w-full h-full object-cover">
210
+ </div>
211
+ </div>
212
+ <div class="p-6">
213
+ <div class="flex justify-between items-start mb-4">
214
+ <div>
215
+ <h2 id="modal-event-title" class="text-2xl font-bold"></h2>
216
+ <div class="flex items-center mt-2">
217
+ <i data-feather="map-pin" class="w-4 h-4 mr-2 text-indigo-600"></i>
218
+ <span id="modal-event-location" class="text-gray-600"></span>
219
+ </div>
220
+ </div>
221
+ <span id="modal-event-category" class="bg-indigo-100 text-indigo-800 text-xs px-2 py-1 rounded-full"></span>
222
+ </div>
223
+
224
+ <div class="flex items-center mb-6">
225
+ <div class="mr-8">
226
+ <div class="flex items-center">
227
+ <i data-feather="calendar" class="w-4 h-4 mr-2 text-indigo-600"></i>
228
+ <span id="modal-event-date" class="text-gray-600"></span>
229
+ </div>
230
+ </div>
231
+ <div>
232
+ <div class="flex items-center">
233
+ <i data-feather="clock" class="w-4 h-4 mr-2 text-indigo-600"></i>
234
+ <span id="modal-event-time" class="text-gray-600">7:00 PM - 11:00 PM</span>
235
+ </div>
236
+ </div>
237
+ </div>
238
+
239
+ <div class="mb-6">
240
+ <h3 class="text-lg font-semibold mb-2">About the Event</h3>
241
+ <p id="modal-event-description" class="text-gray-700"></p>
242
+ </div>
243
+
244
+ <div class="mb-6">
245
+ <h3 class="text-lg font-semibold mb-2">Organizer</h3>
246
+ <div class="flex items-center">
247
+ <img id="modal-event-organizer-avatar" src="https://randomuser.me/api/portraits/women/44.jpg" alt="Organizer" class="w-10 h-10 rounded-full mr-3">
248
+ <div>
249
+ <p id="modal-event-organizer-name" class="font-medium">Sarah Johnson</p>
250
+ <p class="text-sm text-gray-500">Event Organizer</p>
251
+ </div>
252
+ </div>
253
+ </div>
254
+
255
+ <div class="flex justify-between items-center">
256
+ <div>
257
+ <p class="text-sm text-gray-500">Price</p>
258
+ <p id="modal-event-price" class="text-xl font-bold">$25.00</p>
259
+ </div>
260
+ <button id="register-btn" class="px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
261
+ Register Now
262
+ </button>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </div>
267
+
268
+ <!-- Registration Form Modal -->
269
+ <div id="registration-modal" class="modal fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
270
+ <div class="bg-white rounded-xl max-w-md w-full p-6">
271
+ <div class="flex justify-between items-center mb-6">
272
+ <h2 class="text-xl font-bold">Register for <span id="register-event-title"></span></h2>
273
+ <button id="close-registration-modal" class="text-gray-500 hover:text-gray-700">
274
+ <i data-feather="x"></i>
275
+ </button>
276
+ </div>
277
+
278
+ <form id="registration-form" class="space-y-4">
279
+ <div>
280
+ <label for="name" class="block text-sm font-medium text-gray-700 mb-1">Full Name</label>
281
+ <input type="text" id="name" name="name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
282
+ </div>
283
+
284
+ <div>
285
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
286
+ <input type="email" id="email" name="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
287
+ </div>
288
+
289
+ <div>
290
+ <label for="phone" class="block text-sm font-medium text-gray-700 mb-1">Phone Number</label>
291
+ <input type="tel" id="phone" name="phone" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
292
+ </div>
293
+
294
+ <div>
295
+ <label for="tickets" class="block text-sm font-medium text-gray-700 mb-1">Number of Tickets</label>
296
+ <select id="tickets" name="tickets" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
297
+ <option value="1">1</option>
298
+ <option value="2">2</option>
299
+ <option value="3">3</option>
300
+ <option value="4">4</option>
301
+ <option value="5">5</option>
302
+ </select>
303
+ </div>
304
+
305
+ <div class="pt-2">
306
+ <button type="submit" class="w-full px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
307
+ Complete Registration
308
+ </button>
309
+ </div>
310
+ </form>
311
+ </div>
312
+ </div>
313
+
314
+ <!-- Registration Success Modal -->
315
+ <div id="success-modal" class="modal fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
316
+ <div class="bg-white rounded-xl max-w-md w-full p-8 text-center">
317
+ <div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100 mb-4">
318
+ <i data-feather="check" class="h-6 w-6 text-green-600"></i>
319
+ </div>
320
+ <h2 class="text-xl font-bold mb-2">Registration Successful!</h2>
321
+ <p class="text-gray-600 mb-6">You're all set for <span id="success-event-title" class="font-medium"></span>. We've sent the details to your email.</p>
322
+ <button id="close-success-modal" class="px-6 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
323
+ Back to Events
324
+ </button>
325
+ </div>
326
+ </div>
327
+
328
+ <!-- Footer -->
329
+ <footer class="bg-gray-800 text-white py-12">
330
+ <div class="max-w-6xl mx-auto px-4">
331
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
332
+ <div>
333
+ <h3 class="text-xl font-bold mb-4">SparkMeet</h3>
334
+ <p class="text-gray-400">Connecting people through amazing events and experiences.</p>
335
+ </div>
336
+ <div>
337
+ <h4 class="text-lg font-semibold mb-4">Explore</h4>
338
+ <ul class="space-y-2">
339
+ <li><a href="#" class="text-gray-400 hover:text-white">Events</a></li>
340
+ <li><a href="#" class="text-gray-400 hover:text-white">Categories</a></li>
341
+ <li><a href="#" class="text-gray-400 hover:text-white">Cities</a></li>
342
+ <li><a href="#" class="text-gray-400 hover:text-white">Popular</a></li>
343
+ </ul>
344
+ </div>
345
+ <div>
346
+ <h4 class="text-lg font-semibold mb-4">Company</h4>
347
+ <ul class="space-y-2">
348
+ <li><a href="#" class="text-gray-400 hover:text-white">About Us</a></li>
349
+ <li><a href="#" class="text-gray-400 hover:text-white">Careers</a></li>
350
+ <li><a href="#" class="text-gray-400 hover:text-white">Blog</a></li>
351
+ <li><a href="#" class="text-gray-400 hover:text-white">Contact</a></li>
352
+ </ul>
353
+ </div>
354
+ <div>
355
+ <h4 class="text-lg font-semibold mb-4">Connect</h4>
356
+ <div class="flex space-x-4">
357
+ <a href="#" class="text-gray-400 hover:text-white">
358
+ <i data-feather="facebook"></i>
359
+ </a>
360
+ <a href="#" class="text-gray-400 hover:text-white">
361
+ <i data-feather="twitter"></i>
362
+ </a>
363
+ <a href="#" class="text-gray-400 hover:text-white">
364
+ <i data-feather="instagram"></i>
365
+ </a>
366
+ <a href="#" class="text-gray-400 hover:text-white">
367
+ <i data-feather="linkedin"></i>
368
+ </a>
369
+ </div>
370
+ </div>
371
+ </div>
372
+ <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
373
+ <p>&copy; 2023 SparkMeet. All rights reserved.</p>
374
+ </div>
375
+ </div>
376
+ </footer>
377
+
378
+ <script>
379
+ // Initialize Feather Icons
380
+ feather.replace();
381
+
382
+ // Mobile menu toggle
383
+ const mobileMenuButton = document.getElementById('mobile-menu-button');
384
+ const mobileMenu = document.getElementById('mobile-menu');
385
+
386
+ mobileMenuButton.addEventListener('click', () => {
387
+ mobileMenu.classList.toggle('hidden');
388
+ });
389
+
390
+ // User dropdown menu
391
+ const userMenu = document.getElementById('user-menu');
392
+ const dropdownMenu = document.getElementById('dropdown-menu');
393
+
394
+ userMenu.addEventListener('click', () => {
395
+ dropdownMenu.classList.toggle('hidden');
396
+ });
397
+
398
+ // Close dropdown when clicking outside
399
+ document.addEventListener('click', (e) => {
400
+ if (!userMenu.contains(e.target) && !dropdownMenu.contains(e.target)) {
401
+ dropdownMenu.classList.add('hidden');
402
+ }
403
+ });
404
+
405
+ // Category filter
406
+ const categoryFilters = document.querySelectorAll('.category-filter');
407
+
408
+ categoryFilters.forEach(filter => {
409
+ filter.addEventListener('click', () => {
410
+ categoryFilters.forEach(f => f.classList.remove('active'));
411
+ filter.classList.add('active');
412
+ });
413
+ });
414
+
415
+ // Event details modal
416
+ const eventModal = document.getElementById('event-modal');
417
+ const closeModal = document.getElementById('close-modal');
418
+ const viewDetailsBtns = document.querySelectorAll('.view-details-btn');
419
+
420
+ viewDetailsBtns.forEach(btn => {
421
+ btn.addEventListener('click', () => {
422
+ const eventCard = btn.closest('.event-card');
423
+ const eventTitle = eventCard.querySelector('h3').textContent;
424
+ const eventCategory = eventCard.querySelector('span').textContent;
425
+ const eventLocation = eventCard.querySelector('.text-sm.font-medium').textContent;
426
+ const eventDate = eventCard.querySelector('.text-sm').textContent;
427
+ const eventDescription = eventCard.querySelector('p').textContent;
428
+ const eventImage = eventCard.querySelector('img').src;
429
+
430
+ document.getElementById('modal-event-title').textContent = eventTitle;
431
+ document.getElementById('modal-event-category').textContent = eventCategory;
432
+ document.getElementById('modal-event-location').textContent = eventLocation;
433
+ document.getElementById('modal-event-date').textContent = eventDate;
434
+ document.getElementById('modal-event-description').textContent = eventDescription;
435
+ document.getElementById('modal-event-image').src = eventImage;
436
+
437
+ eventModal.classList.remove('hidden');
438
+ });
439
+ });
440
+
441
+ closeModal.addEventListener('click', () => {
442
+ eventModal.classList.add('hidden');
443
+ });
444
+
445
+ // Registration modal
446
+ const registrationModal = document.getElementById('registration-modal');
447
+ const closeRegistrationModal = document.getElementById('close-registration-modal');
448
+ const registerBtn = document.getElementById('register-btn');
449
+
450
+ registerBtn.addEventListener('click', () => {
451
+ const eventTitle = document.getElementById('modal-event-title').textContent;
452
+ document.getElementById('register-event-title').textContent = eventTitle;
453
+
454
+ eventModal.classList.add('hidden');
455
+ registrationModal.classList.remove('hidden');
456
+ });
457
+
458
+ closeRegistrationModal.addEventListener('click', () => {
459
+ registrationModal.classList.add('hidden');
460
+ });
461
+
462
+ // Registration form submission
463
+ const registrationForm = document.getElementById('registration-form');
464
+ const successModal = document.getElementById('success-modal');
465
+ const closeSuccessModal = document.getElementById('close-success-modal');
466
+
467
+ registrationForm.addEventListener('submit', (e) => {
468
+ e.preventDefault();
469
+
470
+ const eventTitle = document.getElementById('register-event-title').textContent;
471
+ document.getElementById('success-event-title').textContent = eventTitle;
472
+
473
+ registrationModal.classList.add('hidden');
474
+ successModal.classList.remove('hidden');
475
+ });
476
+
477
+ closeSuccessModal.addEventListener('click', () => {
478
+ successModal.classList.add('hidden');
479
+ });
480
+
481
+ // Close modals when clicking outside
482
+ const modals = document.querySelectorAll('.modal');
483
+
484
+ modals.forEach(modal => {
485
+ modal.addEventListener('click', (e) => {
486
+ if (e.target === modal) {
487
+ modal.classList.add('hidden');
488
+ }
489
+ });
490
+ });
491
+ </script>
492
+ </body>
493
  </html>
login.html ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Log In - SparkConnect</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <style>
10
+ .gradient-bg {
11
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
12
+ }
13
+ .btn-primary {
14
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
15
+ }
16
+ .btn-primary:hover {
17
+ background: linear-gradient(135deg, #f5576c 0%, #f093fb 100%);
18
+ }
19
+ </style>
20
+ </head>
21
+ <body class="bg-gray-50 min-h-screen font-sans">
22
+ <!-- Navigation -->
23
+ <nav class="bg-white shadow-sm">
24
+ <div class="max-w-6xl mx-auto px-4">
25
+ <div class="flex justify-between items-center py-4">
26
+ <a href="index.html" class="flex items-center space-x-2">
27
+ <span class="text-2xl font-bold bg-gradient-to-r from-purple-600 to-pink-500 bg-clip-text text-transparent">SparkConnect</span>
28
+ </a>
29
+ <a href="signup.html" class="text-gray-600 hover:text-purple-600 font-medium">Sign Up</a>
30
+ </div>
31
+ </div>
32
+ </nav>
33
+
34
+ <!-- Login Form -->
35
+ <div class="min-h-screen flex items-center justify-center px-4 py-12">
36
+ <div class="max-w-md w-full space-y-8">
37
+ <div class="text-center">
38
+ <h2 class="text-3xl font-bold text-gray-900 mb-2">Welcome Back! 👋</h2>
39
+ <p class="text-gray-600">Continue your journey to find amazing connections</p>
40
+ </div>
41
+
42
+ <!-- OAuth Buttons -->
43
+ <div class="space-y-4">
44
+ <button class="w-full flex items-center justify-center px-4 py-3 border border-gray-300 rounded-lg shadow-sm bg-white text-gray-700 hover:bg-gray-50 transition-colors">
45
+ <i data-feather="mail" class="w-5 h-5 mr-3"></i>
46
+ Continue with Google
47
+ </button>
48
+ <button class="w-full flex items-center justify-center px-4 py-3 border border-gray-300 rounded-lg shadow-sm bg-white text-gray-700 hover:bg-gray-50 transition-colors">
49
+ <i data-feather="smartphone" class="w-5 h-5 mr-3"></i>
50
+ Continue with Apple
51
+ </button>
52
+ </div>
53
+
54
+ <div class="relative">
55
+ <div class="absolute inset-0 flex items-center">
56
+ <div class="w-full border-t border-gray-300"></div>
57
+ </div>
58
+ <div class="relative flex justify-center text-sm">
59
+ <span class="px-2 bg-gray-50 text-gray-500">Or log in with email</span>
60
+ </div>
61
+ </div>
62
+
63
+ <form class="space-y-6" id="login-form">
64
+ <div>
65
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
66
+ <input type="email" id="email" name="email" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors" placeholder="you@example.com">
67
+ </div>
68
+
69
+ <div>
70
+ <label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
71
+ <input type="password" id="password" name="password" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors" placeholder="Enter your password">
72
+ </div>
73
+
74
+ <div class="flex items-center justify-between">
75
+ <div class="flex items-center">
76
+ <input type="checkbox" id="remember" name="remember" class="w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500">
77
+ <label for="remember" class="ml-2 block text-sm text-gray-700">Remember me</label>
78
+ </div>
79
+ <a href="#" class="text-sm text-purple-600 hover:text-purple-500">Forgot password?</a>
80
+ </div>
81
+
82
+ <button type="submit" class="w-full btn-primary text-white py-3 px-4 rounded-lg font-medium hover:shadow-lg transition-all duration-300">
83
+ Log In
84
+ </button>
85
+ </form>
86
+
87
+ <div class="text-center">
88
+ <p class="text-sm text-gray-600">
89
+ Don't have an account?
90
+ <a href="signup.html" class="font-medium text-purple-600 hover:text-purple-500">Sign up</a>
91
+ </p>
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+ <script>
97
+ feather.replace();
98
+
99
+ const loginForm = document.getElementById('login-form');
100
+
101
+ loginForm.addEventListener('submit', async (e) => {
102
+ e.preventDefault();
103
+
104
+ const email = document.getElementById('email').value;
105
+ const password = document.getElementById('password').value;
106
+
107
+ // Simulate login process
108
+ const submitBtn = loginForm.querySelector('button[type="submit"]');
109
+ const originalText = submitBtn.textContent;
110
+ submitBtn.textContent = 'Logging in...';
111
+ submitBtn.disabled = true;
112
+
113
+ // In a real app, this would be an API call
114
+ setTimeout(() => {
115
+ // Redirect to discovery page
116
+ window.location.href = 'discovery.html';
117
+ }, 2000);
118
+ });
119
+ </script>
120
+ </body>
121
+ </html>
profile-builder.html ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```html
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Build Your Profile - SparkConnect</title>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <style>
11
+ .gradient-bg {
12
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
13
+ }
14
+ .btn-primary {
15
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
16
+ }
17
+ .btn-primary:hover {
18
+ background: linear-gradient(135deg, #f5576c 0%, #f093fb 100%);
19
+ }
20
+ .photo-upload {
21
+ border: 2px dashed #d1d5db;
22
+ transition: all 0.3s ease;
23
+ }
24
+ .photo-upload:hover {
25
+ border-color: #8b5cf6;
26
+ }
27
+ </style>
28
+ </head>
29
+ <body class="bg-gray-50 min-h-screen font-sans">
30
+ <!-- Navigation -->
31
+ <nav class="bg-white shadow-sm">
32
+ <div class="max-w-6xl mx-auto px-4">
33
+ <div class="flex justify-between items-center py-4">
34
+ <a href="index.html" class="flex items-center space-x-2">
35
+ <span class="text-2xl font-bold bg-gradient-to-r from-purple-600 to-pink-500 bg-clip-text text-transparent">SparkConnect</span>
36
+ </a>
37
+ <div class="flex items-center space-x-4">
38
+ <span class="text-sm text-gray-600">Step 2 of 3</span>
39
+ <div class="w-24 bg-gray-200 rounded-full h-2">
40
+ <div class="bg-purple-600 h-2 rounded-full w-2/3"></div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </nav>
46
+
47
+ <!-- Profile Builder -->
48
+ <div class="max-w-2xl mx-auto px-4 py-8">
49
+ <div class="text-center mb-8">
50
+ <h1 class="text-3xl font-bold text-gray-900 mb-2">Build Your Profile ✨</h1>
51
+ <p class="text-gray-600">Show the world who you are and what makes you unique</p>
52
+ </div>
53
+
54
+ <form id="profile-form" class="space-y-8">
55
+ <!-- Photos Section -->
56
+ <div class="bg-white rounded-xl shadow-sm p-6">
57
+ <h2 class="text-xl font-semibold mb-4">Your Photos</h2>
58
+ <p class="text-gray-600 mb-6">Add at least 2 photos to get started. Show your personality!</p>
59
+
60
+ <div class="grid grid-cols-2 md:grid-cols-3 gap-4 mb-6">
61
+ <!-- Photo Slot 1 -->
62
+ <div class="photo-upload aspect-square rounded-lg bg-gray-100 flex items-center justify-center cursor-pointer"
signup.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Sign Up - SparkConnect</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <style>
10
+ .gradient-bg {
11
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
12
+ }
13
+ .btn-primary {
14
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
15
+ }
16
+ .btn-primary:hover {
17
+ background: linear-gradient(135deg, #f5576c 0%, #f093fb 100%);
18
+ }
19
+ </style>
20
+ </head>
21
+ <body class="bg-gray-50 min-h-screen font-sans">
22
+ <!-- Navigation -->
23
+ <nav class="bg-white shadow-sm">
24
+ <div class="max-w-6xl mx-auto px-4">
25
+ <div class="flex justify-between items-center py-4">
26
+ <a href="index.html" class="flex items-center space-x-2">
27
+ <span class="text-2xl font-bold bg-gradient-to-r from-purple-600 to-pink-500 bg-clip-text text-transparent">SparkConnect</span>
28
+ </a>
29
+ <a href="login.html" class="text-gray-600 hover:text-purple-600 font-medium">Log In</a>
30
+ </div>
31
+ </div>
32
+ </nav>
33
+
34
+ <!-- Signup Form -->
35
+ <div class="min-h-screen flex items-center justify-center px-4 py-12">
36
+ <div class="max-w-md w-full space-y-8">
37
+ <div class="text-center">
38
+ <h2 class="text-3xl font-bold text-gray-900 mb-2">Find Your Vibe ✨</h2>
39
+ <p class="text-gray-600">Join thousands of people finding authentic connections</p>
40
+ </div>
41
+
42
+ <!-- OAuth Buttons -->
43
+ <div class="space-y-4">
44
+ <button class="w-full flex items-center justify-center px-4 py-3 border border-gray-300 rounded-lg shadow-sm bg-white text-gray-700 hover:bg-gray-50 transition-colors">
45
+ <i data-feather="mail" class="w-5 h-5 mr-3"></i>
46
+ Continue with Google
47
+ </button>
48
+ <button class="w-full flex items-center justify-center px-4 py-3 border border-gray-300 rounded-lg shadow-sm bg-white text-gray-700 hover:bg-gray-50 transition-colors">
49
+ <i data-feather="smartphone" class="w-5 h-5 mr-3"></i>
50
+ Continue with Apple
51
+ </button>
52
+ </div>
53
+
54
+ <div class="relative">
55
+ <div class="absolute inset-0 flex items-center">
56
+ <div class="w-full border-t border-gray-300"></div>
57
+ </div>
58
+ <div class="relative flex justify-center text-sm">
59
+ <span class="px-2 bg-gray-50 text-gray-500">Or continue with email</span>
60
+ </div>
61
+ </div>
62
+
63
+ <form class="space-y-6" id="signup-form">
64
+ <div>
65
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
66
+ <input type="email" id="email" name="email" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors" placeholder="you@example.com">
67
+ </div>
68
+
69
+ <div>
70
+ <label for="dob" class="block text-sm font-medium text-gray-700 mb-1">Date of Birth</label>
71
+ <input type="date" id="dob" name="dob" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors">
72
+ <p class="text-xs text-gray-500 mt-1">You must be 18 or older to join</p>
73
+ </div>
74
+
75
+ <div>
76
+ <label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
77
+ <input type="password" id="password" name="password" required class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition-colors" placeholder="Create a strong password">
78
+ <div class="mt-2 space-y-1">
79
+ <div class="flex items-center">
80
+ <i data-feather="check" class="w-4 h-4 text-green-500 mr-2"></i>
81
+ <span class="text-xs text-gray-600">At least 8 characters</span>
82
+ </div>
83
+ <div class="flex items-center">
84
+ <i data-feather="check" class="w-4 h-4 text-green-500 mr-2"></i>
85
+ <span class="text-xs text-gray-600">Mix of letters and numbers</span>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <div class="flex items-center">
91
+ <input type="checkbox" id="terms" name="terms" required class="w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500">
92
+ <label for="terms" class="ml-2 block text-sm text-gray-700">
93
+ I agree to the <a href="#" class="text-purple-600 hover:text-purple-500">Terms of Service</a> and <a href="#" class="text-purple-600 hover:text-purple-500">Privacy Policy</a>
94
+ </label>
95
+ </div>
96
+
97
+ <button type="submit" class="w-full btn-primary text-white py-3 px-4 rounded-lg font-medium hover:shadow-lg transition-all duration-300">
98
+ Create Account
99
+ </button>
100
+ </form>
101
+
102
+ <div class="text-center">
103
+ <p class="text-sm text-gray-600">
104
+ Already have an account?
105
+ <a href="login.html" class="font-medium text-purple-600 hover:text-purple-500">Log in</a>
106
+ </p>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <!-- Age Verification Modal -->
112
+ <div id="age-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
113
+ <div class="bg-white rounded-xl max-w-sm w-full p-6 text-center">
114
+ <div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
115
+ <i data-feather="alert-triangle" class="h-6 w-6 text-red-600"></i>
116
+ </div>
117
+ <h2 class="text-xl font-bold mb-2">Age Restriction</h2>
118
+ <p class="text-gray-600 mb-6">You must be 18 or older to use SparkConnect. Please come back when you're older!</p>
119
+ <button onclick="closeAgeModal()" class="px-6 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors">
120
+ Understood
121
+ </button>
122
+ </div>
123
+ </div>
124
+
125
+ <script>
126
+ feather.replace();
127
+
128
+ const signupForm = document.getElementById('signup-form');
129
+ const ageModal = document.getElementById('age-modal');
130
+
131
+ function closeAgeModal() {
132
+ ageModal.classList.add('hidden');
133
+ }
134
+
135
+ signupForm.addEventListener('submit', async (e) => {
136
+ e.preventDefault();
137
+
138
+ const email = document.getElementById('email').value;
139
+ const dob = document.getElementById('dob').value;
140
+ const password = document.getElementById('password').value;
141
+
142
+ // Age verification
143
+ const birthDate = new Date(dob);
144
+ const today = new Date();
145
+ const age = today.getFullYear() - birthDate.getFullYear();
146
+ const monthDiff = today.getMonth() - birthDate.getMonth();
147
+
148
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
149
+ age--;
150
+ }
151
+
152
+ if (age < 18) {
153
+ ageModal.classList.remove('hidden');
154
+ return;
155
+ }
156
+
157
+ // Simulate signup process
158
+ const submitBtn = signupForm.querySelector('button[type="submit"]');
159
+ const originalText = submitBtn.textContent;
160
+ submitBtn.textContent = 'Creating account...';
161
+ submitBtn.disabled = true;
162
+
163
+ // In a real app, this would be an API call
164
+ setTimeout(() => {
165
+ // Redirect to profile builder
166
+ window.location.href = 'profile-builder.html';
167
+ }, 2000);
168
+ });
169
+ </script>
170
+ </body>
171
+ </html>