Add offer management functionality and new offerAdder page

This commit is contained in:
Fabian Schieder 2026-04-06 21:03:01 +02:00
parent 41cd0bd5dd
commit 3de11faaac
4 changed files with 474 additions and 0 deletions

View File

@ -231,6 +231,9 @@ include 'header.php';
<a href="productAdder.php" class="auth__submit account__action-link"> <a href="productAdder.php" class="auth__submit account__action-link">
Produkt hinzufügen Produkt hinzufügen
</a> </a>
<a href="offerAdder.php" class="auth__submit account__action-link" style="margin-top: 10px; background-color: #f59e0b;">
Angebot hinzufügen
</a>
<a href="admin_users.php" class="auth__submit account__action-link" style="margin-top: 10px; background-color: #3b82f6;"> <a href="admin_users.php" class="auth__submit account__action-link" style="margin-top: 10px; background-color: #3b82f6;">
Benutzerverwaltung Benutzerverwaltung
</a> </a>

Binary file not shown.

View File

@ -0,0 +1,350 @@
-- MySQL Script generated by MySQL Workbench
-- Mon Apr 6 01:50:45 2026
-- Model: New Model Version: 1.0
-- MySQL Workbench Forward Engineering
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema FSST
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema FSST
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `FSST` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ;
USE `FSST` ;
-- -----------------------------------------------------
-- Table `FSST`.`attributes`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`attributes` (
`attributeID` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`unit` VARCHAR(50) NULL DEFAULT NULL,
`dataType` VARCHAR(20) NULL DEFAULT NULL,
PRIMARY KEY (`attributeID`))
ENGINE = InnoDB
AUTO_INCREMENT = 70
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`brands`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`brands` (
`brandID` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`brandID`))
ENGINE = InnoDB
AUTO_INCREMENT = 8
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`categories`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`categories` (
`categoryID` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`parentCategoryID` INT NULL DEFAULT NULL,
PRIMARY KEY (`categoryID`),
INDEX `categories_ibfk_1` (`parentCategoryID` ASC) VISIBLE,
CONSTRAINT `categories_ibfk_1`
FOREIGN KEY (`parentCategoryID`)
REFERENCES `FSST`.`categories` (`categoryID`)
ON DELETE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 26
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`categoryAttributes`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`categoryAttributes` (
`categoryID` INT NOT NULL,
`attributeID` INT NOT NULL,
PRIMARY KEY (`categoryID`, `attributeID`),
INDEX `attributeID` (`attributeID` ASC) VISIBLE,
CONSTRAINT `categoryAttributes_ibfk_1`
FOREIGN KEY (`categoryID`)
REFERENCES `FSST`.`categories` (`categoryID`),
CONSTRAINT `categoryAttributes_ibfk_2`
FOREIGN KEY (`attributeID`)
REFERENCES `FSST`.`attributes` (`attributeID`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`users`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`users` (
`userID` INT NOT NULL AUTO_INCREMENT,
`email` VARCHAR(255) NOT NULL,
`passwordHash` VARCHAR(255) NOT NULL,
`displayName` VARCHAR(255) NULL DEFAULT NULL,
`isActive` TINYINT(1) NOT NULL DEFAULT '1',
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`profilePicture` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`userID`),
UNIQUE INDEX `email` (`email` ASC) VISIBLE)
ENGINE = InnoDB
AUTO_INCREMENT = 45
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`notifications`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`notifications` (
`notificationID` INT NOT NULL AUTO_INCREMENT,
`userID` INT NOT NULL,
`title` VARCHAR(255) NOT NULL,
`message` TEXT NOT NULL,
`isRead` TINYINT(1) NOT NULL DEFAULT '0',
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`notificationID`),
INDEX `fk_notifications_user` (`userID` ASC) VISIBLE,
CONSTRAINT `fk_notifications_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 4
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`products`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`products` (
`productID` INT NOT NULL AUTO_INCREMENT,
`categoryID` INT NOT NULL,
`brandID` INT NOT NULL,
`model` VARCHAR(255) NOT NULL,
`description` TEXT NULL DEFAULT NULL,
`imagePath` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`productID`),
INDEX `categoryID` (`categoryID` ASC) VISIBLE,
INDEX `brandID` (`brandID` ASC) VISIBLE,
CONSTRAINT `products_ibfk_1`
FOREIGN KEY (`categoryID`)
REFERENCES `FSST`.`categories` (`categoryID`),
CONSTRAINT `products_ibfk_2`
FOREIGN KEY (`brandID`)
REFERENCES `FSST`.`brands` (`brandID`))
ENGINE = InnoDB
AUTO_INCREMENT = 1347
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`shops`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`shops` (
`shopID` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`website` VARCHAR(255) NULL DEFAULT NULL,
`logoPath` VARCHAR(255) NULL DEFAULT NULL,
`shippingTime` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`shopID`))
ENGINE = InnoDB
AUTO_INCREMENT = 7
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`offers`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`offers` (
`offerID` INT NOT NULL AUTO_INCREMENT,
`productID` INT NOT NULL,
`shopID` INT NOT NULL,
`price` DECIMAL(10,2) NOT NULL,
`shippingCost` DECIMAL(10,2) NULL DEFAULT NULL,
`inStock` TINYINT(1) NULL DEFAULT NULL,
`offerURL` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`offerID`),
INDEX `productID` (`productID` ASC) VISIBLE,
INDEX `shopID` (`shopID` ASC) VISIBLE,
CONSTRAINT `offers_ibfk_1`
FOREIGN KEY (`productID`)
REFERENCES `FSST`.`products` (`productID`),
CONSTRAINT `offers_ibfk_2`
FOREIGN KEY (`shopID`)
REFERENCES `FSST`.`shops` (`shopID`))
ENGINE = InnoDB
AUTO_INCREMENT = 10
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`priceAlerts`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`priceAlerts` (
`alertID` INT NOT NULL AUTO_INCREMENT,
`userID` INT NOT NULL,
`productID` INT NOT NULL,
`targetPrice` DECIMAL(10,2) NOT NULL,
`isActive` TINYINT(1) NOT NULL DEFAULT '1',
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`alertID`),
INDEX `fk_pricealerts_user` (`userID` ASC) VISIBLE,
INDEX `fk_pricealerts_product` (`productID` ASC) VISIBLE,
CONSTRAINT `fk_pricealerts_product`
FOREIGN KEY (`productID`)
REFERENCES `FSST`.`products` (`productID`)
ON DELETE CASCADE,
CONSTRAINT `fk_pricealerts_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 4
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`productAttributes`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`productAttributes` (
`productID` INT NOT NULL,
`attributeID` INT NOT NULL,
`valueString` VARCHAR(255) NULL DEFAULT NULL,
`valueNumber` DECIMAL(10,2) NULL DEFAULT NULL,
`valueBool` TINYINT(1) NULL DEFAULT NULL,
PRIMARY KEY (`productID`, `attributeID`),
INDEX `attributeID` (`attributeID` ASC) VISIBLE,
CONSTRAINT `productAttributes_ibfk_1`
FOREIGN KEY (`productID`)
REFERENCES `FSST`.`products` (`productID`),
CONSTRAINT `productAttributes_ibfk_2`
FOREIGN KEY (`attributeID`)
REFERENCES `FSST`.`attributes` (`attributeID`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`reviews`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`reviews` (
`reviewID` INT NOT NULL AUTO_INCREMENT,
`userID` INT NOT NULL,
`productID` INT NOT NULL,
`rating` INT NOT NULL,
`comment` TEXT NULL DEFAULT NULL,
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`reviewID`),
INDEX `fk_reviews_user` (`userID` ASC) VISIBLE,
INDEX `fk_reviews_product` (`productID` ASC) VISIBLE,
CONSTRAINT `fk_reviews_product`
FOREIGN KEY (`productID`)
REFERENCES `FSST`.`products` (`productID`)
ON DELETE CASCADE,
CONSTRAINT `fk_reviews_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 42
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`roles`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`roles` (
`roleID` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`roleID`),
UNIQUE INDEX `name` (`name` ASC) VISIBLE)
ENGINE = InnoDB
AUTO_INCREMENT = 4
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`userFavorites`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`userFavorites` (
`userID` INT NOT NULL,
`productID` INT NOT NULL,
`createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`userID`, `productID`),
INDEX `fk_favorites_product` (`productID` ASC) VISIBLE,
CONSTRAINT `fk_favorites_product`
FOREIGN KEY (`productID`)
REFERENCES `FSST`.`products` (`productID`)
ON DELETE CASCADE,
CONSTRAINT `fk_favorites_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`userRoles`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`userRoles` (
`userID` INT NOT NULL,
`roleID` INT NOT NULL,
PRIMARY KEY (`userID`, `roleID`),
INDEX `fk_userroles_role` (`roleID` ASC) VISIBLE,
CONSTRAINT `fk_userroles_role`
FOREIGN KEY (`roleID`)
REFERENCES `FSST`.`roles` (`roleID`)
ON DELETE CASCADE,
CONSTRAINT `fk_userroles_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- -----------------------------------------------------
-- Table `FSST`.`userSessions`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `FSST`.`userSessions` (
`sessionID` VARCHAR(128) NOT NULL,
`userID` INT NOT NULL,
`expiresAt` TIMESTAMP NOT NULL,
PRIMARY KEY (`sessionID`),
INDEX `fk_sessions_user` (`userID` ASC) VISIBLE,
CONSTRAINT `fk_sessions_user`
FOREIGN KEY (`userID`)
REFERENCES `FSST`.`users` (`userID`)
ON DELETE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

121
offerAdder.php Normal file
View File

@ -0,0 +1,121 @@
<?php
/**
* @file offerAdder.php
* @brief Angebot hinzufügen
*/
require_once __DIR__ . '/lib/bootstrap.php';
// Only ADMIN
if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('ADMIN', $_SESSION['user_roles'], true)) {
http_response_code(403);
include 'header.php';
echo '<main class="auth"><section class="auth__grid"><div class="auth__card">';
echo '<h2 class="auth__title">Zugriff verweigert</h2>';
echo '<p>Du hast keine Berechtigung, Angebote hinzuzufügen.</p>';
echo '</div></section></main>';
include 'footer.php';
exit;
}
$db = db_get_connection();
$message = '';
$messageType = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'add_offer') {
$productID = (int)$_POST['product_id'];
$shopID = (int)$_POST['shop_id'];
$price = (float)$_POST['price'];
$shippingCost = isset($_POST['shipping_cost']) && $_POST['shipping_cost'] !== '' ? (float)$_POST['shipping_cost'] : 0.00;
$inStock = isset($_POST['in_stock']) ? 1 : 0;
$offerURL = trim($_POST['offer_url']);
if ($productID > 0 && $shopID > 0 && $price >= 0) {
$stmt = $db->prepare("INSERT INTO offers (productID, shopID, price, shippingCost, inStock, offerURL) VALUES (?, ?, ?, ?, ?, ?)");
if ($stmt->execute([$productID, $shopID, $price, $shippingCost, $inStock, $offerURL])) {
$message = 'Angebot erfolgreich hinzugefügt!';
$messageType = 'success';
} else {
$message = 'Fehler beim Hinzufügen des Angebots.';
$messageType = 'error';
}
} else {
$message = 'Bitte alle Pflichtfelder korrekt ausfüllen.';
$messageType = 'error';
}
}
// Get all products for dropdown
$productsStmt = $db->query("SELECT productID, model FROM products ORDER BY model ASC");
$products = $productsStmt->fetchAll(PDO::FETCH_ASSOC);
// Get all shops for dropdown
$shopsStmt = $db->query("SELECT shopID, name FROM shops ORDER BY name ASC");
$shops = $shopsStmt->fetchAll(PDO::FETCH_ASSOC);
include 'header.php';
?>
<main class="page-main" style="padding: 2rem;">
<div class="container" style="max-width: 800px; margin: 0 auto; background: #fff; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
<h1 style="margin-bottom: 1.5rem;">Angebot hinzufügen</h1>
<?php if ($message): ?>
<div class="alert alert-<?php echo htmlspecialchars($messageType); ?>" style="padding:15px; margin-bottom: 20px; border-radius: 4px; background-color: <?php echo $messageType === 'success' ? '#d4edda' : '#f8d7da'; ?>; color: <?php echo $messageType === 'success' ? '#155724' : '#721c24'; ?>; border: 1px solid <?php echo $messageType === 'success' ? '#c3e6cb' : '#f5c6cb'; ?>;">
<?php echo htmlspecialchars($message); ?>
</div>
<?php endif; ?>
<form method="POST" action="offerAdder.php" style="display: flex; flex-direction: column; gap: 1.5rem;">
<input type="hidden" name="action" value="add_offer">
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
<label for="product_id" style="font-weight: 600;">Produkt auswählen *</label>
<select id="product_id" name="product_id" required style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
<option value="">-- Bitte wählen --</option>
<?php foreach ($products as $product): ?>
<option value="<?php echo htmlspecialchars($product['productID']); ?>" <?php echo (isset($_GET['productID']) && $_GET['productID'] == $product['productID']) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($product['model']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
<label for="shop_id" style="font-weight: 600;">Shop auswählen *</label>
<select id="shop_id" name="shop_id" required style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
<option value="">-- Bitte wählen --</option>
<?php foreach ($shops as $shop): ?>
<option value="<?php echo htmlspecialchars($shop['shopID']); ?>">
<?php echo htmlspecialchars($shop['name']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div style="display: flex; gap: 1rem;">
<div style="flex: 1; display: flex; flex-direction: column; gap: 0.5rem;">
<label for="price" style="font-weight: 600;">Preis () *</label>
<input type="number" id="price" name="price" step="0.01" min="0" required style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
</div>
<div style="flex: 1; display: flex; flex-direction: column; gap: 0.5rem;">
<label for="shipping_cost" style="font-weight: 600;">Versandkosten ()</label>
<input type="number" id="shipping_cost" name="shipping_cost" step="0.01" min="0" value="0.00" style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
</div>
</div>
<div style="display: flex; align-items: center; gap: 0.5rem;">
<input type="checkbox" id="in_stock" name="in_stock" value="1" checked style="width: 18px; height: 18px;">
<label for="in_stock" style="font-weight: 600; cursor: pointer;">Auf Lager</label>
</div>
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
<label for="offer_url" style="font-weight: 600;">Angebots-URL</label>
<input type="url" id="offer_url" name="offer_url" placeholder="https://" style="width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px;">
</div>
<button type="submit" style="padding: 12px 20px; background: #007bff; color: white; font-weight: bold; border: none; border-radius: 4px; cursor: pointer; align-self: flex-start; text-transform: uppercase; font-size: 0.9rem;">Angebot hinzufügen</button>
</form>
</div>
</main>
<?php include 'footer.php'; ?>