128 lines
6.9 KiB
PHP
128 lines
6.9 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>AI Workout Generator</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header class="main-header">
|
|
<h1>AI Workout Generator</h1>
|
|
<p>Fill out the form below to get a personalized workout plan.</p>
|
|
</header>
|
|
|
|
<div class="card">
|
|
<form action="generator.php" method="POST">
|
|
<div class="form-group">
|
|
<label for="goal">Fitness Goal</label>
|
|
<select id="goal" name="goal" class="form-control">
|
|
<option value="build_muscle">Build Muscle</option>
|
|
<option value="lose_weight">Lose Weight</option>
|
|
<option value="improve_endurance">Improve Endurance</option>
|
|
<option value="general_fitness">General Fitness</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="level">Fitness Level</label>
|
|
<select id="level" name="level" class="form-control">
|
|
<option value="beginner">Beginner</option>
|
|
<option value="intermediate">Intermediate</option>
|
|
<option value="advanced">Advanced</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="duration">Workout Duration (minutes)</label>
|
|
<select id="duration" name="duration" class="form-control">
|
|
<option value="30">30 minutes</option>
|
|
<option value="45">45 minutes</option>
|
|
<option value="60">60 minutes</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Available Equipment</label>
|
|
<div class="checkbox-group">
|
|
<label><input type="checkbox" name="equipment[]" value="none" checked> None (Bodyweight)</label>
|
|
<label><input type="checkbox" name="equipment[]" value="dumbbells"> Dumbbells</label>
|
|
<label><input type="checkbox" name="equipment[]" value="barbell"> Barbell</label>
|
|
<label><input type="checkbox" name="equipment[]" value="kettlebells"> Kettlebells</label>
|
|
<label><input type="checkbox" name="equipment[]" value="resistance_bands"> Resistance Bands</label>
|
|
<label><input type="checkbox" name="equipment[]" value="full_gym"> Full Gym Access</label>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary">Generate Workout</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="workout-result">
|
|
<?php
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
require_once __DIR__ . '/ai/LocalAIApi.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$goal = $_POST['goal'] ?? 'general_fitness';
|
|
$level = $_POST['level'] ?? 'beginner';
|
|
$duration = $_POST['duration'] ?? '30';
|
|
$equipment = isset($_POST['equipment']) ? implode(', ', $_POST['equipment']) : 'none';
|
|
|
|
$system_prompt = "You are an expert fitness coach. Your task is to create a personalized workout plan based on the user's goals, fitness level, and available equipment. Respond with a JSON object. The JSON object should have a single key 'workout' which is an array of sections. Each section object should have 'title' (e.g., 'Warm-up', 'Main Workout', 'Cool-down') and 'exercises' which is an array of exercise objects. Each exercise object should have 'name', 'sets', 'reps' (e.g., '3 sets of 10-12 reps' or '60 seconds'), and 'video_url' which is a URL to a YouTube video demonstrating the exercise.";
|
|
|
|
$user_prompt = "Please generate a workout plan for me based on the following details:\n- Fitness Goal: {$goal}\n- Fitness Level: {$level}\n- Workout Duration: {$duration} minutes\n- Available Equipment: {$equipment}";
|
|
|
|
echo '<div class="card"><div class="card-header"><h2>Your Personalized Workout Plan</h2></div><div class="card-body"><p>Generating your workout, please wait...</p></div></div>';
|
|
|
|
$resp = LocalAIApi::createResponse(
|
|
[
|
|
'input' => [
|
|
['role' => 'system', 'content' => $system_prompt],
|
|
['role' => 'user', 'content' => $user_prompt],
|
|
],
|
|
]
|
|
);
|
|
|
|
if (!empty($resp['success'])) {
|
|
$text = LocalAIApi::extractText($resp);
|
|
$workout_data = json_decode($text, true);
|
|
|
|
if ($workout_data && isset($workout_data['workout'])) {
|
|
echo '<div class="card animated fadeIn">';
|
|
foreach ($workout_data['workout'] as $section) {
|
|
echo '<div class="workout-section">';
|
|
echo '<h3>' . htmlspecialchars($section['title']) . '</h3>';
|
|
echo '<ul class="exercise-list">';
|
|
foreach ($section['exercises'] as $exercise) {
|
|
echo '<li>';
|
|
echo '<strong>' . htmlspecialchars($exercise['name']) . '</strong>';
|
|
echo '<span>' . htmlspecialchars($exercise['sets']) . ' of ' . htmlspecialchars($exercise['reps']) . '</span>';
|
|
if (!empty($exercise['video_url'])) {
|
|
echo '<a href="' . htmlspecialchars($exercise['video_url']) . '" target="_blank">Watch Video</a>';
|
|
}
|
|
echo '</li>';
|
|
}
|
|
echo '</ul>';
|
|
echo '</div>';
|
|
}
|
|
echo '</div>';
|
|
} else {
|
|
echo '<div class="card"><div class="card-body"><p>Error: The AI returned an invalid workout structure. Here is the raw response:</p><pre>' . htmlspecialchars($text) . '</pre></div></div>';
|
|
}
|
|
} else {
|
|
echo '<div class="card"><div class="card-body"><p>Error generating workout. Details: ' . htmlspecialchars($resp['error'] ?? 'Unknown error') . '</p></div></div>';
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
<script src="assets/js/main.js"></script>
|
|
</body>
|
|
</html>
|