feat: rewrite website in PHP, drop Node.js stack
Replace React/Vite frontend + Fastify API with a single PHP application. - Front controller router in public/index.php (clean URLs via .htaccess) - Session-based auth (no JWT) — register, login, verify email, forgot/reset password, logout - Stripe checkout sessions, billing portal, webhook handler (checkout.session.completed, subscription.updated/deleted) - License IP change via internal licensing server API - PHP classes: DB (PDO), Auth, Mailer (PHPMailer), StripeClient - Views: home, pricing, install, login, register, dashboard, verify-email, forgot-password, reset-password, 404 - Tailwind CSS via CDN — no build step required - Composer dependencies: stripe/stripe-php, phpmailer/phpmailer, vlucas/phpdotenv, ramsey/uuid - CSRF protection on all POST forms - PRG pattern with session flash messages Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
72f5cc1060
commit
faf0818dde
@@ -0,0 +1,16 @@
|
||||
</main>
|
||||
<footer class="border-t border-gray-800 bg-gray-950 py-10 mt-16">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-gray-500">
|
||||
<span>© <?= date('Y') ?> NixPanel. All rights reserved.</span>
|
||||
<div class="flex gap-6">
|
||||
<a href="/pricing" class="hover:text-gray-300 transition-colors">Pricing</a>
|
||||
<a href="/install" class="hover:text-gray-300 transition-colors">Install</a>
|
||||
<a href="https://docs.nixpanel.io" target="_blank" rel="noreferrer" class="hover:text-gray-300 transition-colors">Docs</a>
|
||||
<a href="/login" class="hover:text-gray-300 transition-colors">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="bg-gray-950">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= e($pageTitle ?? 'NixPanel — Modern Web Hosting Control Panel') ?></title>
|
||||
<meta name="description" content="<?= e($pageDesc ?? 'NixPanel is a modern, open-source cPanel alternative. Manage your Linux server with NixServer and NixClient.') ?>">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
50: '#eff6ff',
|
||||
100: '#dbeafe',
|
||||
400: '#60a5fa',
|
||||
500: '#3b82f6',
|
||||
600: '#2563eb',
|
||||
700: '#1d4ed8',
|
||||
900: '#1e3a5f',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style type="text/tailwindcss">
|
||||
@layer base {
|
||||
body { @apply bg-gray-950 text-gray-100 font-sans antialiased; }
|
||||
.btn-primary { @apply inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-lg bg-brand-600 hover:bg-brand-700 text-white font-semibold text-sm transition-colors; }
|
||||
.btn-secondary { @apply inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-lg bg-transparent hover:bg-gray-800 text-gray-300 border border-gray-700 font-semibold text-sm transition-colors; }
|
||||
.btn-outline { @apply inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-lg bg-transparent hover:bg-brand-900/30 text-brand-400 border border-brand-500/50 font-semibold text-sm transition-colors; }
|
||||
.input { @apply w-full bg-gray-900 border border-gray-700 text-white rounded-lg px-4 py-2.5 text-sm placeholder-gray-500 focus:outline-none focus:border-brand-500 transition-colors; }
|
||||
.card { @apply bg-gray-900/50 border border-gray-800 rounded-xl p-6; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen flex flex-col">
|
||||
|
||||
<?php if ($flash): ?>
|
||||
<div id="flash" class="fixed top-4 right-4 z-50 max-w-sm w-full">
|
||||
<div class="flex items-start gap-3 px-4 py-3 rounded-lg border shadow-lg
|
||||
<?= $flash['type'] === 'success' ? 'bg-emerald-900/60 border-emerald-500/30 text-emerald-300' : 'bg-red-900/60 border-red-500/30 text-red-300' ?>">
|
||||
<span class="text-sm flex-1"><?= e($flash['message']) ?></span>
|
||||
<button onclick="document.getElementById('flash').remove()" class="opacity-60 hover:opacity-100 text-lg leading-none">×</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>setTimeout(() => { const f = document.getElementById('flash'); if (f) f.remove(); }, 5000);</script>
|
||||
<?php endif ?>
|
||||
@@ -0,0 +1,25 @@
|
||||
<header class="border-b border-gray-800 bg-gray-950/80 backdrop-blur-sm sticky top-0 z-40">
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||
<a href="/" class="flex items-center gap-2">
|
||||
<span class="text-xl font-bold text-white">Nix<span class="text-brand-500">Panel</span></span>
|
||||
</a>
|
||||
|
||||
<nav class="hidden md:flex items-center gap-6 text-sm text-gray-400">
|
||||
<a href="/" class="hover:text-white transition-colors">Home</a>
|
||||
<a href="/pricing" class="hover:text-white transition-colors">Pricing</a>
|
||||
<a href="/install" class="hover:text-white transition-colors">Install</a>
|
||||
<a href="https://docs.nixpanel.io" target="_blank" rel="noreferrer" class="hover:text-white transition-colors">Docs</a>
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<?php if (\NixPanel\Auth::isLoggedIn()): ?>
|
||||
<a href="/dashboard" class="text-sm text-gray-300 hover:text-white transition-colors">Dashboard</a>
|
||||
<a href="/logout" class="text-sm px-4 py-2 rounded-lg border border-gray-700 text-gray-300 hover:border-gray-500 hover:text-white transition-colors">Sign out</a>
|
||||
<?php else: ?>
|
||||
<a href="/login" class="text-sm text-gray-300 hover:text-white transition-colors">Sign in</a>
|
||||
<a href="/register" class="text-sm px-4 py-2 rounded-lg bg-brand-600 hover:bg-brand-700 text-white font-semibold transition-colors">Get started</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="flex-1">
|
||||
Reference in New Issue
Block a user