From 5978936e4595dbd9c99d891d892e3073dac26f13 Mon Sep 17 00:00:00 2001 From: Arina Date: Wed, 30 Apr 2025 00:07:31 +0300 Subject: [PATCH] registration, login, admin panel --- src/App.js | 19 +-- src/components/AdminPage.css | 163 ++++++++++++++++++++++++ src/components/AdminPage.js | 204 ++++++++++++++++++++++++++++++ src/components/CategoriesPage.css | 57 +++++++++ src/components/CategoriesPage.js | 55 ++++++++ src/components/Header.css | 140 ++++++++++---------- src/components/Header.js | 36 ++++-- src/components/HomePage.css | 203 +++++++++++++++++++++++++++++ src/components/HomePage.js | 64 ++++++---- src/components/LoginPage.css | 84 ++++++++++++ src/components/LoginPage.js | 13 +- src/components/RegisterPage.css | 85 +++++++++++++ src/components/RegisterPage.js | 13 +- src/img/Background.jpg | Bin 0 -> 445799 bytes src/img/Basic.jpg | Bin 0 -> 171614 bytes src/img/Caesar.jpg | Bin 0 -> 156035 bytes src/img/Dessert.jpg | Bin 0 -> 148420 bytes src/img/HomePage.jpg | Bin 0 -> 191652 bytes src/img/Meatballs.jpg | Bin 0 -> 159678 bytes src/img/Salad.jpg | Bin 0 -> 215545 bytes src/img/Solyanka.jpg | Bin 0 -> 168231 bytes src/img/Soup.jpg | Bin 0 -> 191863 bytes src/img/log.png | Bin 0 -> 203208 bytes src/index.js | 12 +- 24 files changed, 1032 insertions(+), 116 deletions(-) create mode 100644 src/components/AdminPage.css create mode 100644 src/components/AdminPage.js create mode 100644 src/components/CategoriesPage.css create mode 100644 src/components/CategoriesPage.js create mode 100644 src/components/HomePage.css create mode 100644 src/components/LoginPage.css create mode 100644 src/components/RegisterPage.css create mode 100644 src/img/Background.jpg create mode 100644 src/img/Basic.jpg create mode 100644 src/img/Caesar.jpg create mode 100644 src/img/Dessert.jpg create mode 100644 src/img/HomePage.jpg create mode 100644 src/img/Meatballs.jpg create mode 100644 src/img/Salad.jpg create mode 100644 src/img/Solyanka.jpg create mode 100644 src/img/Soup.jpg create mode 100644 src/img/log.png diff --git a/src/App.js b/src/App.js index 816e235..af3f6ca 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,12 @@ -import React from 'react'; -import { BrowserRouter, Route, Routes } from 'react-router-dom'; -import Header from './components/Header'; -import HomePage from './components/HomePage'; -import LoginPage from './components/LoginPage'; -import RegisterPage from './components/RegisterPage'; -import './App.css'; +import React from "react"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import Header from "./components/Header"; +import HomePage from "./components/HomePage"; +import LoginPage from "./components/LoginPage"; +import RegisterPage from "./components/RegisterPage"; +import CategoriesPage from "./components/CategoriesPage"; +import AdminPage from "./components/AdminPage"; // 1. Импортируем компонент AdminPage +import "./App.css"; function App() { return ( @@ -15,7 +17,8 @@ function App() { } /> } /> } /> - {/* Другие маршруты */} + } /> + } /> {/* 2. Добавляем Route для AdminPage */} diff --git a/src/components/AdminPage.css b/src/components/AdminPage.css new file mode 100644 index 0000000..2849415 --- /dev/null +++ b/src/components/AdminPage.css @@ -0,0 +1,163 @@ +.admin-page { + font-family: "Arial", sans-serif; + margin: 0; + padding: 20px; + background-color: #f9f5f0; + color: #543d2d; +} + +.admin-page h1 { + font-size: 2.5em; + margin-bottom: 20px; + color: #8b4513; + text-align: center; +} + +.recipe-form { + background-color: #fff8f0; + border-radius: 12px; + padding: 20px; + margin-bottom: 30px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15); + border: 1px solid #d3b48c; +} + +.recipe-form h2 { + font-size: 1.8em; + margin-bottom: 15px; + color: #8b4513; + text-align: center; +} + +.recipe-form label { + display: block; + margin-bottom: 5px; + font-weight: bold; +} + +.recipe-form input[type="text"], +.recipe-form textarea { + width: calc(100% - 20px); + padding: 10px; + margin-bottom: 15px; + border-radius: 7px; + border: 1px solid #d3b48c; + font-size: 1em; + color: #543d2d; + background-color: #fff; +} + +.recipe-form button { + display: inline-block; + padding: 12px 24px; + background-color: #a8571d; + color: white; + text-decoration: none; + border: none; + border-radius: 7px; + font-weight: bold; + transition: background-color 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + cursor: pointer; + font-size: 1em; +} + +.recipe-form button:hover { + background-color: #70380e; +} + +.recipe-form input[type="text"], +.recipe-form textarea, +.recipe-form button, +.recipe-form label { + margin-bottom: 15px; +} + +.recipe-table { + width: 100%; + border-collapse: collapse; + background-color: #fff8f0; + border-radius: 12px; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15); + border: 1px solid #d3b48c; + overflow: hidden; +} + +.recipe-table h2 { + font-size: 1.8em; + margin-bottom: 15px; + color: #8b4513; + text-align: center; +} + +.recipe-table th, +.recipe-table td { + padding: 12px; + text-align: left; + border-bottom: 1px solid #d3b48c; +} + +.recipe-table th { + background-color: #e6b88a; + color: #fff; + font-weight: bold; +} + +.recipe-table tbody tr:nth-child(odd) { + background-color: #fff; +} + +.recipe-table tbody tr:hover { + background-color: #f2dfd1; +} + +.recipe-table button { + display: inline-block; + padding: 8px 16px; + background-color: #a8571d; + color: white; + text-decoration: none; + border: none; + border-radius: 5px; + font-weight: bold; + transition: background-color 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + cursor: pointer; + font-size: 0.9em; + margin-right: 5px; +} + +.recipe-table button:hover { + background-color: #70380e; +} + +.recipe-table input[type="text"], +.recipe-table textarea { + width: 100%; + padding: 8px; + border-radius: 5px; + border: 1px solid #d3b48c; + font-size: 1em; + color: #543d2d; +} + +@media (max-width: 768px) { + .admin-page { + padding: 10px; + } + .admin-page h1 { + font-size: 2em; + } + .recipe-form { + padding: 15px; + } + .recipe-table th, + .recipe-table td { + padding: 8px; + font-size: 0.9em; + } + .recipe-table button { + padding: 6px 12px; + font-size: 0.8em; + } +} \ No newline at end of file diff --git a/src/components/AdminPage.js b/src/components/AdminPage.js new file mode 100644 index 0000000..9cf3be4 --- /dev/null +++ b/src/components/AdminPage.js @@ -0,0 +1,204 @@ +import React, { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import "./AdminPage.css"; + +function AdminPage() { + const navigate = useNavigate(); + const [recipes, setRecipes] = useState([]); + const [newRecipe, setNewRecipe] = useState({ + name: "", + ingredients: "", + instructions: "", + }); + const [editingRecipeId, setEditingRecipeId] = useState(null); + + useEffect(() => { + const token = localStorage.getItem("token"); + if (!token) { + navigate("/login"); + } + }, [navigate]); + + //загр рецептов + useEffect(() => { + const storedRecipes = localStorage.getItem("recipes"); + if (storedRecipes) { + setRecipes(JSON.parse(storedRecipes)); + } + }, []); + + //сохр рецептов при изменении + useEffect(() => { + localStorage.setItem("recipes", JSON.stringify(recipes)); + }, [recipes]); + + const handleInputChange = (e, recipeId = null) => { + const { name, value } = e.target; + + if (recipeId) { + setRecipes((prevRecipes) => + prevRecipes.map((recipe) => + recipe.id === recipeId ? { ...recipe, [name]: value } : recipe + ) + ); + } else { + setNewRecipe((prevState) => ({ + ...prevState, + [name]: value, + })); + } + }; + + const addRecipe = (e) => { + e.preventDefault(); + if (newRecipe.name && newRecipe.ingredients && newRecipe.instructions) { + const newRecipeWithId = { ...newRecipe, id: Date.now() }; + setRecipes([...recipes, newRecipeWithId]); + setNewRecipe({ name: "", ingredients: "", instructions: "" }); + } else { + alert("Пожалуйста, заполните все поля."); + } + }; + + const deleteRecipe = (recipeId) => { + if (window.confirm("Вы уверены, что хотите удалить этот рецепт?")) { + const updatedRecipes = recipes.filter((recipe) => recipe.id !== recipeId); + setRecipes(updatedRecipes); + } + }; + + const startEditing = (recipeId) => { + setEditingRecipeId(recipeId); + }; + + const stopEditing = () => { + setEditingRecipeId(null); + }; + + const saveRecipe = (recipeId) => { + const recipeIndex = recipes.findIndex(recipe => recipe.id === recipeId); + + if (recipeIndex !== -1) { + const updatedRecipes = [...recipes]; + updatedRecipes[recipeIndex] = { + ...updatedRecipes[recipeIndex], + name: updatedRecipes[recipeIndex].name, + ingredients: updatedRecipes[recipeIndex].ingredients, + instructions: updatedRecipes[recipeIndex].instructions + }; + setRecipes(updatedRecipes); + localStorage.setItem("recipes", JSON.stringify(updatedRecipes)); + } + stopEditing(); + }; + + return ( +
+

Админ-панель

+ +
+

Добавить рецепт

+
+ + + + +