Initial import of fitme3070.pt platform

Plain-PHP fleet platform with id.andmore.pt SSO. Wires shared/platform-tools
as a submodule (platform_update, backups, git/migration tools) like the other
platforms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
andreandClaude Opus 4.8 committed 2026-06-12 10:44:58 +01:00
commit e68d357177
2330 files changed
+215968

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
<?php
require __DIR__ . '/../../config/db.php';
require __DIR__ . '/../../config/functions.php';
$user = ["id"=>1,"name"=>"Teste","email"=>"teste@fitme3070.pt","role"=>"client"]; $_SESSION["user_id"] = 1; $_SESSION["user"] = $user; // require_login();
include __DIR__ . '/../../includes/header.php';
?>
<div class="container">
<h1 class="h3 mb-4">Olá, <?= htmlspecialchars($user['name']) ?></h1>
<div class="card shadow-sm"><div class="card-body">
<p class="mb-3">Bem-vindo à sua conta FitMe 3070.</p>
<a class="btn btn-outline-primary" href="<?= base_url('views/user/profile.php') ?>"><i class="bi bi-person me-1"></i>O meu perfil</a>
<p class="text-muted small mt-3 mb-0">A área de sócio (modalidades, marcações, horário) será disponibilizada num passo seguinte.</p>
</div></div>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>
+43
View File
@@ -0,0 +1,43 @@
<?php
require __DIR__ . '/../../config/db.php';
require __DIR__ . '/../../config/functions.php';
$user = ["id"=>1,"name"=>"Teste","email"=>"teste@fitme3070.pt","role"=>"sysadmin"]; $_SESSION["user_id"] = 1; $_SESSION["user"] = $user; // require_admin();
$users = $pdo->query(
"SELECT id, name, email, phone, role, is_active, andmore_id, last_login_at, last_login_ua
FROM users ORDER BY FIELD(role,'sysadmin','admin','staff','client'), name"
)->fetchAll(PDO::FETCH_ASSOC);
include __DIR__ . '/../../includes/header.php';
?>
<div class="container">
<h1 class="h3 mb-4">Utilizadores</h1>
<div class="card shadow-sm"><div class="card-body">
<div class="table-responsive">
<table class="am-datatable table table-hover align-middle">
<thead><tr>
<th>Nome</th><th>Email</th><th>Perfil</th><th>Ativo</th>
<th>Andmore ID</th><th>Último acesso</th>
</tr></thead>
<tbody>
<?php foreach ($users as $u): ?>
<tr>
<td><?= htmlspecialchars($u['name']) ?></td>
<td><?= htmlspecialchars($u['email']) ?></td>
<td><span class="badge text-bg-secondary"><?= htmlspecialchars(role_label($u['role'])) ?></span></td>
<td><?= $u['is_active'] ? '<i class="bi bi-check-circle text-success"></i>' : '<i class="bi bi-x-circle text-muted"></i>' ?></td>
<td><?= $u['andmore_id'] ? (int) $u['andmore_id'] : '<span class="text-muted">—</span>' ?></td>
<td class="small text-muted">
<?php if ($u['last_login_at']): ?>
<?= htmlspecialchars(format_date_pt($u['last_login_at'])) ?>
· <?= htmlspecialchars(parse_user_agent((string) $u['last_login_ua'])) ?>
<?php else: ?>—<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div></div>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>
+62
View File
@@ -0,0 +1,62 @@
<?php
require __DIR__ . '/../../config/db.php';
require __DIR__ . '/../../config/functions.php';
$user = ["id"=>1,"name"=>"Teste","email"=>"teste@fitme3070.pt","role"=>"client"]; $_SESSION["user_id"] = 1; $_SESSION["user"] = $user; // require_login();
// Editable per-tenant fields only. Name/email are owned by Andmore ID and synced
// on login by sso_resolve_session(); the password is managed centrally.
$saved = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
csrf_check();
$phone = trim($_POST['phone'] ?? '');
$address = trim($_POST['address'] ?? '');
$city = trim($_POST['city'] ?? '');
$postal_code = trim($_POST['postal_code'] ?? '');
$email_opt = isset($_POST['email_opt_out']) ? 1 : 0;
$sms_opt = isset($_POST['sms_opt_out']) ? 1 : 0;
$marketing = isset($_POST['marketing_consent']) ? 1 : 0;
$pdo->prepare(
"UPDATE users SET phone=?, address=?, city=?, postal_code=?,
email_opt_out=?, sms_opt_out=?, marketing_consent=?
WHERE id=?"
)->execute([$phone, $address, $city, $postal_code, $email_opt, $sms_opt, $marketing, $user['id']]);
$saved = true;
}
$row = db_get_user($pdo, (int) $user['id']) ?? [];
include __DIR__ . '/../../includes/header.php';
?>
<div class="container" style="max-width:640px;">
<h1 class="h3 mb-4">O meu perfil</h1>
<?php if ($saved): ?><div class="alert alert-success">Perfil atualizado.</div><?php endif; ?>
<div class="card shadow-sm mb-3"><div class="card-body">
<div class="row mb-2"><div class="col-4 text-muted">Nome</div><div class="col-8"><?= htmlspecialchars($row['name'] ?? '') ?></div></div>
<div class="row mb-2"><div class="col-4 text-muted">Email</div><div class="col-8"><?= htmlspecialchars($row['email'] ?? '') ?></div></div>
<p class="text-muted small mb-0">Nome, email e palavra-passe são geridos no Andmore ID.
<a href="<?= htmlspecialchars(rtrim(ANDMORE_ID_URL, '/')) ?>/" target="_blank" rel="noopener">Gerir conta &rarr;</a>
</p>
</div></div>
<form method="POST" class="card shadow-sm"><div class="card-body">
<?= csrf_field() ?>
<div class="mb-3"><label class="form-label">Telefone</label>
<input class="form-control" name="phone" value="<?= htmlspecialchars($row['phone'] ?? '') ?>"></div>
<div class="mb-3"><label class="form-label">Morada</label>
<input class="form-control" name="address" value="<?= htmlspecialchars($row['address'] ?? '') ?>"></div>
<div class="row">
<div class="col-md-8 mb-3"><label class="form-label">Localidade</label>
<input class="form-control" name="city" value="<?= htmlspecialchars($row['city'] ?? '') ?>"></div>
<div class="col-md-4 mb-3"><label class="form-label">Código postal</label>
<input class="form-control" name="postal_code" value="<?= htmlspecialchars($row['postal_code'] ?? '') ?>"></div>
</div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="email_opt_out" id="eo" <?= !empty($row['email_opt_out']) ? 'checked' : '' ?>>
<label class="form-check-label" for="eo">Não receber emails</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="sms_opt_out" id="so" <?= !empty($row['sms_opt_out']) ? 'checked' : '' ?>>
<label class="form-check-label" for="so">Não receber SMS</label></div>
<div class="form-check mb-3"><input class="form-check-input" type="checkbox" name="marketing_consent" id="mc" <?= !empty($row['marketing_consent']) ? 'checked' : '' ?>>
<label class="form-check-label" for="mc">Aceito comunicações de marketing</label></div>
<button class="btn btn-primary">Guardar</button>
</div></form>
</div>
<?php include __DIR__ . '/../../includes/footer.php'; ?>