Initial commit: Website
This commit is contained in:
commit
3a8948c60c
5
.gitignore
vendored
Executable file
5
.gitignore
vendored
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
/vendor/
|
||||||
|
/node_modules/
|
||||||
|
.env
|
||||||
|
*.log
|
||||||
|
.cache/
|
||||||
9
.htaccess
Executable file
9
.htaccess
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
AuthType Basic
|
||||||
|
AuthName "Geschützter Bereich"
|
||||||
|
AuthUserFile /FSST/Website/.htpasswd
|
||||||
|
Require valid-user
|
||||||
|
|
||||||
|
# .htpasswd vor Auslieferung schützen
|
||||||
|
<Files ".htpasswd">
|
||||||
|
Require all denied
|
||||||
|
</Files>
|
||||||
0
account.php
Executable file
0
account.php
Executable file
0
footer.php
Executable file
0
footer.php
Executable file
169
index.php
Executable file
169
index.php
Executable file
@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
// ======================================
|
||||||
|
// Fehleranzeige (DEV)
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
// ======================================
|
||||||
|
// DB-Verbindung
|
||||||
|
$con = mysqli_connect("localhost", "FSST", "L9wUNZZ9Qkbt", "FSST");
|
||||||
|
mysqli_set_charset($con, "utf8");
|
||||||
|
|
||||||
|
if (!$con) {
|
||||||
|
die("DB Fehler: " . mysqli_connect_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================
|
||||||
|
// GET-Parameter
|
||||||
|
$categoryID = isset($_GET['category']) ? (int)$_GET['category'] : 0;
|
||||||
|
$maxPrice = isset($_GET['maxPrice']) ? (float)$_GET['maxPrice'] : 0;
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Preisvergleich – Demo</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<?php include 'navbar.php'; ?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>💻 Preisvergleich – Beispielanwendung</h1>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// ======================================
|
||||||
|
// Kategorien laden
|
||||||
|
$categories = mysqli_query($con, "
|
||||||
|
SELECT categoryID, name
|
||||||
|
FROM categories
|
||||||
|
WHERE parentCategoryID IS NOT NULL
|
||||||
|
ORDER BY name
|
||||||
|
");
|
||||||
|
?>
|
||||||
|
|
||||||
|
<form method="get">
|
||||||
|
Kategorie:
|
||||||
|
<select name="category">
|
||||||
|
<option value="0">Alle</option>
|
||||||
|
<?php while ($c = mysqli_fetch_assoc($categories)): ?>
|
||||||
|
<option value="<?= $c['categoryID'] ?>"
|
||||||
|
<?= $categoryID === (int)$c['categoryID'] ? 'selected' : '' ?>>
|
||||||
|
<?= htmlspecialchars($c['name']) ?>
|
||||||
|
</option>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
Max Preis (€):
|
||||||
|
<input type="number" step="1" name="maxPrice" value="<?= htmlspecialchars($maxPrice) ?>">
|
||||||
|
|
||||||
|
<button type="submit">Anzeigen</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// ======================================
|
||||||
|
// Produkte + günstigster Preis
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
p.productID,
|
||||||
|
p.model,
|
||||||
|
b.name AS brand,
|
||||||
|
c.name AS category,
|
||||||
|
MIN(o.price + o.shippingCost) AS bestPrice
|
||||||
|
FROM products p
|
||||||
|
JOIN brands b ON p.brandID = b.brandID
|
||||||
|
JOIN categories c ON p.categoryID = c.categoryID
|
||||||
|
JOIN offers o ON o.productID = p.productID
|
||||||
|
WHERE 1
|
||||||
|
";
|
||||||
|
|
||||||
|
$params = [];
|
||||||
|
$types = "";
|
||||||
|
|
||||||
|
if ($categoryID > 0) {
|
||||||
|
$sql .= " AND p.categoryID = ?";
|
||||||
|
$params[] = $categoryID;
|
||||||
|
$types .= "i";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($maxPrice > 0) {
|
||||||
|
$sql .= " AND (o.price + o.shippingCost) <= ?";
|
||||||
|
$params[] = $maxPrice;
|
||||||
|
$types .= "d";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= " GROUP BY p.productID ORDER BY bestPrice ASC";
|
||||||
|
|
||||||
|
$stmt = mysqli_prepare($con, $sql);
|
||||||
|
if ($params) {
|
||||||
|
mysqli_stmt_bind_param($stmt, $types, ...$params);
|
||||||
|
}
|
||||||
|
mysqli_stmt_execute($stmt);
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
// ======================================
|
||||||
|
// Ausgabe
|
||||||
|
while ($p = mysqli_fetch_assoc($result)):
|
||||||
|
?>
|
||||||
|
<div class="product">
|
||||||
|
<strong><?= htmlspecialchars($p['brand']) ?> <?= htmlspecialchars($p['model']) ?></strong><br>
|
||||||
|
Kategorie: <?= htmlspecialchars($p['category']) ?><br>
|
||||||
|
💰 Ab <?= number_format($p['bestPrice'], 2, ',', '.') ?> €
|
||||||
|
|
||||||
|
<div class="spec">
|
||||||
|
<strong>Specs:</strong><br>
|
||||||
|
<?php
|
||||||
|
$specs = mysqli_query($con, "
|
||||||
|
SELECT a.name, a.unit,
|
||||||
|
pa.valueString, pa.valueNumber, pa.valueBool
|
||||||
|
FROM productAttributes pa
|
||||||
|
JOIN attributes a ON pa.attributeID = a.attributeID
|
||||||
|
WHERE pa.productID = {$p['productID']}
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($s = mysqli_fetch_assoc($specs)) {
|
||||||
|
echo htmlspecialchars($s['name']) . ": ";
|
||||||
|
|
||||||
|
if ($s['valueString'] !== null) echo htmlspecialchars($s['valueString']);
|
||||||
|
elseif ($s['valueNumber'] !== null) echo htmlspecialchars($s['valueNumber']) . " " . $s['unit'];
|
||||||
|
elseif ($s['valueBool'] !== null) echo $s['valueBool'] ? "Ja" : "Nein";
|
||||||
|
|
||||||
|
echo "<br>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="offer">
|
||||||
|
<strong>Angebote:</strong><br>
|
||||||
|
<?php
|
||||||
|
$offers = mysqli_query($con, "
|
||||||
|
SELECT s.name, o.price, o.shippingCost
|
||||||
|
FROM offers o
|
||||||
|
JOIN shops s ON o.shopID = s.shopID
|
||||||
|
WHERE o.productID = {$p['productID']}
|
||||||
|
ORDER BY o.price ASC
|
||||||
|
");
|
||||||
|
|
||||||
|
while ($o = mysqli_fetch_assoc($offers)) {
|
||||||
|
$total = $o['price'] + $o['shippingCost'];
|
||||||
|
echo htmlspecialchars($o['name']) . ": "
|
||||||
|
. number_format($total, 2, ',', '.') . " €<br>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<?php mysqli_close($con); ?>
|
||||||
19
navbar.php
Executable file
19
navbar.php
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
$currentPage = basename($_SERVER['PHP_SELF']);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<nav class="navbar">
|
||||||
|
<ul>
|
||||||
|
<input type="text" name="q" placeholder="Produkt Suchen..." required>
|
||||||
|
<button type="submit">Suchen</button>
|
||||||
|
<li class="<?= $currentPage === 'index.php' ? 'active' : '' ?>">
|
||||||
|
<a href="index.php">Wunschliste</a>
|
||||||
|
</li>
|
||||||
|
<li class="<?= $currentPage === 'produkte.php' ? 'active' : '' ?>">
|
||||||
|
<a href="produkte.php">Wahrenkorb</a>
|
||||||
|
</li>
|
||||||
|
<li class="<?= $currentPage === 'kontakt.php' ? 'active' : '' ?>">
|
||||||
|
<a href="kontakt.php">Account</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
258
style.css
Executable file
258
style.css
Executable file
@ -0,0 +1,258 @@
|
|||||||
|
/* ================================
|
||||||
|
Modernes Preisvergleich-Stylesheet
|
||||||
|
================================ */
|
||||||
|
|
||||||
|
/* --- CSS Reset (leichtgewichtig) --- */
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Root-Variablen --- */
|
||||||
|
:root {
|
||||||
|
--bg-main: #f4f6f8;
|
||||||
|
--bg-card: #ffffff;
|
||||||
|
--color-primary: #2563eb;
|
||||||
|
--color-secondary: #64748b;
|
||||||
|
--color-text: #0f172a;
|
||||||
|
--color-muted: #475569;
|
||||||
|
--border-radius: 10px;
|
||||||
|
--shadow-soft: 0 6px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Grundlayout --- */
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 32px;
|
||||||
|
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, sans-serif;
|
||||||
|
background-color: var(--bg-main);
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Überschrift --- */
|
||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Formular --- */
|
||||||
|
form {
|
||||||
|
background: var(--bg-card);
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
form label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
select,
|
||||||
|
input[type="number"] {
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #cbd5f5;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
select:focus,
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Button --- */
|
||||||
|
button {
|
||||||
|
padding: 9px 16px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: none;
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #1d4ed8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Produktkarte --- */
|
||||||
|
.product {
|
||||||
|
background: var(--bg-card);
|
||||||
|
padding: 18px 22px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Produkt-Titel */
|
||||||
|
.product > strong {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Preis --- */
|
||||||
|
.product .price {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Specs --- */
|
||||||
|
.spec {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px solid #e5e7eb;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Angebote --- */
|
||||||
|
.offer {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px dashed #e5e7eb;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Responsive Feinschliff --- */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Elegant Dark Mode – refined UI
|
||||||
|
====================================== */
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
/* Background Layers */
|
||||||
|
--bg-main: #0b0f19; /* App-Hintergrund */
|
||||||
|
--bg-card: #111827; /* Cards */
|
||||||
|
--bg-input: #020617; /* Inputs */
|
||||||
|
|
||||||
|
/* Text */
|
||||||
|
--color-text: #e5e7eb;
|
||||||
|
--color-muted: #9ca3af;
|
||||||
|
|
||||||
|
/* Accent */
|
||||||
|
--color-primary: #60a5fa; /* sanfteres Blau */
|
||||||
|
|
||||||
|
/* Borders & Shadow */
|
||||||
|
--border-soft: #1e293b;
|
||||||
|
--shadow-soft: 0 12px 40px rgba(0, 0, 0, 0.65);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background:
|
||||||
|
radial-gradient(1200px at top, #111827 0%, var(--bg-main) 60%);
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cards */
|
||||||
|
form,
|
||||||
|
.product {
|
||||||
|
background:
|
||||||
|
linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(255,255,255,0.02),
|
||||||
|
rgba(0,0,0,0.15)
|
||||||
|
),
|
||||||
|
var(--bg-card);
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
border: 1px solid var(--border-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inputs */
|
||||||
|
select,
|
||||||
|
input[type="number"] {
|
||||||
|
background: var(--bg-input);
|
||||||
|
color: var(--color-text);
|
||||||
|
border: 1px solid var(--border-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
select:focus,
|
||||||
|
input:focus {
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
box-shadow: 0 0 0 1px var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button */
|
||||||
|
button {
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
#60a5fa,
|
||||||
|
#3b82f6
|
||||||
|
);
|
||||||
|
color: #020617;
|
||||||
|
box-shadow: 0 4px 12px rgba(96, 165, 250, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
filter: brightness(1.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Produkttext */
|
||||||
|
.product > strong {
|
||||||
|
color: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specs / Offers */
|
||||||
|
.spec,
|
||||||
|
.offer {
|
||||||
|
border-top: 1px solid var(--border-soft);
|
||||||
|
color: var(--color-muted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------NAV-BAR-----------------------*/
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background: #1e1e1e;
|
||||||
|
padding: 12px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a {
|
||||||
|
color: #ddd;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar li.active a {
|
||||||
|
color: #4fc3f7;
|
||||||
|
border-bottom: 2px solid #4fc3f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------*/
|
||||||
Loading…
Reference in New Issue
Block a user