This commit is contained in:
Flatlogic Bot 2025-09-17 12:13:33 +00:00
parent 05d192f46f
commit 7a4a20350d
16 changed files with 810 additions and 17 deletions

View File

@ -1,4 +1,5 @@
<?php
session_start();
require_once __DIR__ . '/../db/config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
@ -24,9 +25,35 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Insert new user
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->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;
}
}
}

178
cv_editor.php Normal file
View File

@ -0,0 +1,178 @@
<?php
session_start();
require_once __DIR__ . '/db/config.php';
$is_guest = !isset($_SESSION['user_id']);
// If a guest tries to edit a CV, redirect them to login.
if ($is_guest && isset($_GET['id'])) {
$_SESSION['error_message'] = 'You must be logged in to edit a CV.';
header('Location: /login.php');
exit;
}
$pdo = db();
$user_role = $_SESSION['user_role'] ?? 'free';
// Fetch templates based on user role
if ($user_role === 'free') {
$templates_stmt = $pdo->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';
?>
<div class="container">
<h2><?php echo $cv_data['id'] ? 'Edit CV' : 'Create New CV'; ?></h2>
<form action="/save_cv.php" method="post" id="cv-form">
<input type="hidden" name="cv_id" value="<?php echo $cv_data['id']; ?>">
<div class="form-group">
<label for="title">CV Title</label>
<input type="text" name="title" id="title" value="<?php echo htmlspecialchars($cv_data['title']); ?>" required>
</div>
<div class="form-group">
<label for="template_id">Template</label>
<select name="template_id" id="template_id">
<?php foreach ($templates as $template): ?>
<option value="<?php echo $template['id']; ?>" <?php echo ($cv_data['template_id'] == $template['id']) ? 'selected' : ''; ?>>
<?php
echo htmlspecialchars($template['name']);
if ($template['is_premium']) {
echo ' (Pro)';
}
?>
</option>
<?php endforeach; ?>
</select>
</div>
<fieldset>
<legend>Personal Information</legend>
<div class="form-group">
<label for="name">Full Name</label>
<input type="text" name="personal_info[name]" id="name" value="<?php echo htmlspecialchars($content['personal_info']['name'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="personal_info[email]" id="email" value="<?php echo htmlspecialchars($content['personal_info']['email'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input type="text" name="personal_info[phone]" id="phone" value="<?php echo htmlspecialchars($content['personal_info']['phone'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="linkedin">LinkedIn Profile</label>
<input type="text" name="personal_info[linkedin]" id="linkedin" value="<?php echo htmlspecialchars($content['personal_info']['linkedin'] ?? ''); ?>">
</div>
</fieldset>
<fieldset>
<legend>Work Experience</legend>
<div id="experience-container">
<?php if (!empty($content['experience'])):
foreach ($content['experience'] as $index => $exp):
?>
<div class="experience-item">
<input type="text" name="experience[<?php echo $index; ?>][title]" placeholder="Job Title" value="<?php echo htmlspecialchars($exp['title'] ?? ''); ?>">
<input type="text" name="experience[<?php echo $index; ?>][company]" placeholder="Company" value="<?php echo htmlspecialchars($exp['company'] ?? ''); ?>">
<textarea name="experience[<?php echo $index; ?>][description]" placeholder="Description"><?php echo htmlspecialchars($exp['description'] ?? ''); ?></textarea>
</div>
<?php
endforeach;
endif;
?>
</div>
<button type="button" id="add-experience">Add Experience</button>
</fieldset>
<fieldset>
<legend>Education</legend>
<div id="education-container">
<?php if (!empty($content['education'])):
foreach ($content['education'] as $index => $edu):
?>
<div class="education-item">
<input type="text" name="education[<?php echo $index; ?>][degree]" placeholder="Degree" value="<?php echo htmlspecialchars($edu['degree'] ?? ''); ?>">
<input type="text" name="education[<?php echo $index; ?>][institution]" placeholder="Institution" value="<?php echo htmlspecialchars($edu['institution'] ?? ''); ?>">
</div>
<?php
endforeach;
endif;
?>
</div>
<button type="button" id="add-education">Add Education</button>
</fieldset>
<fieldset>
<legend>Skills</legend>
<div class="form-group">
<textarea name="skills" id="skills" placeholder="e.g., PHP, JavaScript, Project Management"><?php echo htmlspecialchars($content['skills'] ?? ''); ?></textarea>
</div>
</fieldset>
<button type="submit" class="button">Save CV</button>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
let experienceIndex = <?php echo count($content['experience'] ?? []); ?>;
document.getElementById('add-experience').addEventListener('click', function() {
const container = document.getElementById('experience-container');
const newItem = document.createElement('div');
newItem.className = 'experience-item';
newItem.innerHTML = `
<input type="text" name="experience[${experienceIndex}][title]" placeholder="Job Title">
<input type="text" name="experience[${experienceIndex}][company]" placeholder="Company">
<textarea name="experience[${experienceIndex}][description]" placeholder="Description"></textarea>
`;
container.appendChild(newItem);
experienceIndex++;
});
let educationIndex = <?php echo count($content['education'] ?? []); ?>;
document.getElementById('add-education').addEventListener('click', function() {
const container = document.getElementById('education-container');
const newItem = document.createElement('div');
newItem.className = 'education-item';
newItem.innerHTML = `
<input type="text" name="education[${educationIndex}][degree]" placeholder="Degree">
<input type="text" name="education[${educationIndex}][institution]" placeholder="Institution">
`;
container.appendChild(newItem);
educationIndex++;
});
});
</script>
<?php
require_once __DIR__ . '/includes/footer.php';
?>

View File

@ -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 '<div class="error-banner"><p>' . htmlspecialchars($_SESSION['error_message']) . '</p></div>';
unset($_SESSION['error_message']); // Clear the message after displaying
}
// Check for and display success messages
if (isset($_SESSION['success_message'])) {
echo '<div class="success-banner"><p>' . htmlspecialchars($_SESSION['success_message']) . '</p></div>';
unset($_SESSION['success_message']); // Clear the message after displaying
}
?>
<div class="dashboard-container">
<h2>Welcome to Your Dashboard</h2>
<p>Your role: <?php echo htmlspecialchars($_SESSION['user_role']); ?></p>
<p>Your role: <strong><?php echo htmlspecialchars($_SESSION['role']); ?></strong></p>
<div class="cv-management">
<h3>Your CVs</h3>
<p>You don't have any CVs yet.</p>
<a href="/create_cv.php" class="button">Create a New CV</a>
<?php
require_once __DIR__ . '/db/config.php';
$pdoconn = db();
$stmt = $pdoconn->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):
?>
<ul class="cv-list">
<?php foreach ($cvs as $cv): ?>
<li>
<div class="cv-item">
<strong><?php echo htmlspecialchars($cv['title']); ?></strong>
<span>Last updated: <?php echo date('F j, Y', strtotime($cv['updated_at'])); ?></span>
</div>
<div class="cv-actions">
<a href="view_cv.php?id=<?php echo $cv['id']; ?>" class="button-sm">View</a>
<a href="cv_editor.php?id=<?php echo $cv['id']; ?>" class="button-sm">Edit</a>
<a href="delete_cv.php?id=<?php echo $cv['id']; ?>" class="button-sm button-danger" onclick="return confirm('Are you sure you want to delete this CV?');">Delete</a>
</div>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>You don't have any CVs yet. Let's create one!</p>
<?php endif; ?>
<a href="/cv_editor.php" class="button">Create a New CV</a>
</div>
<a href="/logout.php">Logout</a>

