0.1
This commit is contained in:
parent
e690de7d04
commit
373e36aedb
171
assets/css/custom.css
Normal file
171
assets/css/custom.css
Normal file
@ -0,0 +1,171 @@
|
||||
/* SunSkills App Custom Stylesheet */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Inter:wght@400;500;700&display=swap');
|
||||
|
||||
:root {
|
||||
--primary-dark: #1A1A2E;
|
||||
--secondary-accent: #E94560;
|
||||
--background-light: #F0F2F5;
|
||||
--surface-white: #FFFFFF;
|
||||
--text-primary: #1A1A2E;
|
||||
--text-secondary: #555770;
|
||||
--gradient-start: #16213E;
|
||||
--gradient-end: #1A1A2E;
|
||||
|
||||
--font-heading: 'Playfair Display', serif;
|
||||
--font-body: 'Inter', sans-serif;
|
||||
|
||||
--spacing-unit: 1rem;
|
||||
--border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background-color: var(--background-light);
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: var(--font-heading);
|
||||
color: var(--text-primary);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--secondary-accent);
|
||||
border-color: var(--secondary-accent);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(233, 69, 96, 0.4);
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: var(--surface-white);
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.hero {
|
||||
background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end));
|
||||
color: white;
|
||||
padding: 8rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
color: white;
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 5rem 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.07);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: var(--primary-dark);
|
||||
color: var(--background-light);
|
||||
padding: 3rem 0;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
color: var(--background-light);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer a:hover {
|
||||
color: var(--secondary-accent);
|
||||
}
|
||||
|
||||
/* Pricing Page Styles */
|
||||
.pricing-card .card-price {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.pricing-card .card-price .text-muted {
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.pricing-card ul li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.card-popular {
|
||||
border: 2px solid var(--secondary-accent) !important;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popular-badge {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: -30px;
|
||||
background-color: var(--secondary-accent);
|
||||
color: white;
|
||||
padding: 5px 30px;
|
||||
transform: rotate(45deg);
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Dashboard Premium Styles */
|
||||
.premium-badge {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
background-color: var(--secondary-accent);
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 0.8rem;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.locked-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.locked-overlay i {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
23
assets/js/main.js
Normal file
23
assets/js/main.js
Normal file
@ -0,0 +1,23 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const contactForm = document.getElementById('contactForm');
|
||||
if (contactForm) {
|
||||
contactForm.addEventListener('submit', function(e) {
|
||||
const name = document.getElementById('name').value.trim();
|
||||
const email = document.getElementById('email').value.trim();
|
||||
const message = document.getElementById('message').value.trim();
|
||||
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
|
||||
if (name === '' || email === '' || message === '') {
|
||||
e.preventDefault();
|
||||
alert('Please fill out all fields.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!emailPattern.test(email)) {
|
||||
e.preventDefault();
|
||||
alert('Please enter a valid email address.');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
44
contact.php
Normal file
44
contact.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/mail/MailService.php';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$name = trim(filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING));
|
||||
$email = trim(filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL));
|
||||
$message = trim(filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING));
|
||||
|
||||
if ($name && $email && $message) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$sql = "INSERT INTO contact_submissions (name, email, message) VALUES (?, ?, ?)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([$name, $email, $message]);
|
||||
|
||||
// Send email notification
|
||||
$to = getenv('MAIL_TO') ?: 'support@sunsills.com'; // Fallback recipient
|
||||
$subject = "New Contact Form Submission from {$name}";
|
||||
$emailBody = "<p>You have received a new message from your website contact form.</p>";
|
||||
$emailBody .= "<p><strong>Name:</strong> {$name}</p>";
|
||||
$emailBody .= "<p><strong>Email:</strong> {$email}</p>";
|
||||
$emailBody .= "<p><strong>Message:</strong><br>{$message}</p>";
|
||||
|
||||
MailService::sendMail($to, $subject, $emailBody, strip_tags($emailBody), ['reply_to' => $email]);
|
||||
|
||||
$_SESSION['success_message'] = "Thank you for your message! We will get back to you shortly.";
|
||||
} catch (PDOException $e) {
|
||||
// In a real app, you would log this error
|
||||
$_SESSION['error_message'] = "Sorry, there was an error processing your request. Please try again later.";
|
||||
} catch (Exception $e) {
|
||||
$_SESSION['error_message'] = "Could not send email. Please try again later.";
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error_message'] = "Invalid input. Please fill out all fields correctly.";
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error_message'] = "Invalid request method.";
|
||||
}
|
||||
|
||||
header("Location: index.php#contact");
|
||||
exit();
|
||||
141
dashboard.php
Normal file
141
dashboard.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
// If user is not logged in, redirect to login page
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_name = $_SESSION['user_name'];
|
||||
$subscription_status = $_SESSION['subscription_status'] ?? 'free';
|
||||
$quiz_completed = isset($_SESSION['quiz_answers']);
|
||||
$recommended_skills = [];
|
||||
|
||||
if ($quiz_completed) {
|
||||
try {
|
||||
$p_interest = $_SESSION['quiz_answers']['interests'];
|
||||
$pdo = db();
|
||||
// Fetch all skills in the category, not just free ones
|
||||
$stmt = $pdo->prepare("SELECT * FROM skills WHERE category = ?");
|
||||
$stmt->execute([$p_interest]);
|
||||
$recommended_skills = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
error_log("Database error fetching skills: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard - SunSkills</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php">SunSkills</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<?php if ($subscription_status == 'free'): ?>
|
||||
<li class="nav-item"><a class="nav-link btn btn-warning text-dark" href="pricing.php">Upgrade</a></li>
|
||||
<?php endif; ?>
|
||||
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Welcome, <?php echo htmlspecialchars($user_name); ?>!</h1>
|
||||
<p class="lead">Your subscription status: <span class="fw-bold <?php echo $subscription_status == 'premium' ? 'text-success' : 'text-warning'; ?>"><?php echo htmlspecialchars(ucfirst($subscription_status)); ?></span></p>
|
||||
|
||||
<?php if (isset($_SESSION['success_message'])): ?>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<?php echo $_SESSION['success_message']; unset($_SESSION['success_message']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION['error_message'])): ?>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<?php echo $_SESSION['error_message']; unset($_SESSION['error_message']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($quiz_completed && !empty($recommended_skills)): ?>
|
||||
<div class="mt-5">
|
||||
<h3>Here are your recommended skills!</h3>
|
||||
<p>Based on your interests in <strong><?php echo htmlspecialchars($_SESSION['quiz_answers']['interests']); ?></strong>, we think you'll love these:</p>
|
||||
<div class="row">
|
||||
<?php foreach ($recommended_skills as $skill):
|
||||
$is_premium = $skill['is_premium'];
|
||||
$can_access = ($subscription_status == 'premium' || !$is_premium);
|
||||
?>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100 <?php echo $is_premium ? 'border-warning' : ''; ?>">
|
||||
<?php if ($is_premium): ?>
|
||||
<div class="premium-badge">Premium <i class="bi bi-star-fill"></i></div>
|
||||
<?php endif; ?>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?php echo htmlspecialchars($skill['title']); ?></h5>
|
||||
<p class="card-text"><?php echo htmlspecialchars($skill['description']); ?></p>
|
||||
<div class="ratio ratio-16x9">
|
||||
<?php if ($can_access): ?>
|
||||
<iframe src="<?php echo htmlspecialchars($skill['video_url']); ?>" title="<?php echo htmlspecialchars($skill['title']); ?>" allowfullscreen></iframe>
|
||||
<?php else: ?>
|
||||
<div class="locked-overlay">
|
||||
<i class="bi bi-lock-fill"></i>
|
||||
<p>Upgrade to watch</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<?php if ($can_access): ?>
|
||||
<a href="#" class="btn btn-primary w-100">Start Learning</a>
|
||||
<?php else: ?>
|
||||
<a href="pricing.php" class="btn btn-warning w-100">Upgrade to Premium</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($quiz_completed): ?>
|
||||
<div class="mt-5">
|
||||
<h3>No recommendations found yet</h3>
|
||||
<p>We couldn't find any skills matching your interest in "<?php echo htmlspecialchars($_SESSION['quiz_answers']['interests']); ?>". Please check back later as we add more courses!</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="mt-5 text-center">
|
||||
<h3>Let's Personalize Your Journey!</h3>
|
||||
<p>To unlock skill recommendations tailored just for you, please take our quick 3-question quiz.</p>
|
||||
<a href="quiz.php" class="btn btn-primary btn-lg">Take the Quiz</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-light">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -6,12 +6,36 @@ define('DB_USER', 'app_30908');
|
||||
define('DB_PASS', '98b730aa-be6c-479d-a47d-e5e7abc49229');
|
||||
|
||||
function db() {
|
||||
static $pdo;
|
||||
if (!$pdo) {
|
||||
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
}
|
||||
return $pdo;
|
||||
static $pdo;
|
||||
if ($pdo) {
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() === 1049) { // Database doesn't exist
|
||||
try {
|
||||
$tempPdo = new PDO('mysql:host='.DB_HOST, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
]);
|
||||
$tempPdo->exec('CREATE DATABASE IF NOT EXISTS `'.DB_NAME.'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
|
||||
// Reconnect to the newly created database
|
||||
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
} catch (PDOException $creationException) {
|
||||
// If creation fails, re-throw the original exception
|
||||
throw $e;
|
||||
}
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
15
db/migrate.php
Normal file
15
db/migrate.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
$sql = file_get_contents(__DIR__ . '/migrations/001_create_contact_submissions.sql');
|
||||
if ($sql === false) {
|
||||
throw new Exception("Failed to read migration file.");
|
||||
}
|
||||
$pdo->exec($sql);
|
||||
echo "Migration applied successfully.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error applying migration: " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
13
db/migrate_002.php
Normal file
13
db/migrate_002.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
$sql = file_get_contents(__DIR__ . '/migrations/002_create_users_table.sql');
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
$pdo->exec($sql);
|
||||
echo "Migration 002_create_users_table executed successfully.\n";
|
||||
} catch (PDOException $e) {
|
||||
die("Migration failed: " . $e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
20
db/migrate_003_004.php
Normal file
20
db/migrate_003_004.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
function run_migration($file) {
|
||||
$pdo = db();
|
||||
$sql = file_get_contents($file);
|
||||
if ($sql === false) {
|
||||
die("Error reading migration file: $file");
|
||||
}
|
||||
try {
|
||||
$pdo->exec($sql);
|
||||
echo "Successfully executed migration: $file\n";
|
||||
} catch (PDOException $e) {
|
||||
die("Migration failed: " . $e->getMessage() . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
run_migration(__DIR__ . '/migrations/003_create_skills_table.sql');
|
||||
run_migration(__DIR__ . '/migrations/004_insert_sample_skills.sql');
|
||||
|
||||
36
db/migrate_005.php
Normal file
36
db/migrate_005.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
function run_migration($file) {
|
||||
$db = db();
|
||||
$sql = file_get_contents($file);
|
||||
if ($sql === false) {
|
||||
die("Error reading migration file: $file\n");
|
||||
}
|
||||
|
||||
// Split the SQL file into individual queries
|
||||
$queries = explode(';', $sql);
|
||||
|
||||
foreach ($queries as $query) {
|
||||
$query = trim($query);
|
||||
if (!empty($query)) {
|
||||
try {
|
||||
$db->exec($query);
|
||||
echo "Successfully executed query from $file:\n$query\n\n";
|
||||
} catch (PDOException $e) {
|
||||
die("Error executing query from $file: " . $e->getMessage() . "\nQuery:\n$query\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$migration_files = [
|
||||
__DIR__ . '/migrations/005_add_premium_features.sql',
|
||||
];
|
||||
|
||||
foreach ($migration_files as $file) {
|
||||
run_migration($file);
|
||||
}
|
||||
|
||||
echo "Migrations completed successfully!\n";
|
||||
|
||||
11
db/migrations/001_create_contact_submissions.sql
Normal file
11
db/migrations/001_create_contact_submissions.sql
Normal file
@ -0,0 +1,11 @@
|
||||
-- 001_create_contact_submissions.sql
|
||||
-- Creates the table for storing contact form submissions.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `contact_submissions` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`message` text NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
9
db/migrations/002_create_users_table.sql
Normal file
9
db/migrations/002_create_users_table.sql
Normal file
@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NOT NULL UNIQUE,
|
||||
`phone` VARCHAR(50) NULL UNIQUE,
|
||||
`password` VARCHAR(255) NOT NULL,
|
||||
`profile` TEXT NULL, -- For storing quiz answers/preferences as JSON
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
8
db/migrations/003_create_skills_table.sql
Normal file
8
db/migrations/003_create_skills_table.sql
Normal file
@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS skills (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
category VARCHAR(100),
|
||||
video_url VARCHAR(255),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
7
db/migrations/004_insert_sample_skills.sql
Normal file
7
db/migrations/004_insert_sample_skills.sql
Normal file
@ -0,0 +1,7 @@
|
||||
INSERT INTO skills (title, description, category, video_url) VALUES
|
||||
('Basic Motorcycle Repair', 'Learn to fix common issues with your motorcycle.', 'Auto', 'https://www.youtube.com/embed/example1'),
|
||||
('Introduction to Soldering', 'A beginner\'s guide to soldering electronics.', 'Electronics', 'https://www.youtube.com/embed/example2'),
|
||||
('Cooking for Beginners', 'Learn to cook simple and delicious meals.', 'Cooking', 'https://www.youtube.com/embed/example3'),
|
||||
('Advanced Car Maintenance', 'Go beyond the basics of car maintenance.', 'Auto', 'https://www.youtube.com/embed/example4'),
|
||||
('Building a Simple Robot', 'Create your first robot from scratch.', 'Electronics', 'https://www.youtube.com/embed/example5'),
|
||||
('Baking Artisan Bread', 'Master the art of baking bread at home.', 'Cooking', 'https://www.youtube.com/embed/example6');
|
||||
16
db/migrations/005_add_premium_features.sql
Normal file
16
db/migrations/005_add_premium_features.sql
Normal file
@ -0,0 +1,16 @@
|
||||
ALTER TABLE `users` ADD COLUMN `subscription_status` VARCHAR(50) NOT NULL DEFAULT 'free';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `subscriptions` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`user_id` INT NOT NULL,
|
||||
`plan` VARCHAR(50) NOT NULL,
|
||||
`start_date` DATETIME NOT NULL,
|
||||
`end_date` DATETIME NOT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
ALTER TABLE `skills` ADD COLUMN `is_premium` BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
-- Mark some existing skills as premium for demonstration
|
||||
UPDATE `skills` SET `is_premium` = TRUE WHERE `id` IN (2, 4, 5);
|
||||
320
index.php
320
index.php
@ -1,150 +1,182 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
@ini_set('display_errors', '1');
|
||||
@error_reporting(E_ALL);
|
||||
@date_default_timezone_set('UTC');
|
||||
|
||||
$phpVersion = PHP_VERSION;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
?>
|
||||
<!doctype html>
|
||||
<?php session_start(); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>New Style</title>
|
||||
<?php
|
||||
// Read project preview data from environment
|
||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
?>
|
||||
<?php if ($projectDescription): ?>
|
||||
<!-- Meta description -->
|
||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
||||
<!-- Open Graph meta tags -->
|
||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<!-- Twitter meta tags -->
|
||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
||||
<?php endif; ?>
|
||||
<?php if ($projectImageUrl): ?>
|
||||
<!-- Open Graph image -->
|
||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<!-- Twitter image -->
|
||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
||||
<?php endif; ?>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
||||
animation: bg-pan 20s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
@keyframes bg-pan {
|
||||
0% { background-position: 0% 0%; }
|
||||
100% { background-position: 100% 100%; }
|
||||
}
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.loader {
|
||||
margin: 1.25rem auto 1.25rem;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.hint {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
padding: 0; margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap; border: 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 1rem;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
code {
|
||||
background: rgba(0,0,0,0.2);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
}
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SunSkills - Learn Practical Skills for a Brighter Future</title>
|
||||
<meta name="description" content="SunSkills offers a clean, futuristic interface for streamlined professional development in design trends.">
|
||||
<meta name="keywords" content="online courses, skill development, practical skills, career growth, vocational training, hands-on learning, professional development, online learning">
|
||||
<meta property="og:title" content="SunSkills - Learn Practical Skills">
|
||||
<meta property="og:description" content="Join SunSkills to learn valuable, practical skills from local experts. Affordable, accessible, and designed for your career growth.">
|
||||
<meta property="og:image" content="https://project-screens.s3.amazonaws.com/screenshots/34681/app-hero-20251005-013825.png">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:image" content="https://project-screens.s3.amazonaws.com/screenshots/34681/app-hero-20251005-013825.png">
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
||||
</footer>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">SunSkills</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="#about">About</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#skills">Skills</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#testimonials">Testimonials</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="privacy.php">Privacy</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="hero">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 mx-auto">
|
||||
<h1>Learn Real Skills, Build Your Future</h1>
|
||||
<p class="lead">Affordable, practical courses from local experts to help you earn more and live better.</p>
|
||||
<a href="#skills" class="btn btn-primary btn-lg">Explore Skills</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section id="about" class="section">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-6">
|
||||
<h2>About SunSkills</h2>
|
||||
<p>We believe everyone deserves a chance to build a better future. SunSkills connects you with trusted local experts who teach practical, real-world skills. Whether you want to start a business, save money on repairs, or find a better job, our micro-learning courses are designed for your success.</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<img src="https://picsum.photos/seed/sunskills-about/800/600" class="img-fluid rounded-3" alt="A close-up of hands working on a detailed craft, representing practical skills.">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="skills" class="section bg-light">
|
||||
<div class="container">
|
||||
<h2 class="text-center mb-5">Featured Skills</h2>
|
||||
<div class="row">
|
||||
<!-- Skill 1 -->
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="https://picsum.photos/seed/sunskills-skill1/600/400" class="card-img-top" alt="A sample skill being taught, for example, bicycle repair.">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Basic Bicycle Repair</h5>
|
||||
<p class="card-text">Learn to fix common bike problems and save money on repairs.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Skill 2 -->
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="https://picsum.photos/seed/sunskills-skill2/600/400" class="card-img-top" alt="Smartphone photography skill.">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Smartphone Photography</h5>
|
||||
<p class="card-text">Take stunning photos with the camera in your pocket.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Skill 3 -->
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<img src="https://picsum.photos/seed/sunskills-skill3/600/400" class="card-img-top" alt="Home electrical basics skill.">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Home Electrical Basics</h5>
|
||||
<p class="card-text">Safely handle minor electrical tasks around the house.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="testimonials" class="section">
|
||||
<div class="container">
|
||||
<h2 class="text-center mb-5">What Our Learners Say</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="card-text">"I learned how to fix my own motorcycle! SunSkills saved me so much money. The instructor was a local mechanic and explained everything so clearly."</p>
|
||||
<footer class="blockquote-footer">Ravi, Tier 2 City</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="card-text">"The photography course was amazing. I started a small side-business taking photos for local shops. It's a great way to earn extra income."</p>
|
||||
<footer class="blockquote-footer">Priya, Small Town</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<p class="card-text">"Finally, a platform for skills that matter in my daily life. The subscription is so affordable. Highly recommended!"</p>
|
||||
<footer class="blockquote-footer">Amit, Village</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section bg-light">
|
||||
<div class="container">
|
||||
<h2 class="text-center mb-5">Get In Touch</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-8 mx-auto">
|
||||
<?php if (isset($_SESSION['success_message'])): ?>
|
||||
<div class="alert alert-success" role="alert">
|
||||
<?php echo $_SESSION['success_message']; unset($_SESSION['success_message']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION['error_message'])): ?>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<?php echo $_SESSION['error_message']; unset($_SESSION['error_message']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="card p-4">
|
||||
<form id="contactForm" action="contact.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Your Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Your Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="message" class="form-label">Message</label>
|
||||
<textarea class="form-control" id="message" name="message" rows="5" required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Send Message</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
128
login.php
Normal file
128
login.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
$errors = [];
|
||||
|
||||
// If user is already logged in, redirect to dashboard
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
header("Location: dashboard.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$email = trim($_POST['email']);
|
||||
$password = $_POST['password'];
|
||||
|
||||
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'A valid email is required.';
|
||||
}
|
||||
if (empty($password)) {
|
||||
$errors[] = 'Password is required.';
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
// Password is correct, start session
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['user_name'] = $user['name'];
|
||||
$_SESSION['subscription_status'] = $user['subscription_status'];
|
||||
header("Location: dashboard.php");
|
||||
exit;
|
||||
} else {
|
||||
$errors[] = "Invalid email or password.";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "Database error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login - SunSkills</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php">SunSkills</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#about">About</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#skills">Skills</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#testimonials">Testimonials</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#contact">Contact</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="register.php">Register</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="card-title text-center mb-4">Log In to Your Account</h1>
|
||||
|
||||
<?php if (isset($_SESSION['success_message'])): ?>
|
||||
<div class="alert alert-success">
|
||||
<?php echo $_SESSION['success_message']; unset($_SESSION['success_message']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<p class="mb-0"><?php echo $error; ?></p>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="login.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email Address</label>
|
||||
<input type="email" class="form-control" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="text-center mt-4">
|
||||
Don't have an account? <a href="register.php">Sign Up</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-light">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
22
logout.php
Normal file
22
logout.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
// Unset all of the session variables.
|
||||
$_SESSION = array();
|
||||
|
||||
// If it's desired to kill the session, also delete the session cookie.
|
||||
// Note: This will destroy the session, and not just the session data!
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
}
|
||||
|
||||
// Finally, destroy the session.
|
||||
session_destroy();
|
||||
|
||||
// Redirect to homepage with a logged out message
|
||||
header("Location: index.php");
|
||||
exit;
|
||||
87
pricing.php
Normal file
87
pricing.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php session_start(); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pricing - SunSkills</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php">SunSkills</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#about">About</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="dashboard.php">Skills</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#testimonials">Testimonials</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="text-center mb-5">
|
||||
<h2>Unlock Your Potential</h2>
|
||||
<p class="lead">Join 10,000+ skilled professionals who are building their future with SunSkills.</p>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<!-- Monthly Plan -->
|
||||
<div class="col-lg-4 col-md-6 mb-4">
|
||||
<div class="card h-100 text-center pricing-card">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h5 class="card-title">Monthly</h5>
|
||||
<h6 class="card-price">₹99<span class="text-muted">/month</span></h6>
|
||||
<ul class="list-unstyled mt-3 mb-4">
|
||||
<li><i class="bi bi-check-circle-fill"></i> Unlock 100+ skills</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Offline downloads</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Earn Certificates</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Ask Instructors Questions</li>
|
||||
</ul>
|
||||
<a href="subscribe.php?plan=monthly" class="btn btn-primary mt-auto">Start Learning</a>
|
||||
<small class="text-muted mt-2">Cancel anytime</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Yearly Plan -->
|
||||
<div class="col-lg-4 col-md-6 mb-4">
|
||||
<div class="card h-100 text-center pricing-card card-popular">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="popular-badge">BEST VALUE</div>
|
||||
<h5 class="card-title">Yearly</h5>
|
||||
<h6 class="card-price">₹999<span class="text-muted">/year</span></h6>
|
||||
<ul class="list-unstyled mt-3 mb-4">
|
||||
<li><i class="bi bi-check-circle-fill"></i> Unlock 100+ skills</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Offline downloads</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Earn Certificates</li>
|
||||
<li><i class="bi bi-check-circle-fill"></i> Ask Instructors Questions</li>
|
||||
</ul>
|
||||
<a href="subscribe.php?plan=yearly" class="btn btn-primary mt-auto">Start Learning</a>
|
||||
<small class="text-muted mt-2">Cancel anytime</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
13
privacy.php
Normal file
13
privacy.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php include '_header.php'; ?>
|
||||
|
||||
<div class="container section">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>Privacy Policy</h1>
|
||||
<p>This is a placeholder for the Privacy Policy page. Content will be added here soon.</p>
|
||||
<a href="index.php">Go back to Home</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include '_footer.php'; ?>
|
||||
151
quiz.php
Normal file
151
quiz.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
// If user is not logged in, redirect to login page
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$errors = [];
|
||||
$success_message = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$goal = $_POST['goal'] ?? '';
|
||||
$skill_level = $_POST['skill_level'] ?? '';
|
||||
$interests = $_POST['interests'] ?? [];
|
||||
|
||||
if (empty($goal) || empty($skill_level) || empty($interests)) {
|
||||
$errors[] = "Please answer all questions.";
|
||||
} else {
|
||||
$profile_data = [
|
||||
'goal' => $goal,
|
||||
'skill_level' => $skill_level,
|
||||
'interests' => $interests
|
||||
];
|
||||
$profile_json = json_encode($profile_data);
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("UPDATE users SET profile = ? WHERE id = ?");
|
||||
if ($stmt->execute([$profile_json, $user_id])) {
|
||||
$_SESSION['success_message'] = "Thank you! Your personalized recommendations are ready.";
|
||||
header("Location: dashboard.php");
|
||||
exit;
|
||||
} else {
|
||||
$errors[] = "Failed to save your preferences. Please try again.";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "Database error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Personalization Quiz - SunSkills</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php">SunSkills</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="card-title text-center mb-4">Tell Us About Yourself</h1>
|
||||
<p class="text-center text-muted mb-5">Help us tailor your learning experience.</p>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<p class="mb-0"><?php echo $error; ?></p>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="quiz.php" method="POST">
|
||||
<!-- Question 1: Goal -->
|
||||
<div class="mb-4">
|
||||
<p class="fw-bold">1. What is your primary goal?</p>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="goal" id="goal_earn" value="earn_money" required>
|
||||
<label class="form-check-label" for="goal_earn">Earn more money</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="goal" id="goal_business" value="start_business">
|
||||
<label class="form-check-label" for="goal_business">Start a business</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="goal" id="goal_hobby" value="learn_hobby">
|
||||
<label class="form-check-label" for="goal_hobby">Learn a new hobby</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Question 2: Skill Level -->
|
||||
<div class="mb-4">
|
||||
<p class="fw-bold">2. What is your current skill level in your area of interest?</p>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="skill_level" id="level_beginner" value="beginner" required>
|
||||
<label class="form-check-label" for="level_beginner">Beginner (Just starting out)</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="skill_level" id="level_intermediate" value="intermediate">
|
||||
<label class="form-check-label" for="level_intermediate">Intermediate (I have some experience)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Question 3: Interests -->
|
||||
<div class="mb-4">
|
||||
<p class="fw-bold">3. Which topics are you most interested in?</p>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="interests[]" id="interest_auto" value="auto">
|
||||
<label class="form-check-label" for="interest_auto">Automotive & Vehicle Repair</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="interests[]" id="interest_electronics" value="electronics">
|
||||
<label class="form-check-label" for="interest_electronics">Electronics & Gadgets</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="interests[]" id="interest_cooking" value="cooking">
|
||||
<label class="form-check-label" for="interest_cooking">Cooking & Culinary Skills</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="interests[]" id="interest_home" value="home">
|
||||
<label class="form-check-label" for="interest_home">Home Improvement</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Submit Answers</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-light">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
131
register.php
Normal file
131
register.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
$errors = [];
|
||||
$success_message = '';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$name = trim($_POST['name']);
|
||||
$email = trim($_POST['email']);
|
||||
$password = $_POST['password'];
|
||||
|
||||
if (empty($name)) {
|
||||
$errors[] = 'Name is required.';
|
||||
}
|
||||
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'A valid email is required.';
|
||||
}
|
||||
if (empty($password) || strlen($password) < 8) {
|
||||
$errors[] = 'Password must be at least 8 characters long.';
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
// Check if email already exists
|
||||
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
if ($stmt->fetch()) {
|
||||
$errors[] = 'An account with this email already exists.';
|
||||
} else {
|
||||
// Insert new user
|
||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
|
||||
|
||||
if ($stmt->execute([$name, $email, $hashed_password])) {
|
||||
$_SESSION['success_message'] = "Registration successful! Please log in.";
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
} else {
|
||||
$errors[] = "Registration failed. Please try again.";
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "Database error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Register - SunSkills</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light sticky-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php">SunSkills</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#about">About</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#skills">Skills</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#testimonials">Testimonials</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="index.php#contact">Contact</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="login.php">Login</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="card-title text-center mb-4">Create Your Account</h1>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<p class="mb-0"><?php echo $error; ?></p>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form action="register.php" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Full Name</label>
|
||||
<input type="text" class="form-control" id="name" name="name" required value="<?php echo isset($_POST['name']) ? htmlspecialchars($_POST['name']) : ''; ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email Address</label>
|
||||
<input type="email" class="form-control" id="email" name="email" required value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : ''; ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" id="password" name="password" required>
|
||||
<div class="form-text">Password must be at least 8 characters long.</div>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Register</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="text-center mt-4">
|
||||
Already have an account? <a href="login.php">Log In</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-light">
|
||||
<div class="container text-center">
|
||||
<p>© <?php echo date("Y"); ?> SunSkills. All Rights Reserved.</p>
|
||||
<p><a href="privacy.php">Privacy Policy</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
53
subscribe.php
Normal file
53
subscribe.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
// 1. Check if user is logged in
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 2. Get the plan from the URL
|
||||
$plan = $_GET['plan'] ?? null;
|
||||
if ($plan !== 'monthly' && $plan !== 'yearly') {
|
||||
// Redirect if plan is invalid
|
||||
header('Location: pricing.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$start_date = new DateTime();
|
||||
$end_date = new DateTime();
|
||||
|
||||
if ($plan === 'monthly') {
|
||||
$end_date->modify('+1 month');
|
||||
} elseif ($plan === 'yearly') {
|
||||
$end_date->modify('+1 year');
|
||||
}
|
||||
|
||||
$db = db();
|
||||
|
||||
// 3. Update user's subscription status
|
||||
$stmt_user = $db->prepare("UPDATE users SET subscription_status = 'premium' WHERE id = ?");
|
||||
$user_updated = $stmt_user->execute([$user_id]);
|
||||
|
||||
// 4. Create a record in the subscriptions table
|
||||
$stmt_sub = $db->prepare("INSERT INTO subscriptions (user_id, plan, start_date, end_date) VALUES (?, ?, ?, ?)");
|
||||
$subscription_created = $stmt_sub->execute([
|
||||
$user_id,
|
||||
$plan,
|
||||
$start_date->format('Y-m-d H:i:s'),
|
||||
$end_date->format('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
if ($user_updated && $subscription_created) {
|
||||
// 5. Update session and redirect with success message
|
||||
$_SESSION['subscription_status'] = 'premium';
|
||||
$_SESSION['success_message'] = 'Welcome to Premium! You now have access to all courses.';
|
||||
} else {
|
||||
$_SESSION['error_message'] = 'There was an error processing your subscription. Please try again.';
|
||||
}
|
||||
|
||||
header('Location: dashboard.php');
|
||||
exit();
|
||||
Loading…
x
Reference in New Issue
Block a user