Download index.html from Prochu/trainflow: direct link, hf CLI and curl.
- Browser
- Download file 34.2 kB
-
https://huggingface.co/spaces/Prochu/trainflow/resolve/main/index.html
- Command line
-
hf download hf://spaces/Prochu/trainflow/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Prochu/trainflow/resolve/main/index.html
34.2 kB
| // src/types/index.ts | |
| export interface Exercise { | |
| name: string; | |
| sets: number; | |
| reps: string; | |
| type: string; | |
| } | |
| export interface WorkoutPlan { | |
| duration: string; | |
| daysPerWeek: number; | |
| goal: string; | |
| exercises: Exercise[]; | |
| } | |
| export interface Question { | |
| id: string; | |
| question: string; | |
| options: { | |
| text: string; | |
| value: string; | |
| icon: string; | |
| }[]; | |
| } | |
| // src/services/workoutService.ts | |
| import { WorkoutPlan } from '../types'; | |
| export const generateWorkoutPlan = async (answers: any): Promise<WorkoutPlan> => { | |
| const response = await fetch('/api/workout-plan', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ answers }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error('Failed to generate workout plan'); | |
| } | |
| return response.json(); | |
| }; | |
| // server/index.ts | |
| import express from 'express'; | |
| import cors from 'cors'; | |
| import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node'; | |
| const app = express(); | |
| app.use(cors()); | |
| app.use(express.json()); | |
| // API routes | |
| app.get('/api/workout-plan', ClerkExpressRequireAuth(), async (req, res) => { | |
| // Generate workout plan logic here | |
| res.json({ | |
| plan: { | |
| duration: '4 weeks', | |
| daysPerWeek: 4, | |
| goal: 'Muscle Building', | |
| exercises: [ | |
| // Exercise data | |
| ] | |
| } | |
| }); | |
| }); | |
| const PORT = process.env.PORT || 5000; | |
| app.listen(PORT, () => { | |
| console.log(`Server running on port ${PORT}`); | |
| }); | |
| // src/pages/MainApp.tsx | |
| import React from 'react'; | |
| import { Outlet } from 'react-router-dom'; | |
| import BottomNav from '../components/BottomNav'; | |
| const MainApp = () => { | |
| return ( | |
| <div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800 text-white"> | |
| <div className="pb-20"> | |
| <Outlet /> | |
| </div> | |
| <BottomNav /> | |
| </div> | |
| ); | |
| }; | |
| export default MainApp; | |
| // src/pages/LandingPage.tsx | |
| import React from 'react'; | |
| import { useClerk } from '@clerk/clerk-react'; | |
| import { Button } from '../components/ui/button'; | |
| const LandingPage = () => { | |
| const { openSignIn } = useClerk(); | |
| return ( | |
| <div className="min-h-screen px-4 py-8 pb-24 bg-gradient-to-br from-gray-900 to-gray-800 text-white"> | |
| <div className="max-w-6xl mx-auto"> | |
| <nav className="flex justify-between items-center py-6"> | |
| <div> | |
| <h1 className="text-2xl font-bold">Fit<span className="text-indigo-500">AI</span></h1> | |
| </div> | |
| <UserButton /> | |
| </nav> | |
| <div className="flex flex-col md:flex-row items-center justify-between mt-16"> | |
| {/* Rest of landing page content */} | |
| <Button onClick={() => openSignIn()}> | |
| Rozpocznij teraz | |
| </Button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default LandingPage; | |
| // src/App.tsx | |
| import React, { useState } from 'react'; | |
| import { ClerkProvider, SignedIn, SignedOut, UserButton } from '@clerk/clerk-react'; | |
| import LandingPage from './pages/LandingPage'; | |
| import MainApp from './pages/MainApp'; | |
| import './App.css'; | |
| const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY || ''; | |
| function App() { | |
| return ( | |
| <ClerkProvider publishableKey={clerkPubKey}> | |
| <SignedIn> | |
| <MainApp /> | |
| </SignedIn> | |
| <SignedOut> | |
| <LandingPage /> | |
| </SignedOut> | |
| </ClerkProvider> | |
| ); | |
| } | |
| export default App; | |
| <html lang="pl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>FitAI - Tw贸j inteligentny plan treningowy</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <script src="https://cdn.jsdelivr.net/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"></script> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#6366f1', | |
| secondary: '#8b5cf6', | |
| dark: '#1e293b', | |
| light: '#f8fafc' | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| .card { | |
| backdrop-filter: blur(10px); | |
| background: rgba(255, 255, 255, 0.08); | |
| border-radius: 20px; | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); | |
| } | |
| .exercise-card { | |
| transition: all 0.3s ease; | |
| } | |
| .exercise-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 12px 20px rgba(0, 0, 0, 0.2); | |
| } | |
| .progress-bar { | |
| height: 8px; | |
| border-radius: 4px; | |
| overflow: hidden; | |
| } | |
| .progress-fill { | |
| height: 100%; | |
| border-radius: 4px; | |
| transition: width 0.5s ease-in-out; | |
| } | |
| .floating-btn { | |
| box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4); | |
| transition: all 0.3s ease; | |
| } | |
| .floating-btn:hover { | |
| transform: scale(1.05); | |
| box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6); | |
| } | |
| .animate-pulse-slow { | |
| animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| } | |
| .slide-in { | |
| animation: slideIn 0.5s ease-out forwards; | |
| } | |
| @keyframes slideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(20px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .sticky-nav { | |
| position: fixed; | |
| bottom: 0; | |
| left: 0; | |
| right: 0; | |
| background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); | |
| padding: 12px 0; | |
| z-index: 100; | |
| display: flex; | |
| justify-content: center; | |
| height: 60px; /* Sta艂a wysoko艣膰 nawigacji */ | |
| box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3); /* Delikatny cie艅 dla lepszego oddzielenia */ | |
| } | |
| .clerk-user-button { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .clerk-user-button-trigger { | |
| width: 24px; | |
| height: 24px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .nav-content { | |
| width: 100%; | |
| max-width: 1024px; | |
| display: flex; | |
| justify-content: space-around; | |
| } | |
| .main-container { | |
| padding-bottom: 120px; /* Zwi臋kszamy padding aby uwzgl臋dni膰 nawigacj臋 */ | |
| width: 100%; | |
| max-width: 1024px; | |
| margin-bottom: 60px; /* Dodajemy margines na dole */ | |
| } | |
| @media (min-width: 768px) { | |
| .main-container { | |
| padding: 2rem; | |
| margin-top: 2rem; | |
| border-radius: 20px; | |
| background: rgba(30, 41, 59, 0.7); | |
| backdrop-filter: blur(10px); | |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .exercise-card { | |
| max-width: 600px; | |
| margin-left: auto; | |
| margin-right: auto; | |
| } | |
| .card { | |
| max-width: 600px; | |
| margin-left: auto; | |
| margin-right: auto; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="text-light"> | |
| <!-- Landing Page --> | |
| <section id="landing" class="min-h-screen px-4 py-8 pb-24"> <!-- Dodajemy pb-24 dla paddingu na dole --> | |
| <div class="max-w-6xl mx-auto"> | |
| <nav class="flex justify-between items-center py-6"> | |
| <div> | |
| <h1 class="text-2xl font-bold">Fit<span class="text-primary">AI</span></h1> | |
| </div> | |
| <div id="user-button"></div> | |
| </nav> | |
| <div class="flex flex-col md:flex-row items-center justify-between mt-16"> | |
| <div class="md:w-1/2 mb-12 md:mb-0"> | |
| <h2 class="text-4xl md:text-5xl font-bold mb-6">Tw贸j inteligentny <span class="text-primary">plan treningowy</span></h2> | |
| <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> | |
| <button id="getStartedBtn" class="px-8 py-3 bg-primary rounded-xl font-medium flex items-center space-x-2 floating-btn"> | |
| <span>Rozpocznij teraz</span> | |
| <i class="fas fa-arrow-right"></i> | |
| </button> | |
| </div> | |
| <div class="md:w-1/2"> | |
| <div class="card p-8 relative overflow-hidden"> | |
| <div class="absolute -top-10 -right-10 w-32 h-32 rounded-full bg-primary/20"></div> | |
| <div class="absolute -bottom-8 -left-8 w-24 h-24 rounded-full bg-secondary/20"></div> | |
| <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" | |
| alt="Fitness" class="w-full h-auto rounded-lg"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-24"> | |
| <h3 class="text-2xl font-bold mb-8 text-center">Dlaczego FitAI?</h3> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <div class="card p-6"> | |
| <div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center mb-4"> | |
| <i class="fas fa-brain text-primary"></i> | |
| </div> | |
| <h4 class="font-bold mb-2">AI-Powered</h4> | |
| <p class="opacity-80">Nasze algorytmy AI tworz膮 idealny plan treningowy dostosowany do Ciebie.</p> | |
| </div> | |
| <div class="card p-6"> | |
| <div class="w-12 h-12 rounded-full bg-secondary/20 flex items-center justify-center mb-4"> | |
| <i class="fas fa-bolt text-secondary"></i> | |
| </div> | |
| <h4 class="font-bold mb-2">Szybkie efekty</h4> | |
| <p class="opacity-80">Optymalizowane plany treningowe dla maksymalnych rezultat贸w.</p> | |
| </div> | |
| <div class="card p-6"> | |
| <div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center mb-4"> | |
| <i class="fas fa-chart-line text-primary"></i> | |
| </div> | |
| <h4 class="font-bold mb-2">艢led藕 post臋py</h4> | |
| <p class="opacity-80">Monitoruj swoje osi膮gni臋cia i dostosowuj plan do swoich potrzeb.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Main Container --> | |
| <div id="app" class="min-h-screen px-4 py-8 main-container hidden"> | |
| <!-- Header --> | |
| <header class="flex justify-between items-center mb-8"> | |
| <div> | |
| <h1 class="text-2xl font-bold">Fit<span class="text-primary">AI</span></h1> | |
| <p class="text-sm opacity-75">Inteligentny plan treningowy</p> | |
| </div> | |
| <div class="flex space-x-3"> | |
| <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center"> | |
| <i class="fas fa-user text-primary"></i> | |
| </button> | |
| <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center"> | |
| <i class="fas fa-cog text-primary"></i> | |
| </button> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main> | |
| <!-- Hero Section --> | |
| <section class="card p-6 mb-8 relative overflow-hidden"> | |
| <div class="absolute -top-10 -right-10 w-32 h-32 rounded-full bg-primary/20"></div> | |
| <div class="absolute -bottom-8 -left-8 w-24 h-24 rounded-full bg-secondary/20"></div> | |
| <div class="relative z-10"> | |
| <h2 class="text-xl font-bold mb-2">Stw贸rz sw贸j idealny plan treningowy</h2> | |
| <p class="text-sm opacity-80 mb-4">Odpowiedz na kilka pyta艅, a nasze AI stworzy dla Ciebie spersonalizowany plan treningowy</p> | |
| <button id="startBtn" class="w-full py-3 bg-primary rounded-xl font-medium flex items-center justify-center space-x-2 floating-btn"> | |
| <span>Rozpocznij teraz</span> | |
| <i class="fas fa-arrow-right"></i> | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Questionnaire Section --> | |
| <section id="questionnaire" class="hidden"> | |
| <div class="card p-6 mb-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="font-medium">Tw贸j plan treningowy</h3> | |
| <span class="text-sm bg-primary/20 px-2 py-1 rounded">Krok <span id="currentStep">1</span>/5</span> | |
| </div> | |
| <div class="progress-bar bg-gray-700 mb-6"> | |
| <div id="progressFill" class="progress-fill bg-primary w-1/5"></div> | |
| </div> | |
| <div id="questionContainer"> | |
| <!-- Questions will be injected here --> | |
| </div> | |
| <div class="flex justify-between mt-6"> | |
| <button id="prevBtn" class="py-2 px-4 rounded-lg bg-gray-700 opacity-0 invisible"> | |
| <i class="fas fa-arrow-left mr-2"></i>Wstecz | |
| </button> | |
| <button id="nextBtn" class="py-2 px-4 bg-primary rounded-lg flex items-center"> | |
| <span>Dalej</span> | |
| <i class="fas fa-arrow-right ml-2"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Generating Section --> | |
| <section id="generating" class="hidden"> | |
| <div class="card p-8 text-center"> | |
| <div class="flex justify-center mb-6"> | |
| <div class="w-16 h-16 rounded-full bg-primary/20 flex items-center justify-center animate-pulse-slow"> | |
| <i class="fas fa-brain text-2xl text-primary"></i> | |
| </div> | |
| </div> | |
| <h3 class="text-xl font-bold mb-2">Tworz臋 Tw贸j plan...</h3> | |
| <p class="opacity-80 mb-6">Nasze AI analizuje Twoje odpowiedzi i tworzy idealny plan treningowy</p> | |
| <div class="flex space-x-2 justify-center"> | |
| <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow"></div> | |
| <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow delay-150"></div> | |
| <div class="w-2 h-2 bg-primary rounded-full animate-pulse-slow delay-300"></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Results Section --> | |
| <section id="results" class="hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-xl font-bold">Tw贸j plan treningowy</h2> | |
| <button class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center"> | |
| <i class="fas fa-download text-primary"></i> | |
| </button> | |
| </div> | |
| <div class="card p-5 mb-6"> | |
| <div class="flex justify-between mb-4"> | |
| <div> | |
| <h3 class="font-bold">Plan na 4 tygodnie</h3> | |
| <p class="text-sm opacity-80">Dla 艣redniozaawansowanych</p> | |
| </div> | |
| <div class="bg-secondary/20 text-secondary px-3 py-1 rounded-lg text-sm font-medium"> | |
| 4 dni/tydzie艅 | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-2 mb-4"> | |
| <div class="bg-gray-800/50 rounded-lg p-3 text-center"> | |
| <p class="text-sm opacity-80">Cel</p> | |
| <p class="font-medium">Budowa mi臋艣ni</p> | |
| </div> | |
| <div class="bg-gray-800/50 rounded-lg p-3 text-center"> | |
| <p class="text-sm opacity-80">Czas</p> | |
| <p class="font-medium">45-60 min</p> | |
| </div> | |
| </div> | |
| <button class="w-full py-2 bg-primary/20 text-primary rounded-lg font-medium"> | |
| <i class="fas fa-sync-alt mr-2"></i>Wygeneruj ponownie | |
| </button> | |
| </div> | |
| <h3 class="font-bold mb-4">Dzisiejszy trening: G贸rna cz臋艣膰 cia艂a</h3> | |
| <div class="space-y-4"> | |
| <!-- Exercise Cards --> | |
| <div class="exercise-card card p-4 slide-in"> | |
| <div class="flex items-start"> | |
| <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3"> | |
| <i class="fas fa-dumbbell text-primary"></i> | |
| </div> | |
| <div class="flex-1"> | |
| <h4 class="font-bold">Wyciskanie sztangi le偶膮c</h4> | |
| <div class="flex text-sm mt-1"> | |
| <span class="bg-gray-700 px-2 py-1 rounded mr-2">4 serie</span> | |
| <span class="bg-gray-700 px-2 py-1 rounded">8-12 powt贸rze艅</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="exercise-card card p-4 slide-in"> | |
| <div class="flex items-start"> | |
| <div class="bg-secondary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3"> | |
| <i class="fas fa-dumbbell text-secondary"></i> | |
| </div> | |
| <div class="flex-1"> | |
| <h4 class="font-bold">Wyciskanie hantli na skosie</h4> | |
| <div class="flex text-sm mt-1"> | |
| <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span> | |
| <span class="bg-gray-700 px-2 py-1 rounded">10-15 powt贸rze艅</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="exercise-card card p-4 slide-in"> | |
| <div class="flex items-start"> | |
| <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3"> | |
| <i class="fas fa-dumbbell text-primary"></i> | |
| </div> | |
| <div class="flex-1"> | |
| <h4 class="font-bold">Podci膮ganie na dr膮偶ku</h4> | |
| <div class="flex text-sm mt-1"> | |
| <span class="bg-gray-700 px-2 py-1 rounded mr-2">4 serie</span> | |
| <span class="bg-gray-700 px-2 py-1 rounded">6-10 powt贸rze艅</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="exercise-card card p-4 slide-in"> | |
| <div class="flex items-start"> | |
| <div class="bg-secondary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3"> | |
| <i class="fas fa-dumbbell text-secondary"></i> | |
| </div> | |
| <div class="flex-1"> | |
| <h4 class="font-bold">Uginanie ramion ze sztang膮</h4> | |
| <div class="flex text-sm mt-1"> | |
| <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span> | |
| <span class="bg-gray-700 px-2 py-1 rounded">10-12 powt贸rze艅</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="exercise-card card p-4 slide-in"> | |
| <div class="flex items-start"> | |
| <div class="bg-primary/20 w-12 h-12 rounded-lg flex items-center justify-center mr-3"> | |
| <i class="fas fa-dumbbell text-primary"></i> | |
| </div> | |
| <div class="flex-1"> | |
| <h4 class="font-bold">Wyciskanie francuskie</h4> | |
| <div class="flex text-sm mt-1"> | |
| <span class="bg-gray-700 px-2 py-1 rounded mr-2">3 serie</span> | |
| <span class="bg-gray-700 px-2 py-1 rounded">12-15 powt贸rze艅</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-8 flex space-x-3"> | |
| <button class="flex-1 py-3 bg-primary rounded-xl font-medium"> | |
| <i class="fas fa-play-circle mr-2"></i>Rozpocznij trening | |
| </button> | |
| <button class="w-12 h-12 rounded-xl bg-gray-700 flex items-center justify-center"> | |
| <i class="fas fa-calendar"></i> | |
| </button> | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="sticky-nav border-t border-gray-700" id="app-nav"> | |
| <div class="nav-content px-4"> | |
| <button class="flex flex-col items-center text-primary"> | |
| <i class="fas fa-home text-lg"></i> | |
| <span class="text-xs mt-1">Strona g艂贸wna</span> | |
| </button> | |
| <button class="flex flex-col items-center opacity-60"> | |
| <i class="fas fa-calendar text-lg"></i> | |
| <span class="text-xs mt-1">Kalendarz</span> | |
| </button> | |
| <button class="flex flex-col items-center opacity-60"> | |
| <i class="fas fa-chart-line text-lg"></i> | |
| <span class="text-xs mt-1">Statystyki</span> | |
| </button> | |
| <div id="nav-user-button" class="flex flex-col items-center"> | |
| <div class="w-6 h-6 flex items-center justify-center"> | |
| <i class="fas fa-user text-lg"></i> | |
| </div> | |
| <span class="text-xs mt-1">Profil</span> | |
| </div> | |
| </nav> | |
| <script> | |
| // App state | |
| const state = { | |
| currentStep: 0, | |
| answers: {}, | |
| questions: [ | |
| { | |
| question: "Jaki jest Tw贸j g艂贸wny cel treningowy?", | |
| options: [ | |
| {text: "Budowa mi臋艣ni", icon: "fas fa-dumbbell"}, | |
| {text: "Redukcja tkanki t艂uszczowej", icon: "fas fa-weight-scale"}, | |
| {text: "Poprawa wytrzyma艂o艣ci", icon: "fas fa-heart-pulse"}, | |
| {text: "Og贸lna sprawno艣膰", icon: "fas fa-person-running"} | |
| ] | |
| }, | |
| { | |
| question: "Jaki jest Tw贸j poziom zaawansowania?", | |
| options: [ | |
| {text: "Pocz膮tkuj膮cy", icon: "fas fa-seedling"}, | |
| {text: "艢redniozaawansowany", icon: "fas fa-chart-line"}, | |
| {text: "Zaawansowany", icon: "fas fa-fire"} | |
| ] | |
| }, | |
| { | |
| question: "Ile dni w tygodniu chcesz trenowa膰?", | |
| options: [ | |
| {text: "2 dni", icon: "fas fa-calendar"}, | |
| {text: "3 dni", icon: "fas fa-calendar"}, | |
| {text: "4 dni", icon: "fas fa-calendar"}, | |
| {text: "5+ dni", icon: "fas fa-calendar"} | |
| ] | |
| }, | |
| { | |
| question: "Jakie masz dost臋pne wyposa偶enie?", | |
| options: [ | |
| {text: "Brak sprz臋tu", icon: "fas fa-person"}, | |
| {text: "Hantle", icon: "fas fa-dumbbell"}, | |
| {text: "Sztanga", icon: "fas fa-weight-hanging"}, | |
| {text: "Pe艂ny zestaw si艂owni", icon: "fas fa-building"} | |
| ] | |
| }, | |
| { | |
| question: "Ile czasu mo偶esz po艣wi臋ci膰 na trening?", | |
| options: [ | |
| {text: "30 minut", icon: "fas fa-clock"}, | |
| {text: "45 minut", icon: "fas fa-clock"}, | |
| {text: "60 minut", icon: "fas fa-clock"}, | |
| {text: "90+ minut", icon: "fas fa-clock"} | |
| ] | |
| } | |
| ] | |
| }; | |
| // DOM Elements | |
| const startBtn = document.getElementById('startBtn'); | |
| const questionnaire = document.getElementById('questionnaire'); | |
| const generating = document.getElementById('generating'); | |
| const results = document.getElementById('results'); | |
| const questionContainer = document.getElementById('questionContainer'); | |
| const prevBtn = document.getElementById('prevBtn'); | |
| const nextBtn = document.getElementById('nextBtn'); | |
| const currentStepEl = document.getElementById('currentStep'); | |
| const progressFill = document.getElementById('progressFill'); | |
| // Clerk Initialization | |
| const frontendApi = 'YOUR_CLERK_FRONTEND_API_KEY'; // Replace with your Clerk Frontend API | |
| const clerkPubKey = 'YOUR_CLERK_PUBLISHABLE_KEY'; // Replace with your Clerk Publishable Key | |
| const clerk = new Clerk(frontendApi); | |
| // Initialize Clerk | |
| clerk.load({ | |
| publishableKey: clerkPubKey | |
| }).then(() => { | |
| // Mount user buttons | |
| clerk.mountUserButton('#user-button'); | |
| clerk.mountUserButton('#nav-user-button'); | |
| // Check auth state | |
| clerk.addListener(({ user }) => { | |
| if (user) { | |
| document.getElementById('landing').classList.add('hidden'); | |
| document.getElementById('app').classList.remove('hidden'); | |
| document.getElementById('app-nav').classList.remove('hidden'); | |
| } else { | |
| document.getElementById('landing').classList.remove('hidden'); | |
| document.getElementById('app').classList.add('hidden'); | |
| document.getElementById('app-nav').classList.add('hidden'); | |
| } | |
| }); | |
| }); | |
| // Initialize the app | |
| function initApp() { | |
| startBtn.addEventListener('click', startQuestionnaire); | |
| nextBtn.addEventListener('click', goToNextStep); | |
| prevBtn.addEventListener('click', goToPrevStep); | |
| // Landing page button | |
| document.getElementById('getStartedBtn').addEventListener('click', () => { | |
| clerk.openSignIn(); | |
| }); | |
| } | |
| // Start questionnaire | |
| function startQuestionnaire() { | |
| document.querySelector('section:first-child').classList.add('hidden'); | |
| questionnaire.classList.remove('hidden'); | |
| renderQuestion(); | |
| } | |
| // Render current question | |
| function renderQuestion() { | |
| const question = state.questions[state.currentStep]; | |
| let html = ` | |
| <h4 class="font-bold mb-4">${question.question}</h4> | |
| <div class="space-y-3"> | |
| `; | |
| question.options.forEach((option, index) => { | |
| html += ` | |
| <div class="flex items-center p-3 bg-gray-800/50 rounded-lg cursor-pointer option" data-index="${index}"> | |
| <div class="w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center mr-3"> | |
| <i class="${option.icon} text-primary"></i> | |
| </div> | |
| <span>${option.text}</span> | |
| </div> | |
| `; | |
| }); | |
| html += `</div>`; | |
| questionContainer.innerHTML = html; | |
| // Update step indicator | |
| currentStepEl.textContent = state.currentStep + 1; | |
| progressFill.style.width = `${((state.currentStep + 1) / state.questions.length) * 100}%`; | |
| // Update navigation buttons | |
| prevBtn.classList.toggle('invisible', state.currentStep === 0); | |
| prevBtn.classList.toggle('opacity-0', state.currentStep === 0); | |
| if (state.currentStep === state.questions.length - 1) { | |
| nextBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Wygeneruj plan'; | |
| } else { | |
| nextBtn.innerHTML = '<span>Dalej</span> <i class="fas fa-arrow-right ml-2"></i>'; | |
| } | |
| // Add event listeners to options | |
| document.querySelectorAll('.option').forEach(option => { | |
| option.addEventListener('click', function() { | |
| // Remove selected class from all options | |
| document.querySelectorAll('.option').forEach(opt => { | |
| opt.classList.remove('bg-primary/20', 'border-primary'); | |
| }); | |
| // Add selected class to clicked option | |
| this.classList.add('bg-primary/20', 'border-primary'); | |
| // Store answer | |
| state.answers[state.currentStep] = parseInt(this.dataset.index); | |
| }); | |
| }); | |
| } | |
| // Go to next step | |
| function goToNextStep() { | |
| if (state.answers[state.currentStep] === undefined) { | |
| alert('Prosz臋 wybra膰 odpowied藕 przed przej艣ciem dalej'); | |
| return; | |
| } | |
| if (state.currentStep < state.questions.length - 1) { | |
| state.currentStep++; | |
| renderQuestion(); | |
| } else { | |
| // Last step - generate plan | |
| questionnaire.classList.add('hidden'); | |
| generating.classList.remove('hidden'); | |
| // Simulate AI processing | |
| setTimeout(() => { | |
| generating.classList.add('hidden'); | |
| results.classList.remove('hidden'); | |
| // Animate exercise cards | |
| const cards = document.querySelectorAll('.exercise-card'); | |
| cards.forEach((card, index) => { | |
| card.style.animationDelay = `${index * 0.1}s`; | |
| }); | |
| }, 3000); | |
| } | |
| } | |
| // Go to previous step | |
| function goToPrevStep() { | |
| if (state.currentStep > 0) { | |
| state.currentStep--; | |
| renderQuestion(); | |
| } | |
| } | |
| // Initialize the app when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', () => { | |
| initApp(); | |
| // Hide app navigation on landing page | |
| clerk.addListener(({ user }) => { | |
| if (user) { | |
| document.getElementById('app-nav').classList.remove('hidden'); | |
| } else { | |
| document.getElementById('app-nav').classList.add('hidden'); | |
| } | |
| }); | |
| }); | |
| </script> | |
| <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> | |
| </html> |