View File

@ -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');

View File

@ -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';

45
delete_cv.php Normal file
View File

@ -0,0 +1,45 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
header('Location: dashboard.php?error=Invalid CV ID');
exit();
}
$cv_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
try {
$pdo = db();
// First, verify the CV belongs to the current user
$stmt = $pdo->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();
}
?>

View File

@ -1,21 +1,36 @@
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MagiCV</title>
<title><?php echo isset($pageTitle) ? $pageTitle . ' - MagiCV' : 'MagiCV'; ?></title>
<link rel="stylesheet" href="/public/css/style.css?v=<?php echo time(); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<header>
<nav>
<a href="/" class="logo">MagiCV</a>
<ul>
<li><a href="/#templates">Templates</a></li>
<li><a href="/#features">Features</a></li>
<li><a href="/login.php">Login</a></li>
<li><a href="/register.php" class="button">Sign Up</a></li>
<?php if (isset($_SESSION['user_id'])): ?>
<li><a href="/dashboard.php">Dashboard</a></li>
<li><a href="/templates_preview.php">Templates</a></li>
<?php if (isset($_SESSION['role']) && $_SESSION['role'] == 'free'): ?>
<li><a href="/upgrade.php" class="button-secondary">Upgrade to PRO</a></li>
<?php endif; ?>
<li><a href="/logout.php">Logout</a></li>
<?php else: ?>
<li><a href="/templates_preview.php">Templates</a></li>
<li><a href="/#features">Features</a></li>
<li><a href="/login.php">Login</a></li>
<li><a href="/register.php" class="button">Sign Up</a></li>
<?php endif; ?>
</ul>
</nav>
</header>
<main>
<main>

