Compare commits

..

No commits in common. "ai-dev" and "master" have entirely different histories.

4 changed files with 142 additions and 284 deletions

View File

@ -1,33 +0,0 @@
body {
background-color: #f8f9fa;
}
.navbar {
box-shadow: 0 2px 4px rgba(0,0,0,.04);
}
.card-header {
background-color: #ffffff;
border-bottom: 1px solid #dee2e6;
}
.status-badge {
font-size: 0.8rem;
padding: 0.3em 0.6em;
}
.action-icon {
color: #6c757d;
text-decoration: none;
margin: 0 4px;
transition: color 0.2s;
}
.action-icon:hover {
color: #0d6efd;
}
.action-icon.disabled {
color: #adb5bd;
pointer-events: none;
}

View File

@ -1 +0,0 @@
// This file can be used for custom JavaScript interactions in the future.

View File

@ -1,108 +0,0 @@
<?php
function setup_database() {
try {
$pdo = db();
// Check if tables already exist
$stmt = $pdo->query("SELECT 1 FROM equivalence_catalog LIMIT 1");
if ($stmt !== false && $stmt->fetch()) {
// Tables seem to exist, do nothing
return;
}
} catch (PDOException $e) {
// Table doesn't exist, proceed with creation. This is expected on first run.
}
try {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 1. Shipping Lines Table
$pdo->exec("CREATE TABLE IF NOT EXISTS shipping_lines (
ShippingLineCode VARCHAR(10) PRIMARY KEY,
ShippingLineName VARCHAR(255) NOT NULL,
IsActive BOOLEAN NOT NULL DEFAULT TRUE
)");
// 2. Customs Container Types Table
$pdo->exec("CREATE TABLE IF NOT EXISTS customs_container_types (
CustomsKey VARCHAR(10) PRIMARY KEY,
CustomsDescription VARCHAR(255) NOT NULL,
IsActive BOOLEAN NOT NULL DEFAULT TRUE
)");
// 3. N4 Container Types Table
$pdo->exec("CREATE TABLE IF NOT EXISTS n4_container_types (
N4Key VARCHAR(10) PRIMARY KEY,
N4Description VARCHAR(255) NOT NULL,
IsActive BOOLEAN NOT NULL DEFAULT TRUE,
CustomsKeyFK VARCHAR(10),
FOREIGN KEY (CustomsKeyFK) REFERENCES customs_container_types(CustomsKey)
)");
// 4. Equivalence Catalog Table
$pdo->exec("CREATE TABLE IF NOT EXISTS equivalence_catalog (
EquivalenceID INT AUTO_INCREMENT PRIMARY KEY,
ShippingLineCode VARCHAR(10),
CustomsKeyFK VARCHAR(10),
N4KeyFK VARCHAR(10),
EffectiveDate DATE NOT NULL,
IsActive BOOLEAN NOT NULL DEFAULT TRUE,
FOREIGN KEY (ShippingLineCode) REFERENCES shipping_lines(ShippingLineCode),
FOREIGN KEY (CustomsKeyFK) REFERENCES customs_container_types(CustomsKey),
FOREIGN KEY (N4KeyFK) REFERENCES n4_container_types(N4Key),
UNIQUE (ShippingLineCode, CustomsKeyFK, N4KeyFK)
)");
// 5. Audit Log Table
$pdo->exec("CREATE TABLE IF NOT EXISTS audit_log (
LogID INT AUTO_INCREMENT PRIMARY KEY,
EquivalenceIDFK INT,
Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
`User` VARCHAR(255),
Action VARCHAR(50),
OldValue TEXT,
NewValue TEXT,
FOREIGN KEY (EquivalenceIDFK) REFERENCES equivalence_catalog(EquivalenceID) ON DELETE SET NULL
)");
// --- MOCK DATA INSERTION ---
// Shipping Lines
$pdo->exec("INSERT INTO shipping_lines (ShippingLineCode, ShippingLineName) VALUES
('MSCU', 'Mediterranean Shipping Company'),
('ONEY', 'Ocean Network Express'),
('MAEU', 'Maersk Line')");
// Customs Types
$pdo->exec("INSERT INTO customs_container_types (CustomsKey, CustomsDescription) VALUES
('20GP', '20ft General Purpose'),
('40HC', '40ft High Cube'),
('20RF', '20ft Reefer')");
// N4 Types
$pdo->exec("INSERT INTO n4_container_types (N4Key, N4Description, CustomsKeyFK) VALUES
('GP20', 'General Purpose 20 FT', '20GP'),
('DV20', 'Dry Van 20 FT', '20GP'),
('HC40', 'High Cube 40 FT', '40HC'),
('HQ40', 'High Quality 40 FT', '40HC'),
('RF20', 'Refrigerated 20 FT', '20RF')");
// Equivalence Mappings
$pdo->exec("INSERT INTO equivalence_catalog (ShippingLineCode, CustomsKeyFK, N4KeyFK, EffectiveDate, IsActive) VALUES
('MSCU', '20GP', 'GP20', '2023-01-01', TRUE),
('MSCU', '40HC', 'HC40', '2023-01-01', TRUE),
('ONEY', '20GP', 'DV20', '2023-05-15', TRUE),
('ONEY', '40HC', 'HQ40', '2023-05-15', FALSE),
('MAEU', '20RF', 'RF20', '2024-02-20', TRUE)");
} catch (PDOException $e) {
// In a real app, you'd log this error.
// For this setup, we can die to see the error clearly.
die("DB Setup Failed: " . $e->getMessage());
}
}
// Run the setup
setup_database();

274
index.php
View File

@ -1,150 +1,150 @@
<?php
require_once 'db/config.php';
require_once 'db/setup.php';
$equivalences = [];
try {
$pdo = db();
$stmt = $pdo->query("
SELECT
eq.EquivalenceID,
sl.ShippingLineName,
cc.CustomsDescription,
n4.N4Description,
eq.EffectiveDate,
eq.IsActive
FROM
equivalence_catalog eq
JOIN
shipping_lines sl ON eq.ShippingLineCode = sl.ShippingLineCode
JOIN
customs_container_types cc ON eq.CustomsKeyFK = cc.CustomsKey
JOIN
n4_container_types n4 ON eq.N4KeyFK = n4.N4Key
ORDER BY
sl.ShippingLineName, eq.EffectiveDate DESC
");
$equivalences = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// For now, just show a simple error.
die("Could not fetch data: " . $e->getMessage());
}
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
?>
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Container Equivalence Catalog</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<?php
// Read project preview data from environment
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<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;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="#">Container Equivalences</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Equivalence Catalog</a>
</li>
<li class="nav-item">
<a class="nav-link text-muted" href="#">Customs Types <small>(soon)</small></a>
</li>
<li class="nav-item">
<a class="nav-link text-muted" href="#">N4 Types <small>(soon)</small></a>
</li>
<li class="nav-item">
<a class="nav-link text-muted" href="#">Shipping Lines <small>(soon)</small></a>
</li>
</ul>
<span class="navbar-text">
<i class="bi bi-person-circle me-1"></i> Logged in as: <strong>Administrator</strong>
</span>
</div>
</div>
</nav>
<main class="container mt-4">
<main>
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h4 class="mb-0">Shipping Line Equivalence Catalog</h4>
<button class="btn btn-primary disabled" disabled><i class="bi bi-plus-circle me-1"></i> Add New</button>
</div>
<div class="row mt-3">
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text"><i class="bi bi-search"></i></span>
<input type="text" class="form-control" placeholder="Search by description, line..." disabled>
</div>
</div>
<div class="col-md-4">
<select class="form-select" disabled>
<option selected>Filter by Active Status...</option>
<option value="1">Active</option>
<option value="0">Inactive</option>
</select>
</div>
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-striped table-hover mb-0">
<thead class="table-light">
<tr>
<th scope="col">Shipping Line</th>
<th scope="col">Customs Description</th>
<th scope="col">N4 Description</th>
<th scope="col">Effective Date</th>
<th scope="col">Status</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($equivalences)): ?>
<tr>
<td colspan="6" class="text-center text-muted p-4">No equivalence records found. The database might be empty.</td>
</tr>
<?php else: ?>
<?php foreach ($equivalences as $eq): ?>
<tr>
<td><?php echo htmlspecialchars($eq['ShippingLineName']); ?></td>
<td><?php echo htmlspecialchars($eq['CustomsDescription']); ?></td>
<td><?php echo htmlspecialchars($eq['N4Description']); ?></td>
<td><?php echo htmlspecialchars($eq['EffectiveDate']); ?></td>
<td>
<?php if ($eq['IsActive']): ?>
<span class="badge rounded-pill bg-success-subtle text-success-emphasis status-badge">Active</span>
<?php else: ?>
<span class="badge rounded-pill bg-danger-subtle text-danger-emphasis status-badge">Inactive</span>
<?php endif; ?>
</td>
<td>
<a href="#" class="action-icon disabled" title="Edit"><i class="bi bi-pencil-square"></i></a>
<a href="#" class="action-icon disabled" title="Delete"><i class="bi bi-trash"></i></a>
<a href="#" class="action-icon disabled" title="History"><i class="bi bi-clock-history"></i></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<div class="card-footer text-muted">
Displaying <?php echo count($equivalences); ?> records.
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
</footer>
</body>
</html>