154 lines
4.3 KiB
PHP
154 lines
4.3 KiB
PHP
<?php
|
|
// ─── DB CONFIG ─────────────────────────────────────────────────
|
|
$dbHost = 'localhost';
|
|
$dbPort = '5432';
|
|
$dbName = 'af585fp_db';
|
|
$dbUser = 'database_user';
|
|
$dbPass = 'password_database';
|
|
// ────────────────────────────────────────────────────────────────
|
|
|
|
$dsn = "pgsql:host=$dbHost;port=$dbPort;dbname=$dbName";
|
|
try {
|
|
$pdo = new PDO($dsn, $dbUser, $dbPass, [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
|
]);
|
|
// Auto-migration: if the table does not exist, create it
|
|
$pdo->exec(<<<'SQL'
|
|
CREATE TABLE IF NOT EXISTS visitors (
|
|
id SERIAL PRIMARY KEY,
|
|
visited_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
SQL
|
|
);
|
|
} catch (Exception $e) {
|
|
die("Database connection or migration failed: " . $e->getMessage());
|
|
}
|
|
|
|
// Insert a row then count
|
|
$pdo->exec("INSERT INTO visitors DEFAULT VALUES");
|
|
$count = $pdo->query("SELECT COUNT(*) FROM visitors")->fetchColumn();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Visit Counter</title>
|
|
<style>
|
|
/* Import Google Fonts */
|
|
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&display=swap');
|
|
|
|
:root {
|
|
--bg-light: #f0f4f8;
|
|
--bg-dark: #1a1a2e;
|
|
--card-bg-light: #ffffff;
|
|
--card-bg-dark: rgba(26,26,46,0.8);
|
|
--primary: #2e86de;
|
|
--text-light: #333333;
|
|
--text-dark: #eaeaea;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Montserrat', sans-serif;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
background: var(--bg-light);
|
|
transition: background 0.3s ease;
|
|
color: var(--text-light);
|
|
}
|
|
body.dark {
|
|
background: var(--bg-dark);
|
|
color: var(--text-dark);
|
|
}
|
|
|
|
.card {
|
|
background: var(--card-bg-light);
|
|
padding: 2rem;
|
|
border-radius: 1rem;
|
|
box-shadow: 0 8px 24px rgba(0,0,0,0.1);
|
|
text-align: center;
|
|
width: 90%;
|
|
max-width: 400px;
|
|
backdrop-filter: blur(10px);
|
|
transition: background 0.3s ease, box-shadow 0.3s ease;
|
|
}
|
|
body.dark .card {
|
|
background: var(--card-bg-dark);
|
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.controls button {
|
|
background: var(--primary);
|
|
border: none;
|
|
color: #fff;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 0.5rem;
|
|
font-size: 1rem;
|
|
cursor: pointer;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
.controls button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 16px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
p {
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
strong {
|
|
color: var(--primary);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="card">
|
|
<div class="controls">
|
|
<button id="refreshBtn">↻ Refresh</button>
|
|
<button id="themeToggle">🌙</button>
|
|
</div>
|
|
<h1>Visit Counter</h1>
|
|
<p>You are visitor # <strong><?= htmlspecialchars($count) ?></strong></p>
|
|
</div>
|
|
<script>
|
|
// Refresh the page without submitting the count twice
|
|
document.getElementById('refreshBtn').addEventListener('click', () => {
|
|
location.reload();
|
|
});
|
|
// Handling light/dark theme
|
|
const toggle = document.getElementById('themeToggle');
|
|
const applyTheme = (dark) => {
|
|
document.body.classList.toggle('dark', dark);
|
|
toggle.textContent = dark ? '☀️' : '🌙';
|
|
localStorage.setItem('darkMode', dark);
|
|
};
|
|
toggle.addEventListener('click', () => {
|
|
applyTheme(!document.body.classList.contains('dark'));
|
|
});
|
|
// Initialization
|
|
const darkMode = localStorage.getItem('darkMode') === 'true';
|
|
applyTheme(darkMode);
|
|
</script>
|
|
</body>
|
|
</html>
|