diff --git a/auth/register_handler.php b/auth/register_handler.php
index 7ae50c1..9eabf02 100644
--- a/auth/register_handler.php
+++ b/auth/register_handler.php
@@ -1,4 +1,5 @@
prepare("INSERT INTO users (email, password, role) VALUES (?, ?, ?)");
- $stmt->execute([$email, $hashed_password, 'FREE_USER']);
+ $stmt->execute([$email, $hashed_password, 'free']);
- header('Location: /login.php?success=registered');
+ $new_user_id = $pdo->lastInsertId();
+
+ // Check for guest CV data and save it
+ if (isset($_SESSION['guest_cv_data'])) {
+ $cv_data = $_SESSION['guest_cv_data'];
+ $title = $cv_data['title'] ?? 'My CV';
+ $template_id = $cv_data['template_id'] ?? 1;
+ $content = json_encode([
+ 'personal_info' => $cv_data['personal_info'] ?? [],
+ 'experience' => array_values($cv_data['experience'] ?? []),
+ 'education' => array_values($cv_data['education'] ?? []),
+ 'skills' => $cv_data['skills'] ?? ''
+ ]);
+
+ $cv_stmt = $pdo->prepare('INSERT INTO cvs (user_id, title, content, template_id) VALUES (?, ?, ?, ?)');
+ $cv_stmt->execute([$new_user_id, $title, $content, $template_id]);
+
+ unset($_SESSION['guest_cv_data']);
+ }
+
+ // Log the user in automatically
+ $_SESSION['user_id'] = $new_user_id;
+ $_SESSION['user_email'] = $email;
+ $_SESSION['user_role'] = 'free'; // Default role
+
+ // Redirect to dashboard
+ header('Location: /dashboard.php');
exit;
} catch (PDOException $e) {
@@ -34,4 +61,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Location: /register.php?error=db_error');
exit;
}
-}
+}
\ No newline at end of file
diff --git a/cv_editor.php b/cv_editor.php
new file mode 100644
index 0000000..094f19c
--- /dev/null
+++ b/cv_editor.php
@@ -0,0 +1,178 @@
+query('SELECT id, name, is_premium FROM templates WHERE is_premium = 0');
+} else {
+ // Pro and Admin users can see all templates
+ $templates_stmt = $pdo->query('SELECT id, name, is_premium FROM templates');
+}
+$templates = $templates_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+$cv_data = [
+ 'id' => null,
+ 'title' => 'My CV',
+ 'content' => json_encode([
+ 'personal_info' => ['name' => '', 'email' => '', 'phone' => '', 'linkedin' => '' ],
+ 'experience' => [],
+ 'education' => [],
+ 'skills' => ''
+ ]),
+ 'template_id' => null
+];
+
+if (isset($_GET['id'])) {
+ $stmt = $pdo->prepare('SELECT * FROM cvs WHERE id = :id AND user_id = :user_id');
+ $stmt->execute(['id' => $_GET['id'], 'user_id' => $_SESSION['user_id']]);
+ $cv = $stmt->fetch(PDO::FETCH_ASSOC);
+ if ($cv) {
+ $cv_data = $cv;
+ }
+}
+
+$content = json_decode($cv_data['content'], true);
+require_once __DIR__ . '/includes/header.php';
+?>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dashboard.php b/dashboard.php
index d9effe1..638676b 100644
--- a/dashboard.php
+++ b/dashboard.php
@@ -8,16 +8,54 @@ if (!isset($_SESSION['user_id'])) {
}
require_once __DIR__ . '/includes/header.php';
+
+// Check for and display error messages
+if (isset($_SESSION['error_message'])) {
+ echo '' . htmlspecialchars($_SESSION['error_message']) . '
';
+ unset($_SESSION['error_message']); // Clear the message after displaying
+}
+
+// Check for and display success messages
+if (isset($_SESSION['success_message'])) {
+ echo '' . htmlspecialchars($_SESSION['success_message']) . '
';
+ unset($_SESSION['success_message']); // Clear the message after displaying
+}
?>
Welcome to Your Dashboard
-
Your role:
+
Your role:
Your CVs
-
You don't have any CVs yet.
-
Create a New CV
+ prepare('SELECT id, title, updated_at FROM cvs WHERE user_id = :user_id ORDER BY updated_at DESC');
+ $stmt->execute(['user_id' => $_SESSION['user_id']]);
+ $cvs = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+ if ($cvs):
+ ?>
+
+
+
+
+
+ Last updated:
+
+
+
+
+
+
+
You don't have any CVs yet. Let's create one!
+
+
Create a New CV
Logout
diff --git a/db/migrations/002_add_templates.sql b/db/migrations/002_add_templates.sql
new file mode 100644
index 0000000..1e65199
--- /dev/null
+++ b/db/migrations/002_add_templates.sql
@@ -0,0 +1,14 @@
+CREATE TABLE IF NOT EXISTS `templates` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `name` VARCHAR(255) NOT NULL,
+ `description` TEXT,
+ `file_path` VARCHAR(255) NOT NULL,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+ALTER TABLE `cvs` ADD COLUMN `template_id` INT NULL;
+
+-- Insert some default templates
+INSERT INTO `templates` (`name`, `description`, `file_path`) VALUES
+('Minimalist', 'A clean and simple template.', 'minimalist.php'),
+('Professional', 'A classic and professional template.', 'professional.php');
diff --git a/db/migrations/003_add_roles_and_premium_templates.sql b/db/migrations/003_add_roles_and_premium_templates.sql
new file mode 100644
index 0000000..565c2f6
--- /dev/null
+++ b/db/migrations/003_add_roles_and_premium_templates.sql
@@ -0,0 +1,8 @@
+-- Add role to users table
+ALTER TABLE `users` ADD `role` VARCHAR(50) NOT NULL DEFAULT 'free';
+
+-- Add is_premium to templates table
+ALTER TABLE `templates` ADD `is_premium` BOOLEAN NOT NULL DEFAULT FALSE;
+
+-- Set the "Professional" template as premium for demonstration
+UPDATE `templates` SET `is_premium` = TRUE WHERE `name` = 'Professional';
diff --git a/delete_cv.php b/delete_cv.php
new file mode 100644
index 0000000..4bf851e
--- /dev/null
+++ b/delete_cv.php
@@ -0,0 +1,45 @@
+prepare("SELECT user_id FROM cvs WHERE id = ?");
+ $stmt->execute([$cv_id]);
+ $cv = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if (!$cv || $cv['user_id'] != $user_id) {
+ // CV not found or does not belong to the user
+ header('Location: dashboard.php?error=CV not found or permission denied.');
+ exit();
+ }
+
+ // Delete the CV
+ $stmt = $pdo->prepare("DELETE FROM cvs WHERE id = ? AND user_id = ?");
+ $stmt->execute([$cv_id, $user_id]);
+
+ header('Location: dashboard.php?success=CV deleted successfully.');
+ exit();
+
+} catch (PDOException $e) {
+ // Log error and redirect
+ error_log("CV Deletion Error: " . $e->getMessage());
+ header('Location: dashboard.php?error=An error occurred while deleting the CV.');
+ exit();
+}
+?>
\ No newline at end of file
diff --git a/includes/header.php b/includes/header.php
index 2b5aab6..2a8210b 100644
--- a/includes/header.php
+++ b/includes/header.php
@@ -1,21 +1,36 @@
+
-
MagiCV
+
+
-
+
\ No newline at end of file
diff --git a/payment_handler.php b/payment_handler.php
new file mode 100644
index 0000000..6770746
--- /dev/null
+++ b/payment_handler.php
@@ -0,0 +1,27 @@
+prepare($sql);
+
+if ($stmt->execute([$user_id])) {
+ // Update role in session
+ $_SESSION['role'] = 'pro';
+ $_SESSION['success_message'] = "Congratulations! You have successfully upgraded to the PRO plan.";
+} else {
+ $_SESSION['error_message'] = "Something went wrong during the upgrade. Please try again.";
+}
+
+header('Location: dashboard.php');
+exit();
diff --git a/public/css/style.css b/public/css/style.css
index 3e1582d..a3b36bb 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -16,6 +16,15 @@ main {
padding: 2rem;
}
+.container {
+ max-width: 800px;
+ margin: 2rem auto;
+ padding: 2rem;
+ background: #fff;
+ border: 1px solid #eaeaea;
+ border-radius: 8px;
+}
+
/* Header and Navigation */
header {
background: #fff;
@@ -140,22 +149,27 @@ footer {
margin-bottom: 0.5rem;
}
-.form-group input {
+.form-group input, .form-group textarea {
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 5px;
}
-.auth-container .button {
- width: 100%;
- padding: 0.75rem;
+.button {
+ display: inline-block;
+ padding: 0.75rem 1.5rem;
border: none;
border-radius: 5px;
background-color: #6c63ff;
color: #fff;
font-size: 1rem;
cursor: pointer;
+ text-decoration: none;
+}
+
+.auth-container .button {
+ width: 100%;
}
.auth-container p {
@@ -163,9 +177,135 @@ footer {
margin-top: 1rem;
}
+.auth-container .error {
+ color: #c53030;
+ background-color: #fed7d7;
+ padding: 0.75rem;
+ border-radius: 5px;
+ margin-bottom: 1rem;
+ text-align: center;
+}
+
/* Dashboard */
.dashboard-container {
max-width: 800px;
margin: 2rem auto;
padding: 2rem;
}
+
+/* CV List */
+.cv-list {
+ list-style: none;
+ margin-top: 1.5rem;
+}
+
+.cv-list li {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 1rem;
+ padding: 1rem;
+ background: #fff;
+ border: 1px solid #eaeaea;
+ border-radius: 5px;
+ transition: box-shadow 0.3s;
+}
+
+.cv-list li:hover {
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+}
+
+.cv-item strong {
+ font-size: 1.2rem;
+ display: block;
+ margin-bottom: 0.25rem;
+}
+
+.cv-item span {
+ font-size: 0.9rem;
+ color: #777;
+}
+
+.cv-actions {
+ display: flex;
+ gap: 0.5rem;
+}
+
+.button-sm {
+ padding: 0.4rem 0.8rem;
+ font-size: 0.9rem;
+ text-decoration: none;
+ border-radius: 4px;
+ color: #fff;
+ background-color: #6c63ff;
+}
+
+.button-danger {
+ background-color: #e53e3e;
+}
+
+.cv-list a {
+ text-decoration: none;
+ color: #333;
+}
+
+
+/* CV Editor */
+#cv-form fieldset {
+ border: 1px solid #eaeaea;
+ padding: 1.5rem;
+ border-radius: 8px;
+ margin-bottom: 1.5rem;
+}
+
+#cv-form legend {
+ font-weight: bold;
+ padding: 0 0.5rem;
+ margin-left: 1rem;
+}
+
+.experience-item, .education-item {
+ margin-bottom: 1rem;
+ padding: 1rem;
+ border: 1px solid #f0f0f0;
+ border-radius: 5px;
+}
+
+#add-experience, #add-education {
+ margin-top: 1rem;
+ background: none;
+ border: 1px dashed #ccc;
+ color: #555;
+ padding: 0.5rem 1rem;
+ cursor: pointer;
+}
+
+/* Banners */
+.error-banner {
+ background-color: #fed7d7;
+ color: #c53030;
+ padding: 1rem;
+ border: 1px solid #fbcaca;
+ border-radius: 5px;
+ margin-bottom: 1.5rem;
+ text-align: center;
+}
+.auth-container .info {
+ color: #004085;
+ background-color: #cce5ff;
+ padding: 0.75rem;
+ border-radius: 5px;
+ margin-bottom: 1rem;
+ text-align: center;
+}
+
+.success-banner {
+ background-color: #d4edda;
+ color: #155724;
+ padding: 1rem;
+ border: 1px solid #c3e6cb;
+ border-radius: 5px;
+ margin-bottom: 1.5rem;
+ text-align: center;
+}
+
diff --git a/register.php b/register.php
index b9645c0..492923a 100644
--- a/register.php
+++ b/register.php
@@ -1,9 +1,16 @@
Create Your Account
+
+
+
+
+
+
+?>
\ No newline at end of file
diff --git a/save_cv.php b/save_cv.php
new file mode 100644
index 0000000..a868344
--- /dev/null
+++ b/save_cv.php
@@ -0,0 +1,75 @@
+prepare("SELECT COUNT(*) FROM cvs WHERE user_id = ?");
+ $stmt->execute([$user_id]);
+ $cv_count = $stmt->fetchColumn();
+
+ if ($cv_count >= 2) {
+ // Limit reached for free users
+ $_SESSION['error_message'] = 'You have reached the maximum of 2 CVs for the Free Plan. Please upgrade to create more.';
+ header('Location: /dashboard.php');
+ exit;
+ }
+ }
+
+ $content = json_encode([
+ 'personal_info' => $_POST['personal_info'] ?? [],
+ 'experience' => array_values($_POST['experience'] ?? []),
+ 'education' => array_values($_POST['education'] ?? []),
+ 'skills' => $_POST['skills'] ?? ''
+ ]);
+
+ if ($cv_id) {
+ // Update existing CV
+ $stmt = $pdo->prepare('UPDATE cvs SET title = :title, content = :content, template_id = :template_id, updated_at = NOW() WHERE id = :id AND user_id = :user_id');
+ $stmt->execute([
+ 'id' => $cv_id,
+ 'user_id' => $user_id,
+ 'title' => $title,
+ 'content' => $content,
+ 'template_id' => $template_id
+ ]);
+ } else {
+ // Insert new CV
+ $stmt = $pdo->prepare('INSERT INTO cvs (user_id, title, content, template_id) VALUES (:user_id, :title, :content, :template_id)');
+ $stmt->execute([
+ 'user_id' => $user_id,
+ 'title' => $title,
+ 'content' => $content,
+ 'template_id' => $template_id
+ ]);
+ }
+
+ header('Location: /dashboard.php');
+ exit;
+} else {
+ // Not a POST request
+ header('Location: /dashboard.php');
+ exit;
+}
\ No newline at end of file
diff --git a/templates/minimalist.php b/templates/minimalist.php
new file mode 100644
index 0000000..b527cf4
--- /dev/null
+++ b/templates/minimalist.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+
CV:
+
+
+
+
+
+ name); ?>
+ email); ?> | phone); ?>
+
+
+
Work Experience
+
experience)); ?>
+
+
+
Education
+
education)); ?>
+
+
+
Skills
+
skills)); ?>
+
+
+
+
diff --git a/templates/professional.php b/templates/professional.php
new file mode 100644
index 0000000..0bf6244
--- /dev/null
+++ b/templates/professional.php
@@ -0,0 +1,39 @@
+
+
+
+
+
+
CV:
+
+
+
+
+
+
+
Work Experience
+
experience)); ?>
+
+
+
Education
+
education)); ?>
+
+
+
Skills
+
skills)); ?>
+
+
+
+
diff --git a/templates_preview.php b/templates_preview.php
new file mode 100644
index 0000000..3e3b5ec
--- /dev/null
+++ b/templates_preview.php
@@ -0,0 +1,39 @@
+query("SELECT * FROM templates ORDER BY name");
+$templates = $stmt->fetchAll();
+?>
+
+
+ CV Templates
+ Browse our library of professionally designed templates. Sign up to use them!
+
+
+
+
+
+
+
+
+
+
+ PRO
+
+ FREE
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/upgrade.php b/upgrade.php
new file mode 100644
index 0000000..2940f9f
--- /dev/null
+++ b/upgrade.php
@@ -0,0 +1,33 @@
+
+
+
+
+
Upgrade to PRO
+
Unlock premium features and take your CV to the next level.
+
+
+
PRO Plan Benefits:
+
+ Unlimited CVs
+ Access to all premium templates
+ Priority Support
+
+
+
+
+ Click the button below to simulate the upgrade process.
+ Upgrade Now for $10 (Simulated)
+
+
+
+
+
diff --git a/view_cv.php b/view_cv.php
new file mode 100644
index 0000000..f90c951
--- /dev/null
+++ b/view_cv.php
@@ -0,0 +1,72 @@
+prepare("SELECT * FROM cvs WHERE id = ? AND user_id = ?");
+$stmt->execute([$cv_id, $user_id]);
+$cv = $stmt->fetch();
+
+if (!$cv) {
+ header('Location: dashboard.php');
+ exit();
+}
+
+// Fetch the template
+$template_path = null;
+if (!empty($cv['template_id'])) {
+ $stmt = $pdo->prepare("SELECT file_path FROM templates WHERE id = ?");
+ $stmt->execute([$cv['template_id']]);
+ $template = $stmt->fetch();
+ if ($template && file_exists(__DIR__ . '/templates/' . $template['file_path'])) {
+ $template_path = __DIR__ . '/templates/' . $template['file_path'];
+ }
+}
+
+// If a template is found, render it. Otherwise, fall back to a default view.
+if ($template_path) {
+ // The template file will have access to the $cv variable.
+ require_once $template_path;
+} else {
+ // Default view if no template is set or found
+ $cv_data = json_decode($cv['content'], true);
+?>
+
+
+
+
+
+
View CV:
+
+
+
+
+
+
Name:
+
Email:
+
+
Work Experience
+
+
Education
+
+
Skills
+
+
Back to Dashboard
+
+
+
+