27
payment_handler.php Normal file
View File

@ -0,0 +1,27 @@
<?php
session_start();
require 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
$user_id = $_SESSION['user_id'];
// Simulate a successful payment
// Update user role to 'pro'
$sql = "UPDATE users SET role = 'pro' WHERE id = ?";
$stmt = $pdo->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();

View File

@ -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;
}

View File

@ -1,9 +1,16 @@
<?php
session_start();
require_once __DIR__ . '/includes/header.php';
?>
<div class="auth-container">
<h2>Create Your Account</h2>
<?php if (isset($_SESSION['info_message'])): ?>
<p class="info"><?php echo $_SESSION['info_message']; ?></p>
<?php unset($_SESSION['info_message']); ?>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<p class="error">
<?php
@ -40,4 +47,4 @@ require_once __DIR__ . '/includes/header.php';
<?php
require_once __DIR__ . '/includes/footer.php';
?>
?>

75
save_cv.php Normal file
View File

@ -0,0 +1,75 @@
<?php
session_start();
require_once __DIR__ . '/db/config.php';
// If user is not logged in, store CV data in session and redirect to register
if (!isset($_SESSION['user_id'])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['guest_cv_data'] = $_POST;
$_SESSION['info_message'] = 'Create an account to save your CV.';
header('Location: /register.php');
exit;
} else {
// Not a POST request and not logged in
header('Location: /login.php');
exit;
}
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo = db();
$user_id = $_SESSION['user_id'];
$user_role = $_SESSION['user_role'] ?? 'free';
$cv_id = $_POST['cv_id'] ?? null;
$title = $_POST['title'] ?? 'My CV';
$template_id = $_POST['template_id'] ?? 1; // Default to template 1
// --- Role-based Limitation ---
if (empty($cv_id) && $user_role === 'free') {
$stmt = $pdo->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;
}

36
templates/minimalist.php Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CV: <?php echo htmlspecialchars($cv['title']); ?></title>
<style>
body { font-family: sans-serif; line-height: 1.6; }
.cv-container { max-width: 800px; margin: auto; padding: 20px; }
h1, h2, h3 { margin-bottom: 0.5em; }
h1 { font-size: 2.5em; }
h2 { font-size: 1.8em; border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 1.5em;}
.section { margin-bottom: 1.5em; }
</style>
</head>
<body>
<div class="cv-container">
<header class="section">
<h1><?php echo htmlspecialchars(json_decode($cv['content'])->name); ?></h1>
<p><?php echo htmlspecialchars(json_decode($cv['content'])->email); ?> | <?php echo htmlspecialchars(json_decode($cv['content'])->phone); ?></p>
</header>
<div class="section">
<h2>Work Experience</h2>
<p><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->experience)); ?></p>
</div>
<div class="section">
<h2>Education</h2>
<p><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->education)); ?></p>
</div>
<div class="section">
<h2>Skills</h2>
<p><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->skills)); ?></p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CV: <?php echo htmlspecialchars($cv['title']); ?></title>
<style>
body { font-family: 'Times New Roman', Times, serif; line-height: 1.4; }
.cv-container { max-width: 800px; margin: auto; padding: 30px; border: 1px solid #ccc; }
h1, h2, h3 { margin-bottom: 0.5em; }
h1 { text-align: center; font-size: 2.8em; text-transform: uppercase; letter-spacing: 2px;}
h2 { font-size: 1.5em; border-bottom: 2px solid #333; padding-bottom: 5px; margin-top: 2em;}
.contact-info { text-align: center; margin-bottom: 2em; }
.section { margin-bottom: 1.5em; }
</style>
</head>
<body>
<div class="cv-container">
<header class="section">
<h1><?php echo htmlspecialchars(json_decode($cv['content'])->name); ?></h1>
<div class="contact-info">
<p><?php echo htmlspecialchars(json_decode($cv['content'])->email); ?> | <?php echo htmlspecialchars(json_decode($cv['content'])->phone); ?></p>
</div>
</header>
<div class="section">
<h2>Work Experience</h2>
<div><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->experience)); ?></div>
</div>
<div class="section">
<h2>Education</h2>
<div><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->education)); ?></div>
</div>
<div class="section">
<h2>Skills</h2>
<div><?php echo nl2br(htmlspecialchars(json_decode($cv['content'])->skills)); ?></div>
</div>
</div>
</body>
</html>

