Files
mediakor2/index.php
2025-11-25 23:11:04 +00:00

651 lines
16 KiB
PHP

<?php
/*
Minimal DB schema for Mediakor posts:
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
meta VARCHAR(255) DEFAULT NULL,
body TEXT NOT NULL,
is_published TINYINT(1) NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Insert example:
INSERT INTO posts (title, meta, body) VALUES
('Welcome to Mediakor', 'System Log • Today',
'Mediakor is your central hub for projects, servers, and experiments. Use the nav on the left to explore each sector of the network.');
*/
// --- DB CONFIG ---
// You can also set these as environment variables in your Docker stack
$dbHost = $_ENV['DB_HOST'] ?? 'mariadb';
$dbName = $_ENV['DB_NAME'] ?? 'appdb';
$dbUser = $_ENV['DB_USER'] ?? 'appuser';
$dbPass = $_ENV['DB_PASS'] ?? 'apppass';
$posts = [];
$dbError = null;
try {
$dsn = "mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4";
$pdo = new PDO($dsn, $dbUser, $dbPass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$stmt = $pdo->query("
SELECT id, title, meta, body, created_at
FROM posts
WHERE is_published = 1
ORDER BY created_at DESC, id DESC
");
$posts = $stmt->fetchAll();
} catch (PDOException $e) {
// Fallback: static posts if DB connection fails
$dbError = 'DB_connect_failed';
$posts = [
[
'id' => 0,
'title' => 'Welcome to Mediakor',
'meta' => 'System Log • Fallback',
'body' => 'Database connection failed, so this is the static fallback feed. Once your DB is configured, posts will be served from the posts table.',
'created_at' => null,
],
[
'id' => 0,
'title' => 'Configure Database',
'meta' => 'Setup • Guide',
'body' => 'Edit the DB settings at the top of index.php and create the posts table using the SQL snippet in the comment.',
'created_at' => null,
],
];
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mediakor — Command Hub</title>
<style>
:root{
--bg:#050608;
--bg-alt:#0b0c10;
--panel:#101218;
--panel-soft:#161923;
--accent:#ff8c32;
--accent-soft:rgba(255,140,50,0.18);
--accent-border:rgba(255,140,50,0.5);
--text:#f3f4f6;
--muted:#a1a1aa;
--divider:#23232e;
--shadow:0 0 40px rgba(0,0,0,0.65);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
min-height:100vh;
background:
radial-gradient(800px 600px at 75% 0%, #17141f 0, transparent 60%),
radial-gradient(900px 700px at 0% 100%, #141019 0, transparent 60%),
linear-gradient(160deg,#050608,#050608 40%,#080910 100%);
color:var(--text);
font:500 15px/1.6 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
display:flex;
flex-direction:column;
overflow-x:hidden;
position:relative;
}
/* Twinkling starfields (two layers, desynced animation) */
body::before,
body::after{
content:"";
position:fixed;
inset:-200px;
pointer-events:none;
z-index:-1;
background-repeat:no-repeat;
}
body::before{
background-image:
radial-gradient(1px 1px at 10% 20%,rgba(255,255,255,.40) 0,transparent 60%),
radial-gradient(1px 1px at 40% 80%,rgba(255,255,255,.25) 0,transparent 60%),
radial-gradient(1px 1px at 80% 30%,rgba(255,255,255,.30) 0,transparent 60%),
radial-gradient(1px 1px at 20% 60%,rgba(255,255,255,.22) 0,transparent 60%),
radial-gradient(1px 1px at 65% 50%,rgba(255,255,255,.20) 0,transparent 60%);
animation:twinkleLayer1 14s linear infinite alternate;
}
body::after{
background-image:
radial-gradient(1px 1px at 15% 75%,rgba(255,255,255,.25) 0,transparent 60%),
radial-gradient(1px 1px at 70% 15%,rgba(255,255,255,.30) 0,transparent 60%),
radial-gradient(1px 1px at 90% 60%,rgba(255,255,255,.22) 0,transparent 60%),
radial-gradient(1px 1px at 35% 35%,rgba(255,255,255,.27) 0,transparent 60%);
animation:twinkleLayer2 18s linear infinite alternate;
}
@keyframes twinkleLayer1{
0% {opacity:0.25; transform:translate3d(0,0,0);}
50% {opacity:0.55; transform:translate3d(10px,-8px,0);}
100%{opacity:0.20; transform:translate3d(-8px,6px,0);}
}
@keyframes twinkleLayer2{
0% {opacity:0.18; transform:translate3d(0,0,0);}
50% {opacity:0.50; transform:translate3d(-12px,10px,0);}
100%{opacity:0.22; transform:translate3d(8px,-6px,0);}
}
/* Header */
.mk-header{
padding:14px 22px 10px;
border-bottom:1px solid var(--divider);
background:linear-gradient(90deg,rgba(0,0,0,.75),rgba(5,5,10,.4));
backdrop-filter:blur(18px);
display:flex;
align-items:center;
justify-content:space-between;
position:sticky;
top:0;
z-index:20;
}
.mk-logo{
display:flex;
align-items:baseline;
gap:8px;
}
.mk-logo-main{
font-size:26px;
letter-spacing:0.16em;
text-transform:uppercase;
font-weight:700;
color:var(--accent);
}
.mk-logo-sub{
font-size:12px;
text-transform:uppercase;
letter-spacing:0.24em;
color:var(--muted);
}
.mk-header-pill{
padding:4px 10px;
border-radius:999px;
border:1px solid var(--accent-border);
background:radial-gradient(circle at 0 0,rgba(255,140,50,.25),transparent 55%);
font-size:11px;
text-transform:uppercase;
letter-spacing:0.18em;
color:var(--muted);
display:flex;
align-items:center;
gap:8px;
}
.mk-pulse{
width:7px;
height:7px;
border-radius:50%;
background:var(--accent);
box-shadow:0 0 8px rgba(255,140,50,.9);
animation:mk-pulse 1.4s infinite;
}
@keyframes mk-pulse{
0%{transform:scale(1);opacity:1}
50%{transform:scale(1.6);opacity:.25}
100%{transform:scale(1);opacity:1}
}
/* Layout */
.mk-shell{
flex:1;
display:flex;
max-width:1400px;
width:100%;
margin:16px auto 24px;
padding:0 16px;
gap:18px;
}
/* Sidebar */
.mk-sidebar{
width:240px;
min-width:220px;
max-height:calc(100vh - 96px);
background:linear-gradient(150deg,var(--panel),#080910);
border-radius:18px;
border:1px solid var(--divider);
box-shadow:var(--shadow);
padding:14px 12px 12px;
display:flex;
flex-direction:column;
gap:10px;
position:sticky;
top:80px;
}
.mk-sidebar-title{
font-size:11px;
text-transform:uppercase;
letter-spacing:0.14em;
color:var(--muted);
padding:0 8px;
}
.mk-nav{
list-style:none;
margin-top:4px;
}
.mk-nav-item{
margin-bottom:4px;
}
.mk-nav-link{
display:flex;
align-items:center;
gap:10px;
padding:7px 9px;
border-radius:12px;
color:var(--muted);
text-decoration:none;
font-size:13px;
border:1px solid transparent;
background:transparent;
transition:.16s ease;
cursor:pointer;
}
.mk-nav-link span.mk-dot{
width:7px;
height:7px;
border-radius:50%;
background:var(--accent-soft);
border:1px solid var(--accent-border);
}
.mk-nav-link small{
text-transform:uppercase;
letter-spacing:0.16em;
font-size:10px;
color:#71717a;
}
.mk-nav-link strong{
font-weight:600;
color:var(--text);
}
.mk-nav-link:hover{
background:radial-gradient(circle at 0 0,var(--accent-soft),transparent 55%);
border-color:var(--accent-border);
color:var(--text);
transform:translateX(2px);
}
.mk-nav-link.active{
background:linear-gradient(120deg,rgba(255,140,50,.25),rgba(0,0,0,.1));
border-color:var(--accent-border);
color:var(--text);
}
.mk-sidebar-footer{
margin-top:auto;
padding-top:8px;
border-top:1px dashed var(--divider);
font-size:11px;
color:var(--muted);
display:flex;
flex-direction:column;
gap:4px;
padding-inline:8px;
}
.mk-tag{
display:inline-flex;
align-items:center;
gap:6px;
padding:3px 8px;
border-radius:999px;
border:1px solid var(--accent-border);
background:rgba(0,0,0,.6);
font-size:10px;
text-transform:uppercase;
letter-spacing:0.16em;
}
/* Main content */
.mk-main{
flex:1;
min-width:0;
display:flex;
flex-direction:column;
gap:12px;
}
.mk-main-header{
display:flex;
justify-content:space-between;
align-items:flex-end;
padding:6px 4px 4px;
}
.mk-main-title{
display:flex;
flex-direction:column;
gap:2px;
}
.mk-main-title h2{
font-size:18px;
text-transform:uppercase;
letter-spacing:0.18em;
color:var(--text);
}
.mk-main-title span{
font-size:12px;
color:var(--muted);
}
.mk-main-meta{
font-size:11px;
color:var(--muted);
text-transform:uppercase;
letter-spacing:0.14em;
}
/* Posts */
.mk-post-list{
display:flex;
flex-direction:column;
gap:12px;
}
.mk-post{
background:linear-gradient(145deg,var(--panel),var(--panel-soft));
border-radius:18px;
border:1px solid var(--divider);
box-shadow:var(--shadow);
padding:14px 16px 13px;
position:relative;
overflow:hidden;
}
.mk-post::before{
content:"";
position:absolute;
inset:0;
background:radial-gradient(600px 220px at 105% -10%,rgba(255,140,50,.18),transparent 60%);
opacity:0.85;
pointer-events:none;
}
.mk-post-inner{
position:relative;
z-index:1;
}
.mk-post-header{
display:flex;
justify-content:space-between;
align-items:flex-start;
gap:10px;
margin-bottom:6px;
}
.mk-post-title{
font-size:17px;
font-weight:600;
letter-spacing:0.04em;
text-transform:uppercase;
}
.mk-post-meta{
font-size:11px;
text-transform:uppercase;
letter-spacing:0.18em;
color:var(--muted);
white-space:nowrap;
}
.mk-post-body{
font-size:14px;
color:#e4e4ea;
margin-top:2px;
}
.mk-post-footer{
margin-top:10px;
font-size:11px;
display:flex;
justify-content:space-between;
align-items:center;
color:var(--muted);
}
.mk-pill{
padding:3px 8px;
border-radius:999px;
border:1px solid var(--accent-border);
background:rgba(0,0,0,.5);
font-size:10px;
text-transform:uppercase;
letter-spacing:0.16em;
}
.mk-post-actions{
display:flex;
gap:8px;
font-size:11px;
}
.mk-post-actions button{
border:none;
outline:none;
background:transparent;
color:var(--muted);
cursor:pointer;
padding:0;
font:inherit;
opacity:.8;
}
.mk-post-actions button:hover{
opacity:1;
color:var(--accent);
}
/* Responsive */
@media (max-width:960px){
.mk-shell{
flex-direction:column;
max-width:100%;
}
.mk-sidebar{
position:static;
width:auto;
flex-direction:row;
align-items:flex-start;
max-height:none;
overflow-x:auto;
padding:10px;
}
.mk-sidebar-title,
.mk-sidebar-footer{
display:none;
}
.mk-nav{
display:flex;
gap:4px;
margin-top:0;
}
.mk-nav-item{
margin:0;
}
}
@media (max-width:640px){
.mk-header{
flex-direction:column;
align-items:flex-start;
gap:8px;
}
.mk-main-header{
flex-direction:column;
align-items:flex-start;
gap:6px;
}
}
</style>
</head>
<body>
<header class="mk-header">
<div class="mk-logo">
<div class="mk-logo-main">Mediakor</div>
<div class="mk-logo-sub">Central Command</div>
</div>
<div class="mk-header-pill">
<span class="mk-pulse"></span>
<span>Network Status: Online</span>
</div>
</header>
<main class="mk-shell">
<!-- LEFT SIDEBAR NAV -->
<aside class="mk-sidebar">
<div class="mk-sidebar-title">Navigation</div>
<ul class="mk-nav">
<li class="mk-nav-item">
<a href="#" class="mk-nav-link active">
<span class="mk-dot"></span>
<div>
<strong>Dashboard</strong><br>
<small>Core Hub</small>
</div>
</a>
</li>
<li class="mk-nav-item">
<a href="#services" class="mk-nav-link">
<span class="mk-dot"></span>
<div>
<strong>Services</strong><br>
<small>Game & Web</small>
</div>
</a>
</li>
<li class="mk-nav-item">
<a href="#status" class="mk-nav-link">
<span class="mk-dot"></span>
<div>
<strong>Status Panel</strong><br>
<small>Monitoring</small>
</div>
</a>
</li>
<li class="mk-nav-item">
<a href="#docs" class="mk-nav-link">
<span class="mk-dot"></span>
<div>
<strong>Documentation</strong><br>
<small>Wiki & Guides</small>
</div>
</a>
</li>
<li class="mk-nav-item">
<a href="#contact" class="mk-nav-link">
<span class="mk-dot"></span>
<div>
<strong>Contact</strong><br>
<small>Reach Ops</small>
</div>
</a>
</li>
</ul>
<div class="mk-sidebar-footer">
<div class="mk-tag">
<span></span>
<span>Sector: Outer Net</span>
</div>
<span>All traffic through Mediakor is monitored for anomalies and uptime.</span>
<?php if ($dbError): ?>
<span style="color:#f97373;margin-top:4px;">DB status: offline (showing fallback posts)</span>
<?php endif; ?>
</div>
</aside>
<!-- MAIN CONTENT -->
<section class="mk-main">
<div class="mk-main-header">
<div class="mk-main-title">
<h2>Command Feed</h2>
<span>Latest entries from the Mediakor network</span>
</div>
<div class="mk-main-meta">
Feed Mode: <strong style="color:var(--accent); margin-left:4px;">Chronological</strong>
</div>
</div>
<div class="mk-post-list">
<?php if (empty($posts)): ?>
<article class="mk-post">
<div class="mk-post-inner">
<header class="mk-post-header">
<h3 class="mk-post-title">No Posts Yet</h3>
<div class="mk-post-meta">Setup • Info</div>
</header>
<div class="mk-post-body">
Use phpMyAdmin or your SQL client to insert rows into the <code>posts</code> table and they will appear here automatically.
</div>
<footer class="mk-post-footer">
<span class="mk-pill">System</span>
</footer>
</div>
</article>
<?php else: ?>
<?php foreach ($posts as $post): ?>
<article class="mk-post">
<div class="mk-post-inner">
<header class="mk-post-header">
<h3 class="mk-post-title">
<?php echo htmlspecialchars($post['title']); ?>
</h3>
<div class="mk-post-meta">
<?php echo htmlspecialchars($post['meta'] ?? 'Log Entry'); ?>
</div>
</header>
<div class="mk-post-body">
<?php echo nl2br(htmlspecialchars($post['body'])); ?>
</div>
<footer class="mk-post-footer">
<span class="mk-pill">Log Entry</span>
<div class="mk-post-actions">
<!-- These could later link to a dedicated post page or admin tools -->
<button type="button">View Details</button>
<button type="button">Pin</button>
</div>
</footer>
</div>
</article>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
</main>
</body>
</html>