Prochu commited on
Commit
ad48355
·
verified ·
1 Parent(s): 6cb85a0

Zbyduj stronę w typescript i react, dodaj backend - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +828 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Trainflow
3
- emoji: 📚
4
- colorFrom: red
5
- colorTo: pink
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: trainflow
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
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,828 @@
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
+
2
+ // src/types/index.ts
3
+ export interface Exercise {
4
+ name: string;
5
+ sets: number;
6
+ reps: string;
7
+ type: string;
8
+ }
9
+
10
+ export interface WorkoutPlan {
11
+ duration: string;
12
+ daysPerWeek: number;
13
+ goal: string;
14
+ exercises: Exercise[];
15
+ }
16
+
17
+ export interface Question {
18
+ id: string;
19
+ question: string;
20
+ options: {
21
+ text: string;
22
+ value: string;
23
+ icon: string;
24
+ }[];
25
+ }
26
+
27
+
28
+ // src/services/workoutService.ts
29
+ import { WorkoutPlan } from '../types';
30
+
31
+ export const generateWorkoutPlan = async (answers: any): Promise<WorkoutPlan> => {
32
+ const response = await fetch('/api/workout-plan', {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/json',
36
+ },
37
+ body: JSON.stringify({ answers }),
38
+ });
39
+
40
+ if (!response.ok) {
41
+ throw new Error('Failed to generate workout plan');
42
+ }
43
+
44
+ return response.json();
45
+ };
46
+
47
+
48
+ // server/index.ts
49
+ import express from 'express';
50
+ import cors from 'cors';
51
+ import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node';
52
+
53
+ const app = express();
54
+ app.use(cors());
55
+ app.use(express.json());
56
+
57
+ // API routes
58
+ app.get('/api/workout-plan', ClerkExpressRequireAuth(), async (req, res) => {
59
+ // Generate workout plan logic here
60
+ res.json({
61
+ plan: {
62
+ duration: '4 weeks',
63
+ daysPerWeek: 4,
64
+ goal: 'Muscle Building',
65
+ exercises: [
66
+ // Exercise data
67
+ ]
68
+ }
69
+ });
70
+ });
71
+
72
+ const PORT = process.env.PORT || 5000;
73
+ app.listen(PORT, () => {
74
+ console.log(`Server running on port ${PORT}`);
75
+ });
76
+
77
+
78
+ // src/pages/MainApp.tsx
79
+ import React from 'react';
80
+ import { Outlet } from 'react-router-dom';
81
+ import BottomNav from '../components/BottomNav';
82
+
83
+ const MainApp = () => {
84
+ return (
85
+ <div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800 text-white">
86
+ <div className="pb-20">
87
+ <Outlet />
88
+ </div>
89
+ <BottomNav />
90
+ </div>
91
+ );
92
+ };
93
+
94
+ export default MainApp;
95
+
96
+
97
+ // src/pages/LandingPage.tsx
98
+ import React from 'react';
99
+ import { useClerk } from '@clerk/clerk-react';
100
+ import { Button } from '../components/ui/button';
101
+
102
+ const LandingPage = () => {
103
+ const { openSignIn } = useClerk();
104
+
105
+ return (
106
+ <div className="min-h-screen px-4 py-8 pb-24 bg-gradient-to-br from-gray-900 to-gray-800 text-white">
107
+ <div className="max-w-6xl mx-auto">
108
+ <nav className="flex justify-between items-center py-6">
109
+ <div>
110
+ <h1 className="text-2xl font-bold">Fit<span className="text-indigo-500">AI</span></h1>
111
+ </div>
112
+ <UserButton />
113
+ </nav>
114
+
115
+ <div className="flex flex-col md:flex-row items-center justify-between mt-16">
116
+ {/* Rest of landing page content */}
117
+ <Button onClick={() => openSignIn()}>
118
+ Rozpocznij teraz
119
+ </Button>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ );
124
+ };
125
+
126
+ export default LandingPage;
127
+
128
+
129
+ // src/App.tsx
130
+ import React, { useState } from 'react';
131
+ import { ClerkProvider, SignedIn, SignedOut, UserButton } from '@clerk/clerk-react';
132
+ import LandingPage from './pages/LandingPage';
133
+ import MainApp from './pages/MainApp';
134
+ import './App.css';
135
+
136
+ const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY || '';
137
+
138
+ function App() {
139
+ return (
140
+ <ClerkProvider publishableKey={clerkPubKey}>
141
+ <SignedIn>
142
+ <MainApp />
143
+ </SignedIn>
144
+ <SignedOut>
145
+ <LandingPage />
146
+ </SignedOut>
147
+ </ClerkProvider>
148
+ );
149
+ }
150
+
151
+ export default App;
152
+
153
+ <!DOCTYPE html>
154
+ <html lang="pl">
155
+ <head>
156
+ <meta charset="UTF-8">
157
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
158
+ <title>FitAI - Twój inteligentny plan treningowy</title>
159
+ <script src="https://cdn.tailwindcss.com"></script>
160
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
161
+ <script src="https://cdn.jsdelivr.net/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"></script>
162
+ <script>
163
+ tailwind.config = {
164
+ theme: {
165
+ extend: {
166
+ colors: {
167
+ primary: '#6366f1',
168
+ secondary: '#8b5cf6',
169
+ dark: '#1e293b',
170
+ light: '#f8fafc'
171
+ }
172
+ }
173
+ }
174
+ }
175
+ </script>
176
+ <style>
177
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
178
+
179
+ body {
180
+ font-family: 'Poppins', sans-serif;
181
+ background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
182
+ min-height: 100vh;
183
+ display: flex;
184
+ flex-direction: column;
185
+ align-items: center;
186
+ }
187
+
188
+ .card {
189
+ backdrop-filter: blur(10px);
190
+ background: rgba(255, 255, 255, 0.08);
191
+ border-radius: 20px;
192
+ border: 1px solid rgba(255, 255, 255, 0.1);
193
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
194
+ }
195
+
196
+ .exercise-card {
197
+ transition: all 0.3s ease;
198
+ }
199
+
200
+ .exercise-card:hover {
201
+ transform: translateY(-5px);
202
+ box-shadow: 0 12px 20px rgba(0, 0, 0, 0.2);
203
+ }
204
+
205
+ .progress-bar {
206
+ height: 8px;
207
+ border-radius: 4px;
208
+ overflow: hidden;
209
+ }
210
+
211
+ .progress-fill {
212
+ height: 100%;
213
+ border-radius: 4px;
214
+ transition: width 0.5s ease-in-out;
215
+ }
216
+
217
+ .floating-btn {
218
+ box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
219
+ transition: all 0.3s ease;
220
+ }
221
+
222
+ .floating-btn:hover {
223
+ transform: scale(1.05);
224
+ box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6);
225
+ }
226
+
227
+ .animate-pulse-slow {
228
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
229
+ }
230
+
231
+ @keyframes pulse {
232
+ 0%, 100% { opacity: 1; }
233
+ 50% { opacity: 0.5; }
234
+ }
235
+
236
+ .slide-in {
237
+ animation: slideIn 0.5s ease-out forwards;
238
+ }
239
+
240
+ @keyframes slideIn {
241
+ from {
242
+ opacity: 0;
243
+ transform: translateY(20px);
244
+ }
245
+ to {
246
+ opacity: 1;
247
+ transform: translateY(0);
248
+ }
249
+ }
250
+
251
+ .sticky-nav {
252
+ position: fixed;
253
+ bottom: 0;
254
+ left: 0;
255
+ right: 0;
256
+ background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
257
+ padding: 12px 0;
258
+ z-index: 100;
259
+ display: flex;
260
+ justify-content: center;
261
+ height: 60px; /* Stała wysokość nawigacji */
262
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3); /* Delikatny cień dla lepszego oddzielenia */
263
+ }
264
+
265
+ .clerk-user-button {
266
+ display: flex;
267
+ flex-direction: column;
268
+ align-items: center;
269
+ justify-content: center;
270
+ }
271
+
272
+ .clerk-user-button-trigger {
273
+ width: 24px;
274
+ height: 24px;
275
+ display: flex;
276
+ align-items: center;
277
+ justify-content: center;
278
+ }
279
+
280
+ .nav-content {
281
+ width: 100%;
282
+ max-width: 1024px;
283
+ display: flex;
284
+ justify-content: space-around;
285
+ }
286
+
287
+ .main-container {
288
+ padding-bottom: 120px; /* Zwiększamy padding aby uwzględnić nawigację */
289
+ width: 100%;
290
+ max-width: 1024px;
291
+ margin-bottom: 60px; /* Dodajemy margines na dole */
292
+ }
293
+
294
+ @media (min-width: 768px) {
295
+ .main-container {
296
+ padding: 2rem;
297
+ margin-top: 2rem;
298
+ border-radius: 20px;
299
+ background: rgba(30, 41, 59, 0.7);
300
+ backdrop-filter: blur(10px);
301
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
302
+ border: 1px solid rgba(255, 255, 255, 0.1);
303
+ }
304
+
305
+ .exercise-card {
306
+ max-width: 600px;
307
+ margin-left: auto;
308
+ margin-right: auto;
309
+ }
310
+
311
+ .card {
312
+ max-width: 600px;
313
+ margin-left: auto;
314
+ margin-right: auto;
315
+ }
316
+ }
317
+ </style>
318
+ </head>
319
+ <body class="text-light">
320
+ <!-- Landing Page -->
321
+ <section id="landing" class="min-h-screen px-4 py-8 pb-24"> <!-- Dodajemy pb-24 dla paddingu na dole -->
322
+ <div class="max-w-6xl mx-auto">
323
+ <nav class="flex justify-between items-center py-6">
324
+ <div>
325
+ <h1 class="text-2xl font-bold">Fit<span class="text-primary">AI</span></h1>
326
+ </div>
327
+ <div id="user-button"></div>
328
+ </nav>
329
+
330
+ <div class="flex flex-col md:flex-row items-center justify-between mt-16">
331
+ <div class="md:w-1/2 mb-12 md:mb-0">
332
+ <h2 class="text-4xl md:text-5xl font-bold mb-6">Twój inteligentny <span class="text-primary">plan treningowy</span></h2>
333
+ <p class="text-lg opacity-80 mb-8">Odpowiedz na kilka pytań, a nasze AI stworzy dla Ciebie spersonalizowany plan treningowy dostosowany do Twoich celów i możliwości.</p>
334
+ <button id="getStartedBtn" class="px-8 py-3 bg-primary rounded-xl font-medium flex items-center space-x-2 floating-btn">
335
+ <span>Rozpocznij teraz</span>
336
+ <i class="fas fa-arrow-right"></i>
337
+ </button>
338
+ </div>
339
+ <div class="md:w-1/2">
340
+ <div class="card p-8 relative overflow-hidden">
341
+ <div class="absolute -top-10 -right-10 w-32 h-32 rounded-full bg-primary/20"></div>
342
+ <div class="absolute -bottom-8 -left-8 w-24 h-24 rounded-full bg-secondary/20"></div>
343
+ <img src="https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
344
+ alt="Fitness" class="w-full h-auto rounded-lg">
345
+ </div>
346
+ </div>
347
+ </div>
348
+
349
+ <div class="mt-24">
350
+ <h3 class="text-2xl font-bold mb-8 text-center">Dlaczego FitAI?</h3>
351
+ <div class="grid md:grid-cols-3 gap-8">
352
+ <div class="card p-6">
353
+ <div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center mb-4">
354
+ <i class="fas fa-brain text-primary"></i>
355
+ </div>
356
+ <h4 class="font-bold mb-2">AI-Powered</h4>
357
+ <p class="opacity-80">Nasze algorytmy AI tworzą idealny plan treningowy dostosowany do Ciebie.</p>
358
+ </div>
359
+ <div class="card p-6">
360
+ <div class="w-12 h-12 rounded-full bg-secondary/20 flex items-center justify-center mb-4">
361
+ <i class="fas fa-bolt text-secondary"></i>
362
+ </div>
363
+ <h4 class="font-bold mb-2">Szybkie efekty</h4>
364
+ <p class="opacity-80">Optymalizowane plany treningowe dla maksymalnych rezultatów.</p>
365
+ </div>
366
+ <div class="card p-6">
367
+ <div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center mb-4">
368
+ <i class="fas fa-chart-line text-primary"></i>
369
+ </div>
370
+ <h4 class="font-bold mb-2">Śledź postępy</h4>
371
+ <p class="opacity-80">Monitoruj swoje osiągnięcia i dostosowuj plan do swoich potrzeb.</p>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ </div>
376
+ </section>
377
+
378
+ <!-- Main Container -->
379
+ <div id="app" class="min-h-screen px-4 py-8 main-container hidden">
380
+ <!-- Header -->
381
+ <header class="flex justify-between items-center mb-8">
382
+ <div>
383
+ <h1 class="text-2xl font-bold">Fit<span class="text-primary">AI</span></h1>
384
+ <p class="text-sm opacity-75">Inteligentny plan treningowy</p>
385
+ </div>
386
+ <div class="flex space-x-3">
387
+ <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center">
388
+ <i class="fas fa-user text-primary"></i>
389
+ </button>
390
+ <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center">
391
+ <i class="fas fa-cog text-primary"></i>
392
+ </button>
393
+ </div>
394
+ </header>
395
+
396
+ <!-- Main Content -->
397
+ <main>
398
+ <!-- Hero Section -->
399
+ <section class="card p-6 mb-8 relative overflow-hidden">
400
+ <div class="absolute -top-10 -right-10 w-32 h-32 rounded-full bg-primary/20"></div>
401
+ <div class="absolute -bottom-8 -left-8 w-24 h-24 rounded-full bg-secondary/20"></div>
402
+
403
+ <div class="relative z-10">
404
+ <h2 class="text-xl font-bold mb-2">Stwórz swój idealny plan treningowy</h2>
405
+ <p class="text-sm opacity-80 mb-4">Odpowiedz na kilka pytań, a nasze AI stworzy dla Ciebie spersonalizowany plan treningowy</p>
406
+ <button id="startBtn" class="w-full py-3 bg-primary rounded-xl font-medium flex items-center justify-center space-x-2 floating-btn">
407
+ <span>Rozpocznij teraz</span>
408
+ <i class="fas fa-arrow-right"></i>
409
+ </button>
410
+ </div>
411
+ </section>
412
+
413
+ <!-- Questionnaire Section -->
414
+ <section id="questionnaire" class="hidden">
415
+ <div class="card p-6 mb-6">
416
+ <div class="flex justify-between items-center mb-4">
417
+ <h3 class="font-medium">Twój plan treningowy</h3>
418
+ <span class="text-sm bg-primary/20 px-2 py-1 rounded">Krok <span id="currentStep">1</span>/5</span>
419
+ </div>
420
+
421
+ <div class="progress-bar bg-gray-700 mb-6">
422
+ <div id="progressFill" class="progress-fill bg-primary w-1/5"></div>
423
+ </div>
424
+
425
+ <div id="questionContainer">
426
+ <!-- Questions will be injected here -->
427
+ </div>
428
+
429
+ <div class="flex justify-between mt-6">
430
+ <button id="prevBtn" class="py-2 px-4 rounded-lg bg-gray-700 opacity-0 invisible">
431
+ <i class="fas fa-arrow-left mr-2"></i>Wstecz
432
+ </button>
433
+ <button id="nextBtn" class="py-2 px-4 bg-primary rounded-lg flex items-center">
434
+ <span>Dalej</span>
435
+ <i class="fas fa-arrow-right ml-2"></i>
436
+ </button>
437
+ </div>
438
+ </div>
439
+ </section>
440
+
441
+ <!-- Generating Section -->
442
+ <section id="generating" class="hidden">
443
+ <div class="card p-8 text-center">
444
+ <div class="flex justify-center mb-6">
445
+ <div class="w-16 h-16 rounded-full bg-primary/20 flex items-center justify-center animate-pulse-slow">
446
+ <i class="fas fa-brain text-2xl text-primary"></i>
447
+ </div>
448
+ </div>
449
+ <h3 class="text-xl font-bold mb-2">Tworzę Twój plan...</h3>
450
+ <p class="opacity-80 mb-6">Nasze AI analizuje Twoje odpowiedzi i tworzy idealny plan treningowy</p>
451
+ <div class="flex space-x-2 justify-center">
452
+ <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow"></div>
453
+ <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow delay-150"></div>
454
+ <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow delay-300"></div>
455
+ </div>
456
+ </div>
457
+ </section>
458
+
459
+ <!-- Results Section -->
460
+ <section id="results" class="hidden">
461
+ <div class="flex justify-between items-center mb-6">
462
+ <h2 class="text-xl font-bold">Twój plan treningowy</h2>
463
+ <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center">
464
+ <i class="fas fa-download text-primary"></i>
465
+ </button>
466
+ </div>
467
+
468
+ <div class="card p-5 mb-6">
469
+ <div class="flex justify-between mb-4">
470
+ <div>
471
+ <h3 class="font-bold">Plan na 4 tygodnie</h3>
472
+ <p class="text-sm opacity-80">Dla średniozaawansowanych</p>
473
+ </div>
474
+ <div class="bg-secondary/20 text-secondary px-3 py-1 rounded-lg text-sm font-medium">
475
+ 4 dni/tydzień
476
+ </div>
477
+ </div>
478
+
479
+ <div class="grid grid-cols-2 gap-2 mb-4">
480
+ <div class="bg-gray-800/50 rounded-lg p-3 text-center">
481
+ <p class="text-sm opacity-80">Cel</p>
482
+ <p class="font-medium">Budowa mięśni</p>
483
+ </div>
484
+ <div class="bg-gray-800/50 rounded-lg p-3 text-center">
485
+ <p class="text-sm opacity-80">Czas</p>
486
+ <p class="font-medium">45-60 min</p>
487
+ </div>
488
+ </div>
489
+
490
+ <button class="w-full py-2 bg-primary/20 text-primary rounded-lg font-medium">
491
+ <i class="fas fa-sync-alt mr-2"></i>Wygeneruj ponownie
492
+ </button>
493
+ </div>
494
+
495
+ <h3 class="font-bold mb-4">Dzisiejszy trening: Górna część ciała</h3>
496
+
497
+ <div class="space-y-4">
498
+ <!-- Exercise Cards -->
499
+ <div class="exercise-card card p-4 slide-in">
500
+ <div class="flex items-start">
501
+ <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3">
502
+ <i class="fas fa-dumbbell text-primary"></i>
503
+ </div>
504
+ <div class="flex-1">
505
+ <h4 class="font-bold">Wyciskanie sztangi leżąc</h4>
506
+ <div class="flex text-sm mt-1">
507
+ <span class="bg-gray-700 px-2 py-1 rounded mr-2">4 serie</span>
508
+ <span class="bg-gray-700 px-2 py-1 rounded">8-12 powtórzeń</span>
509
+ </div>
510
+ </div>
511
+ </div>
512
+ </div>
513
+
514
+ <div class="exercise-card card p-4 slide-in">
515
+ <div class="flex items-start">
516
+ <div class="bg-secondary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3">
517
+ <i class="fas fa-dumbbell text-secondary"></i>
518
+ </div>
519
+ <div class="flex-1">
520
+ <h4 class="font-bold">Wyciskanie hantli na skosie</h4>
521
+ <div class="flex text-sm mt-1">
522
+ <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span>
523
+ <span class="bg-gray-700 px-2 py-1 rounded">10-15 powtórzeń</span>
524
+ </div>
525
+ </div>
526
+ </div>
527
+ </div>
528
+
529
+ <div class="exercise-card card p-4 slide-in">
530
+ <div class="flex items-start">
531
+ <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3">
532
+ <i class="fas fa-dumbbell text-primary"></i>
533
+ </div>
534
+ <div class="flex-1">
535
+ <h4 class="font-bold">Podciąganie na drążku</h4>
536
+ <div class="flex text-sm mt-1">
537
+ <span class="bg-gray-700 px-2 py-1 rounded mr-2">4 serie</span>
538
+ <span class="bg-gray-700 px-2 py-1 rounded">6-10 powtórzeń</span>
539
+ </div>
540
+ </div>
541
+ </div>
542
+ </div>
543
+
544
+ <div class="exercise-card card p-4 slide-in">
545
+ <div class="flex items-start">
546
+ <div class="bg-secondary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3">
547
+ <i class="fas fa-dumbbell text-secondary"></i>
548
+ </div>
549
+ <div class="flex-1">
550
+ <h4 class="font-bold">Uginanie ramion ze sztangą</h4>
551
+ <div class="flex text-sm mt-1">
552
+ <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span>
553
+ <span class="bg-gray-700 px-2 py-1 rounded">10-12 powtórzeń</span>
554
+ </div>
555
+ </div>
556
+ </div>
557
+ </div>
558
+
559
+ <div class="exercise-card card p-4 slide-in">
560
+ <div class="flex items-start">
561
+ <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3">
562
+ <i class="fas fa-dumbbell text-primary"></i>
563
+ </div>
564
+ <div class="flex-1">
565
+ <h4 class="font-bold">Wyciskanie francuskie</h4>
566
+ <div class="flex text-sm mt-1">
567
+ <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span>
568
+ <span class="bg-gray-700 px-2 py-1 rounded">12-15 powtórzeń</span>
569
+ </div>
570
+ </div>
571
+ </div>
572
+ </div>
573
+ </div>
574
+
575
+ <div class="mt-8 flex space-x-3">
576
+ <button class="flex-1 py-3 bg-primary rounded-xl font-medium">
577
+ <i class="fas fa-play-circle mr-2"></i>Rozpocznij trening
578
+ </button>
579
+ <button class="w-12 h-12 rounded-xl bg-gray-700 flex items-center justify-center">
580
+ <i class="fas fa-calendar"></i>
581
+ </button>
582
+ </div>
583
+ </section>
584
+ </main>
585
+
586
+ </div>
587
+
588
+ <!-- Navigation -->
589
+ <nav class="sticky-nav border-t border-gray-700" id="app-nav">
590
+ <div class="nav-content px-4">
591
+ <button class="flex flex-col items-center text-primary">
592
+ <i class="fas fa-home text-lg"></i>
593
+ <span class="text-xs mt-1">Strona główna</span>
594
+ </button>
595
+ <button class="flex flex-col items-center opacity-60">
596
+ <i class="fas fa-calendar text-lg"></i>
597
+ <span class="text-xs mt-1">Kalendarz</span>
598
+ </button>
599
+ <button class="flex flex-col items-center opacity-60">
600
+ <i class="fas fa-chart-line text-lg"></i>
601
+ <span class="text-xs mt-1">Statystyki</span>
602
+ </button>
603
+ <div id="nav-user-button" class="flex flex-col items-center">
604
+ <div class="w-6 h-6 flex items-center justify-center">
605
+ <i class="fas fa-user text-lg"></i>
606
+ </div>
607
+ <span class="text-xs mt-1">Profil</span>
608
+ </div>
609
+ </nav>
610
+
611
+ <script>
612
+ // App state
613
+ const state = {
614
+ currentStep: 0,
615
+ answers: {},
616
+ questions: [
617
+ {
618
+ question: "Jaki jest Twój główny cel treningowy?",
619
+ options: [
620
+ {text: "Budowa mięśni", icon: "fas fa-dumbbell"},
621
+ {text: "Redukcja tkanki tłuszczowej", icon: "fas fa-weight-scale"},
622
+ {text: "Poprawa wytrzymałości", icon: "fas fa-heart-pulse"},
623
+ {text: "Ogólna sprawność", icon: "fas fa-person-running"}
624
+ ]
625
+ },
626
+ {
627
+ question: "Jaki jest Twój poziom zaawansowania?",
628
+ options: [
629
+ {text: "Początkujący", icon: "fas fa-seedling"},
630
+ {text: "Średniozaawansowany", icon: "fas fa-chart-line"},
631
+ {text: "Zaawansowany", icon: "fas fa-fire"}
632
+ ]
633
+ },
634
+ {
635
+ question: "Ile dni w tygodniu chcesz trenować?",
636
+ options: [
637
+ {text: "2 dni", icon: "fas fa-calendar"},
638
+ {text: "3 dni", icon: "fas fa-calendar"},
639
+ {text: "4 dni", icon: "fas fa-calendar"},
640
+ {text: "5+ dni", icon: "fas fa-calendar"}
641
+ ]
642
+ },
643
+ {
644
+ question: "Jakie masz dostępne wyposażenie?",
645
+ options: [
646
+ {text: "Brak sprzętu", icon: "fas fa-person"},
647
+ {text: "Hantle", icon: "fas fa-dumbbell"},
648
+ {text: "Sztanga", icon: "fas fa-weight-hanging"},
649
+ {text: "Pełny zestaw siłowni", icon: "fas fa-building"}
650
+ ]
651
+ },
652
+ {
653
+ question: "Ile czasu możesz poświęcić na trening?",
654
+ options: [
655
+ {text: "30 minut", icon: "fas fa-clock"},
656
+ {text: "45 minut", icon: "fas fa-clock"},
657
+ {text: "60 minut", icon: "fas fa-clock"},
658
+ {text: "90+ minut", icon: "fas fa-clock"}
659
+ ]
660
+ }
661
+ ]
662
+ };
663
+
664
+ // DOM Elements
665
+ const startBtn = document.getElementById('startBtn');
666
+ const questionnaire = document.getElementById('questionnaire');
667
+ const generating = document.getElementById('generating');
668
+ const results = document.getElementById('results');
669
+ const questionContainer = document.getElementById('questionContainer');
670
+ const prevBtn = document.getElementById('prevBtn');
671
+ const nextBtn = document.getElementById('nextBtn');
672
+ const currentStepEl = document.getElementById('currentStep');
673
+ const progressFill = document.getElementById('progressFill');
674
+
675
+ // Clerk Initialization
676
+ const frontendApi = 'YOUR_CLERK_FRONTEND_API_KEY'; // Replace with your Clerk Frontend API
677
+ const clerkPubKey = 'YOUR_CLERK_PUBLISHABLE_KEY'; // Replace with your Clerk Publishable Key
678
+
679
+ const clerk = new Clerk(frontendApi);
680
+
681
+ // Initialize Clerk
682
+ clerk.load({
683
+ publishableKey: clerkPubKey
684
+ }).then(() => {
685
+ // Mount user buttons
686
+ clerk.mountUserButton('#user-button');
687
+ clerk.mountUserButton('#nav-user-button');
688
+
689
+ // Check auth state
690
+ clerk.addListener(({ user }) => {
691
+ if (user) {
692
+ document.getElementById('landing').classList.add('hidden');
693
+ document.getElementById('app').classList.remove('hidden');
694
+ document.getElementById('app-nav').classList.remove('hidden');
695
+ } else {
696
+ document.getElementById('landing').classList.remove('hidden');
697
+ document.getElementById('app').classList.add('hidden');
698
+ document.getElementById('app-nav').classList.add('hidden');
699
+ }
700
+ });
701
+ });
702
+
703
+ // Initialize the app
704
+ function initApp() {
705
+ startBtn.addEventListener('click', startQuestionnaire);
706
+ nextBtn.addEventListener('click', goToNextStep);
707
+ prevBtn.addEventListener('click', goToPrevStep);
708
+
709
+ // Landing page button
710
+ document.getElementById('getStartedBtn').addEventListener('click', () => {
711
+ clerk.openSignIn();
712
+ });
713
+ }
714
+
715
+ // Start questionnaire
716
+ function startQuestionnaire() {
717
+ document.querySelector('section:first-child').classList.add('hidden');
718
+ questionnaire.classList.remove('hidden');
719
+ renderQuestion();
720
+ }
721
+
722
+ // Render current question
723
+ function renderQuestion() {
724
+ const question = state.questions[state.currentStep];
725
+
726
+ let html = `
727
+ <h4 class="font-bold mb-4">${question.question}</h4>
728
+ <div class="space-y-3">
729
+ `;
730
+
731
+ question.options.forEach((option, index) => {
732
+ html += `
733
+ <div class="flex items-center p-3 bg-gray-800/50 rounded-lg cursor-pointer option" data-index="${index}">
734
+ <div class="w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center mr-3">
735
+ <i class="${option.icon} text-primary"></i>
736
+ </div>
737
+ <span>${option.text}</span>
738
+ </div>
739
+ `;
740
+ });
741
+
742
+ html += `</div>`;
743
+ questionContainer.innerHTML = html;
744
+
745
+ // Update step indicator
746
+ currentStepEl.textContent = state.currentStep + 1;
747
+ progressFill.style.width = `${((state.currentStep + 1) / state.questions.length) * 100}%`;
748
+
749
+ // Update navigation buttons
750
+ prevBtn.classList.toggle('invisible', state.currentStep === 0);
751
+ prevBtn.classList.toggle('opacity-0', state.currentStep === 0);
752
+
753
+ if (state.currentStep === state.questions.length - 1) {
754
+ nextBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Wygeneruj plan';
755
+ } else {
756
+ nextBtn.innerHTML = '<span>Dalej</span> <i class="fas fa-arrow-right ml-2"></i>';
757
+ }
758
+
759
+ // Add event listeners to options
760
+ document.querySelectorAll('.option').forEach(option => {
761
+ option.addEventListener('click', function() {
762
+ // Remove selected class from all options
763
+ document.querySelectorAll('.option').forEach(opt => {
764
+ opt.classList.remove('bg-primary/20', 'border-primary');
765
+ });
766
+
767
+ // Add selected class to clicked option
768
+ this.classList.add('bg-primary/20', 'border-primary');
769
+
770
+ // Store answer
771
+ state.answers[state.currentStep] = parseInt(this.dataset.index);
772
+ });
773
+ });
774
+ }
775
+
776
+ // Go to next step
777
+ function goToNextStep() {
778
+ if (state.answers[state.currentStep] === undefined) {
779
+ alert('Proszę wybrać odpowiedź przed przejściem dalej');
780
+ return;
781
+ }
782
+
783
+ if (state.currentStep < state.questions.length - 1) {
784
+ state.currentStep++;
785
+ renderQuestion();
786
+ } else {
787
+ // Last step - generate plan
788
+ questionnaire.classList.add('hidden');
789
+ generating.classList.remove('hidden');
790
+
791
+ // Simulate AI processing
792
+ setTimeout(() => {
793
+ generating.classList.add('hidden');
794
+ results.classList.remove('hidden');
795
+
796
+ // Animate exercise cards
797
+ const cards = document.querySelectorAll('.exercise-card');
798
+ cards.forEach((card, index) => {
799
+ card.style.animationDelay = `${index * 0.1}s`;
800
+ });
801
+ }, 3000);
802
+ }
803
+ }
804
+
805
+ // Go to previous step
806
+ function goToPrevStep() {
807
+ if (state.currentStep > 0) {
808
+ state.currentStep--;
809
+ renderQuestion();
810
+ }
811
+ }
812
+
813
+ // Initialize the app when DOM is loaded
814
+ document.addEventListener('DOMContentLoaded', () => {
815
+ initApp();
816
+
817
+ // Hide app navigation on landing page
818
+ clerk.addListener(({ user }) => {
819
+ if (user) {
820
+ document.getElementById('app-nav').classList.remove('hidden');
821
+ } else {
822
+ document.getElementById('app-nav').classList.add('hidden');
823
+ }
824
+ });
825
+ });
826
+ </script>
827
+ <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 <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Prochu/trainflow" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
828
+ </html>