3
This commit is contained in:
parent
bfa71e661d
commit
97cbe8f10f
@ -142,6 +142,10 @@ a:hover { color: var(--color-secondary); }
|
||||
padding: 0.5rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.language-switcher:hover .selected-lang {
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
.selected-lang img {
|
||||
width: 20px;
|
||||
@ -155,32 +159,50 @@ a:hover { color: var(--color-secondary); }
|
||||
.icon-sm {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
.language-switcher:hover .icon-sm {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.lang-dropdown {
|
||||
display: none;
|
||||
display: block; /* Use opacity and visibility for animation */
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
top: calc(100% + 0.5rem);
|
||||
right: 0;
|
||||
background-color: var(--surface-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
min-width: 120px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.1);
|
||||
min-width: 150px;
|
||||
z-index: 10;
|
||||
|
||||
/* Animation */
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
|
||||
}
|
||||
.language-switcher:hover .lang-dropdown {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.lang-dropdown a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
gap: 0.75rem;
|
||||
padding: 0.6rem 0.8rem;
|
||||
border-radius: calc(var(--border-radius) / 2);
|
||||
color: var(--text-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
.lang-dropdown a:hover, .lang-dropdown a.active {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.lang-dropdown a.active {
|
||||
font-weight: 600;
|
||||
}
|
||||
.lang-dropdown a img {
|
||||
width: 20px;
|
||||
@ -189,6 +211,67 @@ a:hover { color: var(--color-secondary); }
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* --- User Menu --- */
|
||||
.user-menu {
|
||||
position: relative;
|
||||
}
|
||||
.user-menu-toggle {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
border-radius: 50px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
.user-menu:hover .user-menu-toggle {
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
.avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--border-color);
|
||||
}
|
||||
.user-menu .icon-sm {
|
||||
color: var(--text-color);
|
||||
}
|
||||
.user-dropdown {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc(100% + 0.5rem);
|
||||
right: 0;
|
||||
background-color: var(--surface-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.1);
|
||||
min-width: 160px;
|
||||
z-index: 10;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
|
||||
}
|
||||
.user-menu:hover .user-dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.user-dropdown a {
|
||||
display: block;
|
||||
padding: 0.6rem 1rem;
|
||||
color: var(--text-color);
|
||||
border-radius: calc(var(--border-radius) / 2);
|
||||
}
|
||||
.user-dropdown a:hover {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* --- Theme Switch --- */
|
||||
.theme-switch-wrapper { display: flex; align-items: center; }
|
||||
.theme-switch { position: relative; display: inline-block; width: 50px; height: 26px; }
|
||||
@ -533,3 +616,110 @@ input:checked + .slider:before { transform: translateX(24px); }
|
||||
.terms-content ul, .terms-content ol {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
/* --- Generator Form --- */
|
||||
.generator-section {
|
||||
padding: calc(var(--base-spacing) * 3) 0;
|
||||
background-color: var(--surface-color);
|
||||
}
|
||||
.generator-form {
|
||||
background-color: var(--bg-color);
|
||||
padding: calc(var(--base-spacing) * 2);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: calc(var(--base-spacing) * 2);
|
||||
margin-bottom: calc(var(--base-spacing) * 2);
|
||||
}
|
||||
.form-column-wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.generator-form .form-group label {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: var(--subtle-text-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.generator-form input[type="text"],
|
||||
.generator-form input[type="number"],
|
||||
.generator-form textarea,
|
||||
.generator-form select {
|
||||
width: 100%;
|
||||
padding: 0.8rem 1rem;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--surface-color);
|
||||
color: var(--text-color);
|
||||
font-family: var(--font-family-body);
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.generator-form input:focus,
|
||||
.generator-form textarea:focus,
|
||||
.generator-form select:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 0 0 4px rgba(108, 99, 255, 0.2);
|
||||
}
|
||||
.generator-form select {
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%236c757d' class='bi bi-chevron-down' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 1rem center;
|
||||
background-size: 1em;
|
||||
}
|
||||
.form-submit-group {
|
||||
text-align: center;
|
||||
margin-top: calc(var(--base-spacing) * 2);
|
||||
}
|
||||
.cta-button {
|
||||
background: var(--gradient);
|
||||
color: white;
|
||||
padding: 1rem 2.5rem;
|
||||
border-radius: 50px;
|
||||
font-weight: 700;
|
||||
font-family: var(--font-family-headings);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.cta-button:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* --- Hero Section --- */
|
||||
.hero {
|
||||
background: var(--gradient);
|
||||
padding: 6rem 0;
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
.hero h1, .hero p {
|
||||
color: white;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 1.25rem;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.hero .cta-button {
|
||||
background: white;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.hero .cta-button:hover {
|
||||
background: var(--surface-color);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
feather.replace();
|
||||
|
||||
// --- Theme Switcher ---
|
||||
const themeSwitch = document.getElementById('checkbox');
|
||||
const themeSwitch = document.getElementById('theme-checkbox');
|
||||
const currentTheme = localStorage.getItem('theme');
|
||||
|
||||
if (currentTheme) {
|
||||
@ -23,7 +23,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
}
|
||||
|
||||
themeSwitch.addEventListener('change', switchTheme, false);
|
||||
if (themeSwitch) {
|
||||
themeSwitch.addEventListener('change', switchTheme, false);
|
||||
}
|
||||
|
||||
// --- Generator Form: Photo Upload ---
|
||||
const uploadArea = document.getElementById('upload-area');
|
||||
|
||||
@ -19,6 +19,7 @@ try {
|
||||
$sql_users = "
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
@ -26,6 +27,12 @@ try {
|
||||
$pdo->exec($sql_users);
|
||||
echo "Table 'users' is ready.\n";
|
||||
|
||||
// Add username column to users table
|
||||
if (!columnExists($pdo, 'users', 'username')) {
|
||||
$pdo->exec("ALTER TABLE users ADD COLUMN username VARCHAR(255) NOT NULL AFTER id");
|
||||
echo "Column 'username' added to 'users' table.\n";
|
||||
}
|
||||
|
||||
// Add role column to users table
|
||||
if (!columnExists($pdo, 'users', 'role')) {
|
||||
$pdo->exec("ALTER TABLE users ADD COLUMN role VARCHAR(50) NOT NULL DEFAULT 'user'");
|
||||
|
||||
3
faq.php
3
faq.php
@ -1,10 +1,9 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'includes/translations.php';
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
|
||||
<main class="container my-5">
|
||||
|
||||
<h1 class="text-center mb-5"><?php echo t('faq_title'); ?></h1>
|
||||
|
||||
<div class="accordion" id="faqAccordion">
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
<footer>
|
||||
<div class="container">
|
||||
<p><?= t('footer_copyright') ?></p>
|
||||
<p>© <?php echo date('Y'); ?> <?php echo t('app_name'); ?>. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||
<script>
|
||||
feather.replace();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -22,13 +22,7 @@ if (isset($_GET['lang'])) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$lang = $_SESSION['lang'] ?? 'en';
|
||||
$translations = get_translations();
|
||||
|
||||
function t($key) {
|
||||
global $translations, $lang;
|
||||
return $translations[$lang][$key] ?? $key;
|
||||
}
|
||||
$lang = get_current_language();
|
||||
|
||||
$is_logged_in = isset($_SESSION['user_id']);
|
||||
?>
|
||||
@ -42,7 +36,8 @@ $is_logged_in = isset($_SESSION['user_id']);
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&family=Roboto:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
<script src="https://unpkg.com/phosphor-icons"></script>
|
||||
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/feather-icons"></script>
|
||||
</head>
|
||||
<body data-theme="light">
|
||||
|
||||
@ -67,10 +62,10 @@ $is_logged_in = isset($_SESSION['user_id']);
|
||||
<div class="language-switcher">
|
||||
<div class="selected-lang">
|
||||
<img src="assets/images/flags/<?php echo $lang; ?>.svg" alt="<?php echo $lang; ?>">
|
||||
<i class="ph-bold ph-caret-down icon-sm"></i>
|
||||
<i data-feather="chevron-down"></i>
|
||||
</div>
|
||||
<div class="lang-dropdown">
|
||||
<?php foreach (array_keys($translations) as $lang_code): ?>
|
||||
<?php foreach (array_keys(get_translations()) as $lang_code): ?>
|
||||
<a href="?lang=<?php echo $lang_code; ?>" class="<?php echo $lang === $lang_code ? 'active' : ''; ?>">
|
||||
<img src="assets/images/flags/<?php echo $lang_code; ?>.svg" alt="<?php echo $lang_code; ?>">
|
||||
<span><?php echo strtoupper($lang_code); ?></span>
|
||||
@ -87,8 +82,16 @@ $is_logged_in = isset($_SESSION['user_id']);
|
||||
</div>
|
||||
|
||||
<?php if ($is_logged_in): ?>
|
||||
<a href="profile.php" class="nav-link"><?php echo t('nav_profile'); ?></a>
|
||||
<a href="logout.php" class="nav-link"><?php echo t('nav_logout'); ?></a>
|
||||
<div class="user-menu">
|
||||
<button class="user-menu-toggle">
|
||||
<img src="https://i.pravatar.cc/40?u=<?php echo $_SESSION['user_id']; ?>" alt="User Avatar" class="avatar">
|
||||
<i data-feather="chevron-down"></i>
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="profile.php"><?php echo t('nav_profile'); ?></a>
|
||||
<a href="logout.php"><?php echo t('nav_logout'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<a href="register.php" class="nav-link"><?php echo t('nav_register'); ?></a>
|
||||
<a href="login.php" class="login-btn"><?php echo t('nav_login'); ?></a>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,6 @@
|
||||
<?php require_once 'includes/header.php'; ?>
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
|
||||
<main>
|
||||
<section class="hero">
|
||||
|
||||
11
list_users.php
Normal file
11
list_users.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("SELECT * FROM users");
|
||||
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
print_r($users);
|
||||
} catch (PDOException $e) {
|
||||
die("Database error: " . $e->getMessage() . "\n");
|
||||
}
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'includes/translations.php';
|
||||
require_once 'includes/header.php';
|
||||
|
||||
// Default to monthly
|
||||
|
||||
17
register.php
17
register.php
@ -8,11 +8,12 @@ $success = null;
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$pdo = db();
|
||||
|
||||
$username = $_POST['username'] ?? '';
|
||||
$email = $_POST['email'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
$password_confirm = $_POST['password_confirm'] ?? '';
|
||||
|
||||
if (empty($email) || empty($password) || empty($password_confirm)) {
|
||||
if (empty($username) || empty($email) || empty($password) || empty($password_confirm)) {
|
||||
$error = t('fill_all_fields');
|
||||
} elseif ($password !== $password_confirm) {
|
||||
$error = t('passwords_do_not_match');
|
||||
@ -26,8 +27,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$error = t('email_already_registered');
|
||||
} else {
|
||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare('INSERT INTO users (email, password) VALUES (?, ?)');
|
||||
$stmt->execute([$email, $hashed_password]);
|
||||
$stmt = $pdo->prepare('INSERT INTO users (username, email, password) VALUES (?, ?, ?)');
|
||||
$stmt->execute([$username, $email, $hashed_password]);
|
||||
$success = t('registration_successful');
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
@ -53,15 +54,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
<form action="register.php" method="POST" id="register-form" novalidate>
|
||||
<div class="form-group">
|
||||
<label for="email"><?= t('email') ?></label>
|
||||
<label for="username"><?= t('registration_form_username') ?></label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email"><?= t('registration_form_email') ?></label>
|
||||
<input type="email" id="email" name="email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password"><?= t('password') ?></label>
|
||||
<label for="password"><?= t('registration_form_password') ?></label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password_confirm"><?= t('confirm_password') ?></label>
|
||||
<label for="password_confirm"><?= t('registration_form_password_confirm') ?></label>
|
||||
<input type="password" id="password_confirm" name="password_confirm" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user