39
templates_preview.php Normal file
View File

@ -0,0 +1,39 @@
<?php
require_once __DIR__ . '/includes/header.php';
require_once __DIR__ . '/db/config.php';
$pdo = db();
$stmt = $pdo->query("SELECT * FROM templates ORDER BY name");
$templates = $stmt->fetchAll();
?>
<main class="container">
<h1 class="text-center my-4">CV Templates</h1>
<p class="text-center text-muted mb-5">Browse our library of professionally designed templates. <a href="/register.php">Sign up</a> to use them!</p>
<div class="row">
<?php foreach ($templates as $template): ?>
<div class="col-md-6 col-lg-4 mb-4">
<div class="card h-100">
<img src="https://picsum.photos/seed/<?php echo htmlspecialchars($template['file_path']); ?>/400/500" class="card-img-top" alt="<?php echo htmlspecialchars($template['name']); ?>">
<div class="card-body">
<h5 class="card-title d-flex justify-content-between align-items-center">
<?php echo htmlspecialchars($template['name']); ?>
<?php if ($template['is_premium']): ?>
<span class="badge bg-warning text-dark">PRO</span>
<?php else: ?>
<span class="badge bg-success">FREE</span>
<?php endif; ?>
</h5>
<p class="card-text"><?php echo htmlspecialchars($template['description'] ?? 'A great template for your CV.'); ?></p>
</div>
<div class="card-footer text-center">
<a href="/register.php" class="btn btn-primary">Use this Template</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</main>
<?php require_once __DIR__ . '/includes/footer.php'; ?>

33
upgrade.php Normal file
View File

@ -0,0 +1,33 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
$pageTitle = "Upgrade to PRO";
include 'includes/header.php';
?>
<div class="container">
<div class="auth-container">
<h2>Upgrade to PRO</h2>
<p>Unlock premium features and take your CV to the next level.</p>
<div class="pro-features">
<h3>PRO Plan Benefits:</h3>
<ul>
<li><i class="fas fa-check-circle"></i> Unlimited CVs</li>
<li><i class="fas fa-star"></i> Access to all premium templates</li>
<li><i class="fas fa-headset"></i> Priority Support</li>
</ul>
</div>
<form action="payment_handler.php" method="POST">
<p>Click the button below to simulate the upgrade process.</p>
<button type="submit" class="button">Upgrade Now for $10 (Simulated)</button>
</form>
</div>
</div>
<?php include 'includes/footer.php'; ?>

72
view_cv.php Normal file
View File

@ -0,0 +1,72 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
require_once 'db/config.php';
if (!isset($_GET['id'])) {
header('Location: dashboard.php');
exit();
}
$cv_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
$stmt = $pdo->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);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View CV: <?php echo htmlspecialchars($cv['title']); ?></title>
<link rel="stylesheet" href="public/css/style.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="container">
<h1><?php echo htmlspecialchars($cv['title']); ?></h1>
<p><strong>Name:</strong> <?php echo htmlspecialchars($cv_data['personal_info']['name'] ?? 'N/A'); ?></p>
<p><strong>Email:</strong> <?php echo htmlspecialchars($cv_data['personal_info']['email'] ?? 'N/A'); ?></p>
<hr>
<h2>Work Experience</h2>
<div><?php echo nl2br(htmlspecialchars(json_encode($cv_data['experience'] ?? []))); ?></div>
<h2>Education</h2>
<div><?php echo nl2br(htmlspecialchars(json_encode($cv_data['education'] ?? []))); ?></div>
<h2>Skills</h2>
<p><?php echo nl2br(htmlspecialchars($cv_data['skills'] ?? '')); ?></p>
<a href="/dashboard.php">Back to Dashboard</a>
</div>
</body>
</html>
<?php
}