kdb7r commited on
Commit
07b2773
·
verified ·
1 Parent(s): 1a2939d

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +363 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Nyc Event Scout
3
- emoji: 👀
4
- colorFrom: gray
5
- colorTo: purple
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: nyc-event-scout
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,363 @@
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>NYC Event Scout</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .event-card {
11
+ transition: all 0.3s ease;
12
+ }
13
+ .event-card:hover {
14
+ transform: translateY(-5px);
15
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
16
+ }
17
+ .loading-spinner {
18
+ animation: spin 1s linear infinite;
19
+ }
20
+ @keyframes spin {
21
+ 0% { transform: rotate(0deg); }
22
+ 100% { transform: rotate(360deg); }
23
+ }
24
+ .category-chip {
25
+ transition: all 0.2s ease;
26
+ }
27
+ .category-chip:hover {
28
+ transform: scale(1.05);
29
+ }
30
+ .category-chip.active {
31
+ background-color: #3b82f6;
32
+ color: white;
33
+ }
34
+ </style>
35
+ </head>
36
+ <body class="bg-gray-50 min-h-screen">
37
+ <div class="container mx-auto px-4 py-8">
38
+ <!-- Header -->
39
+ <header class="mb-12 text-center">
40
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">NYC Event Scout</h1>
41
+ <p class="text-gray-600 max-w-2xl mx-auto">Discover the best events happening in New York City, curated just for you.</p>
42
+ </header>
43
+
44
+ <!-- Controls -->
45
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
46
+ <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
47
+ <div class="flex-1">
48
+ <label for="search" class="block text-sm font-medium text-gray-700 mb-1">Search Events</label>
49
+ <div class="relative">
50
+ <input type="text" id="search" placeholder="Music, Art, Tech..."
51
+ class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
52
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
53
+ </div>
54
+ </div>
55
+ <div>
56
+ <label for="sort" class="block text-sm font-medium text-gray-700 mb-1">Sort By</label>
57
+ <select id="sort" class="w-full md:w-auto px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
58
+ <option value="date">Date (Soonest)</option>
59
+ <option value="popular">Most Popular</option>
60
+ <option value="price">Price (Low to High)</option>
61
+ </select>
62
+ </div>
63
+ <button id="scrape-btn" class="mt-6 md:mt-0 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-6 rounded-lg transition duration-200 flex items-center justify-center gap-2">
64
+ <i class="fas fa-sync-alt"></i> Refresh Events
65
+ </button>
66
+ </div>
67
+
68
+ <!-- Categories -->
69
+ <div class="mt-6">
70
+ <p class="text-sm font-medium text-gray-700 mb-2">Filter by Category</p>
71
+ <div class="flex flex-wrap gap-2" id="categories">
72
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">All</button>
73
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Music</button>
74
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Art</button>
75
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Tech</button>
76
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Food</button>
77
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Networking</button>
78
+ <button class="category-chip px-4 py-1 rounded-full bg-gray-100 text-gray-800 text-sm">Workshop</button>
79
+ </div>
80
+ </div>
81
+ </div>
82
+
83
+ <!-- Loading State -->
84
+ <div id="loading" class="hidden flex-col items-center justify-center py-12">
85
+ <div class="loading-spinner w-12 h-12 border-4 border-blue-500 border-t-transparent rounded-full mb-4"></div>
86
+ <p class="text-gray-600">Scraping the best NYC events for you...</p>
87
+ </div>
88
+
89
+ <!-- Results -->
90
+ <div id="results">
91
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="events-container">
92
+ <!-- Events will be injected here -->
93
+ </div>
94
+ </div>
95
+
96
+ <!-- Empty State -->
97
+ <div id="empty-state" class="hidden text-center py-12">
98
+ <i class="fas fa-calendar-times text-5xl text-gray-300 mb-4"></i>
99
+ <h3 class="text-xl font-medium text-gray-700 mb-2">No Events Found</h3>
100
+ <p class="text-gray-500 max-w-md mx-auto">Try adjusting your search or filters to find more events.</p>
101
+ </div>
102
+ </div>
103
+
104
+ <script>
105
+ document.addEventListener('DOMContentLoaded', function() {
106
+ // DOM Elements
107
+ const scrapeBtn = document.getElementById('scrape-btn');
108
+ const eventsContainer = document.getElementById('events-container');
109
+ const loadingElement = document.getElementById('loading');
110
+ const emptyStateElement = document.getElementById('empty-state');
111
+ const searchInput = document.getElementById('search');
112
+ const sortSelect = document.getElementById('sort');
113
+ const categoryChips = document.querySelectorAll('.category-chip');
114
+
115
+ // Mock data - in a real app, this would come from scraping lu.ma/nyc
116
+ // Note: Actual scraping would require a backend due to CORS restrictions
117
+ const mockEvents = [
118
+ {
119
+ id: 1,
120
+ title: "Jazz Night in Brooklyn",
121
+ date: "2023-06-15T19:00:00",
122
+ location: "Blue Note, Brooklyn",
123
+ price: 25,
124
+ image: "https://images.unsplash.com/photo-1511671782779-c97d3d27a1d4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
125
+ category: "Music",
126
+ description: "An evening of smooth jazz with local artists and special guests.",
127
+ attendees: 120,
128
+ organizer: "NYC Jazz Collective"
129
+ },
130
+ {
131
+ id: 2,
132
+ title: "Tech Startup Mixer",
133
+ date: "2023-06-18T18:30:00",
134
+ location: "WeWork, Manhattan",
135
+ price: 10,
136
+ image: "https://images.unsplash.com/photo-1497366811353-6870744d04b2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1469&q=80",
137
+ category: "Tech",
138
+ description: "Network with fellow entrepreneurs and tech enthusiasts.",
139
+ attendees: 85,
140
+ organizer: "NY Tech Meetup"
141
+ },
142
+ {
143
+ id: 3,
144
+ title: "Street Art Walking Tour",
145
+ date: "2023-06-20T14:00:00",
146
+ location: "Bushwick Collective, Brooklyn",
147
+ price: 15,
148
+ image: "https://images.unsplash.com/photo-1518693800322-4eb2c6b12c9e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
149
+ category: "Art",
150
+ description: "Explore NYC's vibrant street art scene with local artists.",
151
+ attendees: 45,
152
+ organizer: "Urban Art NYC"
153
+ },
154
+ {
155
+ id: 4,
156
+ title: "Food Truck Festival",
157
+ date: "2023-06-22T12:00:00",
158
+ location: "Queens Night Market",
159
+ price: 0,
160
+ image: "https://images.unsplash.com/photo-1504674900247-0877df9cc836?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
161
+ category: "Food",
162
+ description: "Sample cuisine from NYC's best food trucks all in one place.",
163
+ attendees: 320,
164
+ organizer: "NYC Foodie Collective"
165
+ },
166
+ {
167
+ id: 5,
168
+ title: "AI & Machine Learning Workshop",
169
+ date: "2023-06-25T10:00:00",
170
+ location: "NYU Tandon School of Engineering",
171
+ price: 50,
172
+ image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
173
+ category: "Tech",
174
+ description: "Hands-on workshop covering the latest in AI and ML technologies.",
175
+ attendees: 60,
176
+ organizer: "Future Tech NYC"
177
+ },
178
+ {
179
+ id: 6,
180
+ title: "Indie Film Screening",
181
+ date: "2023-06-28T19:30:00",
182
+ location: "Nitehawk Cinema, Williamsburg",
183
+ price: 18,
184
+ image: "https://images.unsplash.com/photo-1489599849927-2ee91cede3ba?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
185
+ category: "Art",
186
+ description: "Premiere of new independent films with Q&A from directors.",
187
+ attendees: 90,
188
+ organizer: "NYC Indie Film Club"
189
+ }
190
+ ];
191
+
192
+ // Current filter state
193
+ let currentFilter = {
194
+ search: '',
195
+ category: 'All',
196
+ sort: 'date'
197
+ };
198
+
199
+ // Initialize the app
200
+ function init() {
201
+ renderEvents(mockEvents);
202
+ setupEventListeners();
203
+ }
204
+
205
+ // Set up event listeners
206
+ function setupEventListeners() {
207
+ scrapeBtn.addEventListener('click', handleScrapeClick);
208
+ searchInput.addEventListener('input', handleSearchInput);
209
+ sortSelect.addEventListener('change', handleSortChange);
210
+
211
+ categoryChips.forEach(chip => {
212
+ chip.addEventListener('click', () => handleCategoryClick(chip));
213
+ });
214
+ }
215
+
216
+ // Handle scrape button click
217
+ function handleScrapeClick() {
218
+ showLoading();
219
+
220
+ // Simulate scraping delay
221
+ setTimeout(() => {
222
+ hideLoading();
223
+ renderEvents(mockEvents);
224
+ }, 1500);
225
+ }
226
+
227
+ // Handle search input
228
+ function handleSearchInput(e) {
229
+ currentFilter.search = e.target.value.toLowerCase();
230
+ filterAndRenderEvents();
231
+ }
232
+
233
+ // Handle sort change
234
+ function handleSortChange(e) {
235
+ currentFilter.sort = e.target.value;
236
+ filterAndRenderEvents();
237
+ }
238
+
239
+ // Handle category click
240
+ function handleCategoryClick(chip) {
241
+ // Update active state
242
+ categoryChips.forEach(c => c.classList.remove('active'));
243
+ chip.classList.add('active');
244
+
245
+ // Update filter
246
+ currentFilter.category = chip.textContent;
247
+ filterAndRenderEvents();
248
+ }
249
+
250
+ // Filter and render events based on current filters
251
+ function filterAndRenderEvents() {
252
+ let filteredEvents = [...mockEvents];
253
+
254
+ // Apply search filter
255
+ if (currentFilter.search) {
256
+ filteredEvents = filteredEvents.filter(event =>
257
+ event.title.toLowerCase().includes(currentFilter.search) ||
258
+ event.description.toLowerCase().includes(currentFilter.search) ||
259
+ event.organizer.toLowerCase().includes(currentFilter.search)
260
+ );
261
+ }
262
+
263
+ // Apply category filter
264
+ if (currentFilter.category !== 'All') {
265
+ filteredEvents = filteredEvents.filter(event =>
266
+ event.category === currentFilter.category
267
+ );
268
+ }
269
+
270
+ // Apply sort
271
+ switch(currentFilter.sort) {
272
+ case 'date':
273
+ filteredEvents.sort((a, b) => new Date(a.date) - new Date(b.date));
274
+ break;
275
+ case 'popular':
276
+ filteredEvents.sort((a, b) => b.attendees - a.attendees);
277
+ break;
278
+ case 'price':
279
+ filteredEvents.sort((a, b) => a.price - b.price);
280
+ break;
281
+ }
282
+
283
+ renderEvents(filteredEvents);
284
+ }
285
+
286
+ // Show loading state
287
+ function showLoading() {
288
+ loadingElement.classList.remove('hidden');
289
+ results.classList.add('hidden');
290
+ emptyStateElement.classList.add('hidden');
291
+ }
292
+
293
+ // Hide loading state
294
+ function hideLoading() {
295
+ loadingElement.classList.add('hidden');
296
+ results.classList.remove('hidden');
297
+ }
298
+
299
+ // Render events to the DOM
300
+ function renderEvents(events) {
301
+ if (events.length === 0) {
302
+ emptyStateElement.classList.remove('hidden');
303
+ eventsContainer.innerHTML = '';
304
+ return;
305
+ }
306
+
307
+ emptyStateElement.classList.add('hidden');
308
+
309
+ eventsContainer.innerHTML = events.map(event => `
310
+ <div class="event-card bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg">
311
+ <div class="relative h-48 overflow-hidden">
312
+ <img src="${event.image}" alt="${event.title}" class="w-full h-full object-cover">
313
+ <div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-4">
314
+ <span class="inline-block px-3 py-1 bg-white text-sm font-medium rounded-full">${event.category}</span>
315
+ </div>
316
+ </div>
317
+ <div class="p-6">
318
+ <div class="flex justify-between items-start mb-2">
319
+ <h3 class="text-xl font-bold text-gray-800">${event.title}</h3>
320
+ <span class="text-lg font-semibold text-blue-600">${event.price === 0 ? 'FREE' : '$' + event.price}</span>
321
+ </div>
322
+ <p class="text-gray-600 mb-4 line-clamp-2">${event.description}</p>
323
+
324
+ <div class="flex items-center text-gray-500 text-sm mb-4">
325
+ <i class="fas fa-map-marker-alt mr-2"></i>
326
+ <span>${event.location}</span>
327
+ </div>
328
+
329
+ <div class="flex items-center justify-between text-sm text-gray-500">
330
+ <div>
331
+ <i class="far fa-calendar-alt mr-2"></i>
332
+ <span>${formatDate(event.date)}</span>
333
+ </div>
334
+ <div>
335
+ <i class="fas fa-users mr-2"></i>
336
+ <span>${event.attendees} attending</span>
337
+ </div>
338
+ </div>
339
+
340
+ <div class="mt-4 pt-4 border-t border-gray-100">
341
+ <p class="text-sm text-gray-500"><i class="far fa-user mr-2"></i>Hosted by ${event.organizer}</p>
342
+ </div>
343
+
344
+ <button class="mt-4 w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition duration-200">
345
+ Get Tickets
346
+ </button>
347
+ </div>
348
+ </div>
349
+ `).join('');
350
+ }
351
+
352
+ // Format date for display
353
+ function formatDate(dateString) {
354
+ const options = { weekday: 'short', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' };
355
+ return new Date(dateString).toLocaleDateString('en-US', options);
356
+ }
357
+
358
+ // Initialize the app
359
+ init();
360
+ });
361
+ </script>
362
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
363
+ </html>