Commit 233f0436 authored by Mahmoud Aglan's avatar Mahmoud Aglan

rebuild: PHP foundation + auth + layout system

Complete rewrite from React/Vite to PHP/HTML/CSS/JS stack.
- PHP 8.3 Apache Docker setup with routing
- Supabase auth (login/register) working
- Full CSS design system (dark theme, RTL, responsive)
- SVG icon sprite (no emojis)
- Desktop side nav + mobile bottom nav
- All page routes with placeholders
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 168e1845
node_modules # OS
dist .DS_Store
.env Thumbs.db
*.local
# IDE
.idea/
.vscode/
*.swp
*.swo
# Sensitive
*.pem
Connections and docs /
# Deps (none for now, but future-proofing)
vendor/
node_modules/
RewriteEngine On
# Force HTTPS (CapRover handles SSL termination via X-Forwarded-Proto)
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Route all non-file requests to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1 [QSA,L]
# Security headers
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
# Deny access to sensitive files
<FilesMatch "\.(pem|md|gitignore)$">
Require all denied
</FilesMatch>
<Files "config/*">
Require all denied
</Files>
This diff is collapsed.
FROM node:20-alpine AS build FROM php:8.3-apache
WORKDIR /app
COPY package*.json ./ RUN apt-get update && apt-get install -y libpq-dev \
RUN npm ci && docker-php-ext-install pdo pdo_pgsql pgsql \
COPY . . && apt-get clean && rm -rf /var/lib/apt/lists/*
RUN npm run build
RUN a2enmod rewrite headers
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html ENV APACHE_DOCUMENT_ROOT=/var/www/html
COPY nginx.conf /etc/nginx/conf.d/default.conf RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
COPY . /var/www/html/
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
This diff is collapsed.
This diff is collapsed.
<?php
require_once __DIR__ . '/../config/database.php';
header('Content-Type: application/json');
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';
if ($action === 'login') {
$email = $input['email'] ?? '';
$password = $input['password'] ?? '';
if (!$email || !$password) {
http_response_code(400);
echo json_encode(['error' => 'البريد وكلمة المرور مطلوبين']);
exit;
}
$result = supabase_auth('token?grant_type=password', [
'email' => $email,
'password' => $password,
]);
if ($result['status'] !== 200) {
$msg = $result['data']['error_description'] ?? $result['data']['msg'] ?? 'بيانات الدخول غير صحيحة';
http_response_code(401);
echo json_encode(['error' => $msg]);
exit;
}
echo json_encode([
'access_token' => $result['data']['access_token'],
'refresh_token' => $result['data']['refresh_token'],
'user' => $result['data']['user'],
]);
} elseif ($action === 'register') {
$email = $input['email'] ?? '';
$password = $input['password'] ?? '';
$username = $input['username'] ?? '';
if (!$email || !$password || !$username) {
http_response_code(400);
echo json_encode(['error' => 'جميع الحقول مطلوبة']);
exit;
}
if (strlen($password) < 6) {
http_response_code(400);
echo json_encode(['error' => 'كلمة المرور يجب ان تكون 6 احرف على الاقل']);
exit;
}
$result = supabase_auth('signup', [
'email' => $email,
'password' => $password,
'data' => ['username' => $username, 'display_name' => $username],
]);
if ($result['status'] !== 200 && $result['status'] !== 201) {
$msg = $result['data']['error_description'] ?? $result['data']['msg'] ?? 'فشل التسجيل';
http_response_code(400);
echo json_encode(['error' => $msg]);
exit;
}
if (isset($result['data']['access_token'])) {
echo json_encode([
'access_token' => $result['data']['access_token'],
'refresh_token' => $result['data']['refresh_token'],
'user' => $result['data']['user'],
]);
} else {
echo json_encode(['message' => 'تم التسجيل بنجاح، يرجى تاكيد البريد']);
}
} elseif ($action === 'refresh') {
$refreshToken = $input['refresh_token'] ?? '';
if (!$refreshToken) {
http_response_code(400);
echo json_encode(['error' => 'refresh_token مطلوب']);
exit;
}
$result = supabase_auth('token?grant_type=refresh_token', [
'refresh_token' => $refreshToken,
]);
if ($result['status'] !== 200) {
http_response_code(401);
echo json_encode(['error' => 'الجلسة منتهية']);
exit;
}
echo json_encode([
'access_token' => $result['data']['access_token'],
'refresh_token' => $result['data']['refresh_token'],
]);
} else {
http_response_code(400);
echo json_encode(['error' => 'action غير معروف']);
}
This diff is collapsed.
<?php
define('APP_NAME', 'EL3AB');
define('APP_URL', 'https://el3ab-player.caprover.al-arcade.com');
define('APP_VERSION', '2.0.0');
define('SUPABASE_URL', 'https://safe-supabase-kong.caprover.al-arcade.com');
define('SUPABASE_ANON_KEY', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzM1Njg5NjAwLCJleHAiOjE4OTM0NTYwMDB9.31PF6PvP-pSrvRuQwLFptQoejR0W1A7o53lZhEbnz84');
define('SUPABASE_SERVICE_KEY', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE3MzU2ODk2MDAsImV4cCI6MTg5MzQ1NjAwMH0.wNfmuJNkX-bZwD7RbjxOChlRf_3Xm4I7bswEYTcDCg4');
define('STOCKFISH_API', 'https://stockfishapi.caprover.al-arcade.com');
define('STOCKFISH_MGMT_KEY', 'sk-alarc-stockfish-mgmt-2024');
This diff is collapsed.
</div>
</main>
<?php require __DIR__ . '/../templates/nav-bottom.php'; ?>
</div>
<div class="toast-container" id="toast-container"></div>
<script src="/public/js/app.js"></script>
<?php if (isset($extraJs)): ?>
<script src="<?= $extraJs ?>"></script>
<?php endif; ?>
</body>
</html>
This diff is collapsed.
<!doctype html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="theme-color" content="#071120" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<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=IBM+Plex+Sans+Arabic:wght@400;500;600;700&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet" />
<title>EL3AB - العب</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment