1
0

SMP all works

This commit is contained in:
Sytnyk Yehor
2025-06-05 12:21:37 +03:00
parent bdcbdb850a
commit d22b7ddcaf
34 changed files with 4932 additions and 0 deletions

View File

@ -0,0 +1,4 @@
> [!NOTE]
> Викладач: Сокорчук І. П.
>
> Оцінка: In Progress

View File

@ -0,0 +1,92 @@
<?php
session_start();
require_once 'src/Database/DB.php';
require_once 'src/Database/CartRepository.php';
require_once 'src/Controllers/HomeController.php';
require_once 'src/Controllers/ItemsController.php';
require_once 'src/Controllers/CartController.php';
require_once 'src/Controllers/AuthController.php';
require_once 'src/Controllers/ProfileController.php';
$db = new DB("shop.db");
$request = $_GET['page'] ?? 'home';
$action = $_GET['action'] ?? 'index';
$protected_pages = ['home', 'items', 'cart', 'profile'];
$public_pages = ['login', 'register'];
if (in_array($request, $protected_pages) && !isset($_SESSION['user'])) {
header('Location: ?page=404');
exit();
}
try {
switch ($request) {
case 'home':
$controller = new HomeController($db);
$controller->index();
break;
case 'items':
$controller = new ItemsController($db);
$controller->index();
break;
case 'cart':
$controller = new CartController($db);
if ($action === 'add' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->add();
} elseif ($action === 'remove' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->remove();
} elseif ($action === 'clear' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->clear();
} else {
$controller->index();
}
break;
case 'login':
$controller = new AuthController($db);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->login();
} else {
$controller->showLogin();
}
break;
case 'register':
$controller = new AuthController($db);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->register();
} else {
$controller->showRegister();
}
break;
case 'logout':
$controller = new AuthController($db);
$controller->logout();
break;
case 'profile':
$controller = new ProfileController($db);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$controller->updateProfile();
} else {
$controller->showProfile();
}
break;
default:
http_response_code(404);
include 'templates/pages/404.php';
break;
}
} catch (Exception $e) {
error_log("Application error: " . $e->getMessage());
http_response_code(500);
include 'templates/pages/error.php';
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -0,0 +1,43 @@
body {
font-family: monospace;
background-color: #f0f0f0;
color: #333;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
header,
footer {
background-color: #333;
color: #fff;
padding: 10px 20px;
text-align: center;
}
nav a:not(:hover) {
text-decoration: none;
}
.container {
flex: 1;
padding: 20px;
max-width: 800px;
margin: 20px auto;
background-color: #fff;
border: 1px solid #ccc;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.product-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.product-list>* {
border: 1px solid #eee;
padding: 10px;
}

View File

@ -0,0 +1,109 @@
<?php
class AuthController
{
private $db;
public function __construct(DB $db)
{
$this->db = $db;
}
public function showLogin(): void
{
if (isset($_SESSION['user'])) {
header('Location: ?page=home');
exit();
}
$data = ['title' => 'Вхід в систему'];
$this->render('login', $data);
}
public function login(): void
{
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$error = '';
if (empty($username) || empty($password)) {
$error = 'Заповніть всі поля';
} else {
try {
$user = $this->db->authenticate_user($username, $password);
if ($user) {
$_SESSION['user'] = $user;
header('Location: ?page=home');
exit();
} else {
$error = 'Невірні дані для входу';
}
} catch (DbException $e) {
$error = 'Помилка системи';
error_log("Login error: " . $e->getMessage());
}
}
$data = ['title' => 'Вхід в систему', 'error' => $error];
$this->render('login', $data);
}
public function showRegister(): void
{
if (isset($_SESSION['user'])) {
header('Location: ?page=home');
exit();
}
$data = ['title' => 'Реєстрація'];
$this->render('register', $data);
}
public function register(): void
{
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$name = trim($_POST['name'] ?? '');
$surname = trim($_POST['surname'] ?? '');
$age = (int)($_POST['age'] ?? 0);
$error = '';
if (empty($username) || empty($password) || empty($name)) {
$error = 'Заповніть всі обов\'язкові поля';
} elseif (strlen($password) < 6) {
$error = 'Пароль повинен містити мінімум 6 символів';
} else {
try {
if ($this->db->register_user($username, $password, $name, $surname, $age)) {
$user = $this->db->authenticate_user($username, $password);
$_SESSION['user'] = $user;
header('Location: ?page=home');
exit();
} else {
$error = 'Користувач з таким іменем вже існує';
}
} catch (DbException $e) {
$error = 'Помилка реєстрації';
error_log("Registration error: " . $e->getMessage());
}
}
$data = ['title' => 'Реєстрація', 'error' => $error];
$this->render('register', $data);
}
public function logout(): void
{
session_destroy();
header('Location: ?page=login');
exit();
}
/**
* @param array<int,mixed> $data
*/
private function render(string $template, array $data = []): void
{
extract($data);
include 'templates/pages/' . $template . '.php';
}
}

View File

@ -0,0 +1,77 @@
<?php
class CartController
{
private $cartRepo;
public function __construct(DB $db)
{
$this->cartRepo = new CartRepository($db);
}
public function index(): void
{
$data = [
'title' => 'Кошик',
'cart_items' => $this->cartRepo->getItems(),
'cart_total' => $this->cartRepo->getTotal(),
'cart_count' => $this->cartRepo->getCount(),
'user' => $_SESSION['user']
];
$this->render('cart', $data);
}
public function add(): void
{
$product_id = filter_input(INPUT_POST, 'product_id', FILTER_VALIDATE_INT);
$quantity = filter_input(INPUT_POST, 'quantity', FILTER_VALIDATE_INT);
if ($product_id !== false && $product_id !== null && $quantity !== false && $quantity !== null) {
try {
$this->cartRepo->addItem($product_id, $quantity);
} catch (DbException $e) {
error_log("Cart handling error: " . $e->getMessage());
}
}
header('Location: ?page=items');
exit();
}
public function remove(): void
{
$product_id = filter_input(INPUT_POST, 'product_id', FILTER_VALIDATE_INT);
if ($product_id !== false && $product_id !== null) {
try {
$this->cartRepo->removeItem($product_id);
} catch (DbException $e) {
error_log("Cart handling error: " . $e->getMessage());
}
}
header('Location: ?page=cart');
exit();
}
public function clear(): void
{
try {
$this->cartRepo->clear();
} catch (DbException $e) {
error_log("Cart handling error: " . $e->getMessage());
}
header('Location: ?page=cart');
exit();
}
/**
* @param array<int,mixed> $data
*/
private function render(string $template, array $data = []): void
{
extract($data);
include 'templates/pages/' . $template . '.php';
}
}

View File

@ -0,0 +1,30 @@
<?php
class HomeController
{
private $cartRepo;
public function __construct(DB $db)
{
$this->cartRepo = new CartRepository($db);
}
public function index(): void
{
$data = [
'title' => 'Головна сторінка',
'cart_count' => $this->cartRepo->getCount(),
'user' => $_SESSION['user']
];
$this->render('home', $data);
}
/**
* @param array<int,mixed> $data
*/
private function render(string $template, array $data = []): void
{
extract($data);
include 'templates/pages/' . $template . '.php';
}
}

View File

@ -0,0 +1,33 @@
<?php
class ItemsController
{
private $db;
private $cartRepo;
public function __construct(DB $db)
{
$this->db = $db;
$this->cartRepo = new CartRepository($db);
}
public function index(): void
{
$data = [
'title' => 'Сторінка товарів',
'items' => $this->db->get_items(),
'cart_count' => $this->cartRepo->getCount(),
'user' => $_SESSION['user']
];
$this->render('items', $data);
}
/**
* @param array<int,mixed> $data
*/
private function render(string $template, array $data = []): void
{
extract($data);
include 'templates/pages/' . $template . '.php';
}
}

View File

@ -0,0 +1,96 @@
<?php
class ProfileController
{
private $db;
public function __construct(DB $db)
{
$this->db = $db;
}
public function showProfile(): void
{
$data = ['title' => 'Профіль'];
$this->render('profile', $data);
}
public function updateProfile(): void
{
$user = $_SESSION['user'];
$id = $user['id'];
$name = trim($_POST['name'] ?? $user['name']);
$surname = trim($_POST['surname'] ?? $user['surname']);
$age = (int)($_POST['age'] ?? $user['age']);
$description = trim($_POST['description'] ?? $user['description']);
$photo_path = $user['photo_path'];
$error = '';
if (mb_strlen($name) < 2 && mb_strlen($surname) < 2) {
$error = "Ім'я та прізвище повинні мати довжину більше 1 символа";
$data = ['title' => 'Профіль', 'error' => $error];
$this->render('profile', $data);
return;
}
if (mb_strlen($description) < 50) {
$error = 'Біоаграфія не може бути менше 50 символів';
$data = ['title' => 'Профіль', 'error' => $error];
$this->render('profile', $data);
return;
}
if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
if (!in_array($_FILES['photo']['type'], ['image/jpeg', 'image/png'])) {
$error = 'Неправильний формат файлу';
$data = ['title' => 'Профіль', 'error' => $error];
$this->render('profile', $data);
return;
}
$uploads = 'uploads/';
if (!is_dir($uploads)) {
mkdir($uploads, 0755, true);
}
$new_path = $uploads . $id . '-' . time() . '.' . pathinfo($_FILES['photo']['name'], PATHINFO_EXTENSION);
if (!move_uploaded_file($_FILES['photo']['tmp_name'], $new_path)) {
$error = 'Помилка під час переміщення файлу';
$data = ['title' => 'Профіль', 'error' => $error];
$this->render('profile', $data);
return;
}
$photo_path = $new_path;
}
try {
$success = $this->db->update_user($id, $name, $surname, $description, $photo_path, $age);
if ($success) {
$user = $this->db->get_user_by_id($id);
$_SESSION['user'] = $user;
} else {
$error = 'Під час оновлення даних сталася помилка';
}
header('Location: ?page=profile');
exit();
} catch (DbException $e) {
$error = 'Помилка оновлення профілю';
error_log("Profile update error: " . $e->getMessage());
}
$data = ['title' => 'Профіль', 'error' => $error];
$this->render('profile', $data);
}
/**
* @param array<int,mixed> $data
*/
private function render(string $template, array $data = []): void
{
extract($data);
include 'templates/pages/' . $template . '.php';
}
}

View File

@ -0,0 +1,45 @@
<?php
class CartRepository
{
private $db;
public function __construct(DB $db)
{
$this->db = $db;
}
public function getItems(): array
{
return $this->db->get_cart();
}
public function getTotal(): float
{
return $this->db->get_cart_total();
}
public function getCount(): int
{
return $this->db->get_cart_count();
}
public function addItem(int $id, int $quantity): bool
{
return $this->db->add_to_cart($id, $quantity);
}
public function removeItem(int $id): bool
{
return $this->db->remove_from_cart($id);
}
public function clear(): bool
{
return $this->db->empty_cart();
}
public function getItemQuantity(int $id): int
{
return $this->db->get_cart_item_quantity($id);
}
}

View File

@ -0,0 +1,394 @@
<?php
class DbException extends Exception {}
class DB
{
private $pdo;
/**
* Initializes database
*
* @param string $db_path
* @throws DbException If there's a database error.
*/
public function __construct($db_path)
{
try {
$this->pdo = new PDO("sqlite:" . $db_path);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
throw new DbException("Connection to DB failed.\nCaused by: " . $e->getMessage());
}
try {
$this->pdo->exec("
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
name TEXT NOT NULL,
surname TEXT NOT NULL,
description TEXT NULL,
photo_path TEXT NULL,
age INTEGER DEFAULT 0
);
");
if ($this->pdo->query("SELECT COUNT(*) FROM users;")->fetchColumn() == 0) {
$default_password = password_hash('admin123', PASSWORD_DEFAULT);
$this->pdo->exec("
INSERT INTO users (username, password, name, surname, description, age)
VALUES ('admin', '$default_password', 'Адміністратор', 'Адміністратор', 'Адміністратор', 25);
");
}
} catch (PDOException $e) {
throw new DbException("Error initialising users table.\nCaused by: " . $e->getMessage());
}
try {
$this->pdo->exec("
CREATE TABLE IF NOT EXISTS items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL
);
");
if ($this->pdo->query("SELECT COUNT(id) FROM items;")->fetchColumn() == 0) {
$this->pdo->exec("
INSERT INTO items (name, price) VALUES ('Молоко пастеризоване', 32.50);
INSERT INTO items (name, price) VALUES ('Хліб чорний', 18.00);
INSERT INTO items (name, price) VALUES ('Сир білий', 85.00);
INSERT INTO items (name, price) VALUES ('Сметана 20%', 45.80);
INSERT INTO items (name, price) VALUES ('Кефір 1%', 28.50);
INSERT INTO items (name, price) VALUES ('Вода газована', 25.00);
INSERT INTO items (name, price) VALUES ('Печиво \"Весна\"', 42.30);
INSERT INTO items (name, price) VALUES ('Масло вершкове', 125.00);
INSERT INTO items (name, price) VALUES ('Йогурт натуральний', 38.90);
INSERT INTO items (name, price) VALUES ('Сік апельсиновий', 55.00);
");
}
} catch (PDOException $e) {
throw new DbException("Error initialising items table.\nCaused by: " . $e->getMessage());
}
try {
$this->pdo->exec("
CREATE TABLE IF NOT EXISTS cart (
id INTEGER NOT NULL UNIQUE,
count INTEGER NOT NULL,
FOREIGN KEY(id) REFERENCES items(id) ON DELETE CASCADE
);
");
} catch (PDOException $e) {
throw new DbException("Error initialising cart table.\nCaused by: " . $e->getMessage());
}
}
/**
* Updates user by id
* @param int $id
* @param string $name
* @param string $surname
* @param string $description
* @param int $age
* @param string $photo_path
*/
public function update_user($id, $name, $surname, $description, $photo_path, $age): bool
{
try {
$stmt = $this->pdo->prepare("
UPDATE users
SET name = :name, surname = :surname, description = :description, age = :age, photo_path = :photo_path
WHERE id = :id
");
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':surname', $surname, PDO::PARAM_STR);
$stmt->bindParam(':description', $description, PDO::PARAM_STR);
$stmt->bindParam(':photo_path', $photo_path, PDO::PARAM_STR);
$stmt->bindParam(':age', $age, PDO::PARAM_INT);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
return $stmt->execute();
} catch (PDOException $e) {
throw new DbException("Error updating user.\nCaused by: " . $e->getMessage());
}
}
/**
* Authenticate user by username and password
* @param mixed $username
* @param mixed $password
*/
public function authenticate_user($username, $password): ?array
{
try {
$stmt = $this->pdo->prepare("SELECT id, username, name, surname, description, photo_path, age FROM users WHERE username = :username");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
$stmt = $this->pdo->prepare("SELECT password FROM users WHERE username = :username");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->execute();
$stored_password = $stmt->fetchColumn();
if (password_verify($password, $stored_password)) {
return $user;
}
}
return null;
} catch (PDOException $e) {
throw new DbException("Error authenticating user.\nCaused by: " . $e->getMessage());
}
}
/**
* Register new user
* @param mixed $username
* @param mixed $password
* @param mixed $name
* @param mixed $surname
* @param mixed $age
*/
public function register_user($username, $password, $name, $surname, $age): bool
{
try {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $this->pdo->prepare("INSERT INTO users (username, password, name, surname, age) VALUES (:username, :password, :name, :surname, :age)");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':password', $hashed_password, PDO::PARAM_STR);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':surname', $surname, PDO::PARAM_STR);
$stmt->bindParam(':age', $age, PDO::PARAM_INT);
return $stmt->execute();
} catch (PDOException $e) {
throw new DbException("Error registering user.\nCaused by: " . $e->getMessage());
}
}
/**
* Get user by ID
* @param mixed $id
*/
public function get_user_by_id($id): ?array
{
try {
$stmt = $this->pdo->prepare("SELECT id, username, name, surname, description, age, photo_path FROM users WHERE id = :id");
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ?: null;
} catch (PDOException $e) {
throw new DbException("Error retrieving user by ID.\nCaused by: " . $e->getMessage());
}
}
/**
* Fetches all items from the database.
*
* @return array[]
* @throws DbException If there's a database error.
*/
public function get_items(): array
{
try {
$stmt = $this->pdo->query("SELECT id, name, price FROM items ORDER BY id;");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
throw new DbException("Error retrieving data from the items table.\nCaused by: " . $e->getMessage());
}
}
/**
* Fetches a specific item by ID
*
* @param int $id
* @return array|null
* @throws DbException If there's a database error.
*/
public function get_item_by_id($id): ?array
{
try {
$stmt = $this->pdo->prepare("SELECT id, name, price FROM items WHERE id = :id;");
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result ?: null;
} catch (PDOException $e) {
throw new DbException("Error retrieving item by ID.\nCaused by: " . $e->getMessage());
}
}
/**
* Fetches all items in the cart from the database without price info.
*
* @return array[]
* @throws DbException If there's a database error.
*/
public function get_cart_no_price(): array
{
try {
$stmt = $this->pdo->query(
"SELECT items.name, cart.count
FROM cart
INNER JOIN items ON cart.id = items.id
ORDER BY cart.id;"
);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
throw new DbException("Error retrieving cart items without price.\nCaused by: " . $e->getMessage());
}
}
/**
* Fetches all items in the cart from the database.
*
* @return array[]
* @throws DbException If there's a database error.
*/
public function get_cart(): array
{
try {
$stmt = $this->pdo->query(
"SELECT
cart.id,
items.name,
items.price,
cart.count,
ROUND(items.price * cart.count, 2) as total_price
FROM cart
INNER JOIN items ON cart.id = items.id
ORDER BY cart.id;"
);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
throw new DbException("Error retrieving cart items.\nCaused by: " . $e->getMessage());
}
}
/**
* Get total items count in cart
*
* @return int
* @throws DbException If there's a database error.
*/
public function get_cart_count(): int
{
try {
$stmt = $this->pdo->query("SELECT COALESCE(SUM(count), 0) FROM cart;");
return (int)$stmt->fetchColumn();
} catch (PDOException $e) {
throw new DbException("Error getting cart count.\nCaused by: " . $e->getMessage());
}
}
/**
* Get total price of all items in cart
*
* @return float
* @throws DbException If there's a database error.
*/
public function get_cart_total(): float
{
try {
$stmt = $this->pdo->query(
"SELECT COALESCE(SUM(items.price * cart.count), 0.0)
FROM cart
INNER JOIN items ON cart.id = items.id;"
);
return (float)$stmt->fetchColumn();
} catch (PDOException $e) {
throw new DbException("Error calculating cart total.\nCaused by: " . $e->getMessage());
}
}
/**
* Add item to the cart or update its quantity.
*
* @param int $id
* @param int $count
*
* @return bool
* @throws DbException If there's a database error or item doesn't exist.
*/
public function add_to_cart($id, $count): bool
{
try {
// Check if the item exists
$item = $this->get_item_by_id($id);
if (!$item) {
throw new DbException("Item with ID $id does not exist.");
}
// If count is 0 or less, remove the item from the cart
if ($count <= 0) {
return $this->remove_from_cart($id);
}
// Insert or update the cart item
$stmt = $this->pdo->prepare(
"INSERT INTO cart (id, count)
VALUES (:id, :count)
ON CONFLICT(id) DO UPDATE SET
count = excluded.count;"
);
return $stmt->execute(['id' => $id, 'count' => $count]);
} catch (PDOException $e) {
throw new DbException("Error adding/updating item in the cart.\nCaused by: " . $e->getMessage());
}
}
/**
* Empty the cart
*
* @return bool
* @throws DbException If there's a database error.
*/
public function empty_cart(): bool
{
try {
$stmt = $this->pdo->prepare("DELETE FROM cart");
return $stmt->execute();
} catch (PDOException $e) {
throw new DbException("Error removing item from the cart.\nCaused by: " . $e->getMessage());
}
}
/**
* Remove an item from the cart
*
* @param int $id
*
* @return bool
* @throws DbException If there's a database error.
*/
public function remove_from_cart($id): bool
{
try {
$stmt = $this->pdo->prepare("DELETE FROM cart WHERE id = :id");
return $stmt->execute(['id' => $id]);
} catch (PDOException $e) {
throw new DbException("Error removing item from the cart.\nCaused by: " . $e->getMessage());
}
}
/**
* Get item quantity in cart
*
* @param int $id
* @return int The quantity of the item in the cart, or 0 if not found.
* @throws DbException If there's a database error.
*/
public function get_cart_item_quantity(int $id): int
{
try {
$stmt = $this->pdo->prepare("SELECT count FROM cart WHERE id = :id");
$stmt->execute(['id' => $id]);
$result = $stmt->fetchColumn();
return $result !== false ? (int)$result : 0;
} catch (PDOException $e) {
throw new DbException("Error getting cart item quantity.\nCaused by: " . $e->getMessage());
}
}
}

View File

@ -0,0 +1,5 @@
<?php if (isset($error) && !empty($error)): ?>
<div style="color: red; margin-bottom: 20px; padding: 10px; border: 1px solid red; background: #ffebee;">
<?php echo htmlspecialchars($error); ?>
</div>
<?php endif; ?>

View File

@ -0,0 +1,5 @@
<footer>
<?php $cart_count = $cart_count ?? 0;
include 'navigation.php'; ?>
<p>&copy; <?php echo date("Y"); ?> ТОВ "Весна". Усі права захищені.</p>
</footer>

View File

@ -0,0 +1,7 @@
<header>
<h1>Продовольчий магазин "Весна"</h1>
<?php if (isset($_SESSION['user'])): ?>
<h3>Добрий день <?php echo htmlspecialchars($_SESSION['user']['name']); ?></h3>
<?php endif; ?>
<?php include 'navigation.php'; ?>
</header>

View File

@ -0,0 +1,17 @@
<nav>
<?php if (isset($_SESSION['user'])): ?>
<a href="?page=home">Головна</a>
|
<a href="?page=items">Товари</a>
|
<a href="?page=cart">Кошик (<?php echo $cart_count ?? 0; ?>)</a>
|
<a href="?page=profile">Профіль</a>
|
<a href="?page=logout">Вихід</a>
<?php else: ?>
<a href="?page=login">Вхід</a>
|
<a href="?page=register">Реєстрація</a>
<?php endif; ?>
</nav>

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title><?php echo htmlspecialchars($title ?? 'Продовольчий магазин "Весна"'); ?></title>
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<?php include 'components/header.php'; ?>
<div class="container">
<?php echo $content; ?>
</div>
<?php include 'components/footer.php'; ?>
</body>
</html>

View File

@ -0,0 +1,9 @@
<?php ob_start(); ?>
<div style="display: flex; flex-direction: column; align-items: center; justify-content: space-between;">
<h1 style="text-align: center;">Будь-ласка увійдіть в акаунт для доступу до цієї сторінки</h1>
<img src="public/assets/logo.png" alt="logo" style="width: 90%;">
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,46 @@
<?php ob_start(); ?>
<?php if (empty($cart_items)): ?>
<div style="display: flex; align-items: center; justify-content: space-evenly;">
<h3>Ваш кошик порожній <a href="?page=items">Перейти до покупок</a></h3>
</div>
<?php else: ?>
<div style="display: flex; align-items: center; justify-content: space-evenly;">
<h3>Ваш кошик</h3>
<h3 class="cart-summary">
Загальна сума: <?php echo number_format($cart_total, 2); ?> грн
</h3>
<button type="submit">Сплатити</button>
<form action="?page=cart&action=clear" method="POST" style="display: inline;">
<button type="submit">Очистити</button>
</form>
</div>
<div class="product-list">
<?php foreach ($cart_items as $item): ?>
<div>
<h2>
<?php echo htmlspecialchars($item['name']); ?>
<br>
<?php echo htmlspecialchars($item['count']); ?> шт.
</h2>
<span>Ціна за одиницю: <?php echo number_format($item['price'], 2); ?> грн</span>
<br>
<span>Загальна ціна: <?php echo number_format($item['total_price'], 2); ?> грн</span>
<br><br>
<form action="?page=cart&action=remove" method="POST">
<input type="hidden" name="product_id" value="<?php echo htmlspecialchars($item['id']); ?>">
<button type="submit" style="width: 100%;">Видалити</button>
</form>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,8 @@
<?php ob_start(); ?>
<div style="display: flex; flex-direction: column; align-items: center;">
<img src="public/assets/logo.png" alt="logo" style="width: 90%;">
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,21 @@
<?php ob_start(); ?>
<h2>Доступні товари</h2>
<div class="product-list">
<?php foreach ($items as $item): ?>
<div>
<h2><?php echo htmlspecialchars($item['name']); ?></h2>
<h3>Ціна: <?php echo number_format($item['price'], 2); ?> грн</h3>
<form action="?page=cart&action=add" method="POST">
<input type="hidden" name="product_id" value="<?php echo htmlspecialchars($item['id']); ?>">
<label for="quantity_<?php echo htmlspecialchars($item['id']); ?>">Кількість:</label>
<input type="number" id="quantity_<?php echo htmlspecialchars($item['id']); ?>" name="quantity" value="0" min="0" max="100">
<button type="submit">Купити</button>
</form>
</div>
<?php endforeach; ?>
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,28 @@
<?php ob_start(); ?>
<div style="max-width: 400px; margin: 0 auto;">
<h2>Вхід в систему</h2>
<?php require 'templates/components/error.php' ?>
<form method="POST" action="?page=login">
<div style="margin-bottom: 15px;">
<label for="username">Ім'я користувача:</label><br>
<input type="text" id="username" name="username" required>
</div>
<div style="margin-bottom: 15px;">
<label for="password">Пароль:</label><br>
<input type="password" id="password" name="password" required>
</div>
<button type="submit" style="width: 100%;">Увійти</button>
</form>
<p style="text-align: center; margin-top: 20px;">
<a href="?page=register">Немає акаунта? Зареєструватися</a>
</p>
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,32 @@
<?php ob_start(); ?>
<?php require 'templates/components/error.php' ?>
<div style="display: flex; flex-direction: column; align-items: center; justify-content: space-between;">
<div style="width: 150px; height: 150px; border: 1px solid black; display: flex; justify-content: center; align-items: center; margin-bottom: 20px;">
<img src="<?= htmlspecialchars($_SESSION['user']['photo_path']) ?>" alt="Profile Image" style="max-width: 100%; max-height: 100%; object-fit: contain;">
</div>
<form style="display: grid; gap: 15px;" method="post" enctype="multipart/form-data">
<input type="file" name="photo" accept="image/*">
<label style="font-weight: bold;">Ім'я</label>
<input type="text" value="<?php echo $_SESSION['user']['name'] ?>" name="name">
<label style="font-weight: bold;">Фамілія</label>
<input type="text" value="<?php echo $_SESSION['user']['surname'] ?>" name="surname">
<label style="font-weight: bold;">Вік</label>
<input type="number" min="16" max="150" value="<?php echo $_SESSION['user']['age'] ?>" name="age">
<label style="font-weight: bold;">Про себе</label>
<textarea style="height: 50px; resize: vertical;" name="description"><?php echo $_SESSION['user']['description'] ?></textarea>
<button>Сохранить</button>
</form>
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>

View File

@ -0,0 +1,43 @@
<?php ob_start(); ?>
<div style="max-width: 400px; margin: 0 auto;">
<h2>Реєстрація</h2>
<?php require 'templates/components/error.php' ?>
<form method="POST" action="?page=register">
<div style="margin-bottom: 15px;">
<label for="username">Логін *:</label><br>
<input type="text" id="username" name="username" required>
</div>
<div style="margin-bottom: 15px;">
<label for="password">Пароль * (мінімум 6 символів):</label><br>
<input type="password" name="password" required>
</div>
<div style="margin-bottom: 15px;">
<label for="name">Ім'я *:</label><br>
<input type="text" name="name" required>
</div>
<div style="margin-bottom: 15px;">
<label for="surname">Прізвище *:</label><br>
<input type="text" name="surname" required>
</div>
<div style="margin-bottom: 15px;">
<label for="age">Вік *:</label><br>
<input type="number" name="age" min="16" max="150" style="width: 97%;" required>
</div>
<button type="submit" style="width: 100%;">Зареєструватися</button>
</form>
<p style="text-align: center; margin-top: 20px;">
<a href="?page=login">Вже є акаунт? Увійти</a>
</p>
</div>
<?php
$content = ob_get_clean();
include 'templates/layout.php';
?>