poprawa edycji transakcji, dodanie harmonogramu

This commit is contained in:
Wiktor Szynaka 2024-11-28 21:30:29 +01:00
parent 03bf26a8a1
commit c4cd38ecac
7 changed files with 542 additions and 258 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
@ -13,6 +13,15 @@ const DodawanieProduktu = () => {
});
const navigate = useNavigate();
useEffect(() => {
if (newProduct.type === '0') {
setNewProduct(prevState => ({
...prevState,
availability: '',
}));
}
}, [newProduct.type]);
const handleInputChange = (event) => {
const { name, value } = event.target;
setNewProduct({ ...newProduct, [name]: value });

View File

@ -11,7 +11,7 @@ const EdycjaProduktu = () => {
type: '1',
availability: '',
});
const [error, setError] = useState(null);
const [errors, setErrors] = useState({});
const navigate = useNavigate();
useEffect(() => {
@ -19,7 +19,7 @@ const EdycjaProduktu = () => {
try {
const token = localStorage.getItem('token');
if (!token) {
setError('Brak tokena. Użytkownik musi być zalogowany.');
setErrors({ general: 'Brak tokena. Użytkownik musi być zalogowany.' });
return;
}
@ -28,10 +28,18 @@ const EdycjaProduktu = () => {
Authorization: `Bearer ${token}`,
},
});
setProduct(response.data);
const productData = response.data;
setProduct({
name: productData.name,
description: productData.description,
price: productData.price,
type: productData.type.toString(),
availability: productData.availability || '',
});
} catch (error) {
console.error('Błąd podczas pobierania produktu:', error);
setError('Wystąpił błąd podczas pobierania danych produktu.');
setErrors({ general: 'Wystąpił błąd podczas pobierania danych produktu.' });
}
};
@ -40,17 +48,45 @@ const EdycjaProduktu = () => {
const handleInputChange = (event) => {
const { name, value } = event.target;
setProduct({ ...product, [name]: value });
if (name === 'type') {
if (value === '0') {
setProduct({
...product,
[name]: value,
availability: '',
});
} else {
setProduct({
...product,
[name]: value,
});
}
} else {
setProduct({ ...product, [name]: value });
}
setErrors((prevErrors) => ({
...prevErrors,
[name]: null,
}));
};
const handleSaveChanges = async () => {
const { name, description, price, type, availability } = product;
if (!name || !description || !price || type === '') {
setError('Proszę uzupełnić wszystkie wymagane pola.');
let validationErrors = {};
if (!name) validationErrors.name = 'Nazwa produktu jest wymagana.';
if (!description) validationErrors.description = 'Opis produktu jest wymagany.';
if (!price) validationErrors.price = 'Cena produktu jest wymagana.';
if (type === '') validationErrors.type = 'Typ produktu jest wymagany.';
if (price < 0) validationErrors.price = 'Cena nie może być ujemna.';
if (type === '1' && !availability) validationErrors.availability = 'Dostępność jest wymagana dla produktu.';
if (Object.keys(validationErrors).length > 0) {
setErrors(validationErrors);
return;
}
const payload = {
id,
name,
@ -59,89 +95,106 @@ const EdycjaProduktu = () => {
type: parseInt(type, 10),
...(type === '1' && { availability: availability || 0 }),
};
try {
const token = localStorage.getItem('token');
if (!token) {
setError('Brak tokena. Użytkownik musi być zalogowany.');
setErrors({ general: 'Brak tokena. Użytkownik musi być zalogowany.' });
return;
}
const config = {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
};
const response = await axios.put(`https://localhost:7039/api/Products/${id}`, payload, config);
console.log('Produkt zapisany:', response.data);
setError(null);
await axios.put(`https://localhost:7039/api/Products/${id}`, payload, config);
setErrors({});
navigate('/produkty');
} catch (error) {
console.error('Błąd podczas zapisywania zmian:', error);
if (error.response && error.response.status === 400) {
setError('ID produktu nie zgadza się.');
setErrors({ general: error.response.data });
} else {
setError('Wystąpił błąd podczas zapisywania zmian. Spróbuj ponownie.');
setErrors({ general: 'Wystąpił błąd podczas zapisywania zmian. Spróbuj ponownie.' });
}
}
};
return (
<div className="p-8 bg-gray-100 rounded-lg shadow-md">
<h2 className="text-2xl font-bold mb-4">Edycja produktu</h2>
{error && <p className="text-red-500 mb-4">{error}</p>}
<div className="grid grid-cols-2 gap-4">
<input
type="text"
name="name"
value={product.name}
onChange={handleInputChange}
placeholder="Nazwa produktu lub usługi"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
<input
type="text"
name="description"
value={product.description}
onChange={handleInputChange}
placeholder="Opis"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
<input
type="number"
step="0.01"
name="price"
value={product.price}
onChange={handleInputChange}
placeholder="Cena"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
<select
name="type"
value={product.type}
onChange={handleInputChange}
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
>
<option value="1">Produkt</option>
<option value="0">Usługa</option>
</select>
{product.type === '1' && (
{errors.general && <p className="text-red-500 mb-4">{errors.general}</p>}
<div className="grid grid-cols-2 gap-8">
<div className="relative">
<input
type="number"
name="availability"
value={product.availability}
type="text"
name="name"
value={product.name}
onChange={handleInputChange}
placeholder="Dostępność (ilość)"
placeholder="Nazwa produktu lub usługi"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.name && <span className="absolute text-red-500 text-sm">{errors.name}</span>}
</div>
<div className="relative">
<input
type="text"
name="description"
value={product.description}
onChange={handleInputChange}
placeholder="Opis"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.description && <span className="absolute text-red-500 text-sm">{errors.description}</span>}
</div>
<div className="relative">
<input
type="number"
step="0.01"
name="price"
value={product.price}
onChange={handleInputChange}
placeholder="Cena"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.price && <span className="absolute text-red-500 text-sm">{errors.price}</span>}
</div>
<div className="relative">
<select
name="type"
value={product.type}
onChange={handleInputChange}
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
>
<option value="1">Produkt</option>
<option value="0">Usługa</option>
</select>
{errors.type && <span className="absolute text-red-500 text-sm">{errors.type}</span>}
</div>
{product.type === '1' && (
<div className="relative">
<input
type="number"
name="availability"
value={product.availability}
onChange={handleInputChange}
placeholder="Dostępność (ilość)"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.availability && <span className="absolute text-red-500 text-sm">{errors.availability}</span>}
</div>
)}
</div>
<div className="mt-4">
<button
onClick={handleSaveChanges}

View File

@ -1,238 +1,292 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useParams, useNavigate } from 'react-router-dom';
import Select from 'react-select';
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useParams, useNavigate } from "react-router-dom";
import Select from "react-select";
const EdycjaTransakcji = () => {
const { id } = useParams();
const { id } = useParams();
const [transaction, setTransaction] = useState({
date: '',
employeeId: '',
paymentType: '',
discount: '',
description: '',
transactionProducts: [{ productID: '', productName: '', quantity: '' }],
id: 2,
date: "",
employeeId: "",
transactionProducts: [],
paymentType: "",
discount: "",
description: "",
totalPrice: 0,
});
const [products, setProducts] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [errors, setErrors] = useState({});
const navigate = useNavigate();
const getToken = () => {
const token = localStorage.getItem('token');
const token = localStorage.getItem("token");
if (!token) {
setError('Brak tokena. Użytkownik musi być zalogowany.');
setError("Brak tokena. Użytkownik musi być zalogowany.");
return null;
}
return token;
};
useEffect(() => {
const fetchTransaction = async () => {
const fetchTransactionData = async () => {
const token = getToken();
if (!token) return;
try {
const token = getToken();
if (!token) return;
const transactionResponse = await axios.get(`https://localhost:7039/api/transaction/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log('Dane transakcji:', transactionResponse.data);
const [transactionRes, productsRes] = await Promise.all([
axios.get(`https://localhost:7039/api/transaction/${id}`, {
headers: { Authorization: `Bearer ${token}` },
}),
axios.get("https://localhost:7039/api/Products", {
headers: { Authorization: `Bearer ${token}` },
}),
]);
const updatedTransaction = {
...transactionResponse.data,
transactionProducts: transactionResponse.data.transactionProducts.map((transactionProduct) => ({
productID: transactionProduct.product.id,
productName: transactionProduct.product.name,
quantity: transactionProduct.quantity,
...transactionRes.data,
transactionProducts: transactionRes.data.transactionProducts.map((tp) => ({
id: tp.id,
transactionId: transactionRes.data.id,
productID: tp.product.id,
productName: tp.product.name,
quantity: tp.quantity,
})),
};
setTransaction(updatedTransaction);
const productResponse = await axios.get('https://localhost:7039/api/Products', {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log('Produkty:', productResponse.data);
const productOptions = productResponse.data.map((product) => ({
const productOptions = productsRes.data.map((product) => ({
value: product.id,
label: product.name,
}));
setProducts(productOptions);
} catch (error) {
console.error('Błąd podczas pobierania transakcji lub produktów:', error);
setError('Wystąpił błąd podczas ładowania danych.');
} finally {
setIsLoading(false);
} catch (err) {
console.error(err);
setError("Wystąpił błąd podczas ładowania danych.");
}
};
fetchTransaction();
fetchTransactionData();
}, [id]);
const validateForm = () => {
const validationErrors = {};
if (!transaction.date) validationErrors.date = "Data transakcji jest wymagana.";
if (!transaction.employeeId || transaction.employeeId <= 0) validationErrors.employeeId = "Numer pracownika jest błędny.";
if (transaction.transactionProducts.length === 0)
validationErrors.transactionProducts = "Transakcja musi zawierać co najmniej jeden produkt.";
else {
transaction.transactionProducts.forEach((product, index) => {
if (!product.productID) validationErrors[`productID_${index}`] = "Produkt jest wymagany.";
if (!product.quantity || product.quantity <= 0)
validationErrors[`quantity_${index}`] = "Ilość musi być większa niż 0.";
});
}
if (!transaction.paymentType) validationErrors.paymentType = "Sposób płatności jest wymagany.";
if (transaction.discount < 0) validationErrors.discount = "Rabat nie może być ujemny.";
setErrors(validationErrors);
return Object.keys(validationErrors).length === 0;
};
const handleInputChange = (event) => {
const { name, value } = event.target;
setTransaction({ ...transaction, [name]: value });
setTransaction((prev) => ({ ...prev, [name]: value }));
setErrors((prevErrors) => ({ ...prevErrors, [name]: null }));
};
const handleAddProduct = () => {
setTransaction((prev) => ({
...prev,
transactionProducts: [
...prev.transactionProducts,
{ id: null, transactionId: prev.id, productID: 0, productName: "", quantity: "" },
],
}));
};
const handleProductChange = (index, selectedOption) => {
const updatedTransactionProducts = [...transaction.transactionProducts];
updatedTransactionProducts[index].productID = selectedOption.value;
updatedTransactionProducts[index].productName = selectedOption.label;
setTransaction({
...transaction,
transactionProducts: updatedTransactionProducts,
});
};
const handleAddProduct = () => {
setTransaction({
...transaction,
transactionProducts: [
...transaction.transactionProducts,
{ productID: 0, productName: '', quantity: '' },
],
setTransaction((prev) => {
const updatedProducts = prev.transactionProducts.map((product, i) =>
i === index
? { ...product, productID: selectedOption.value, productName: selectedOption.label }
: product
);
return { ...prev, transactionProducts: updatedProducts };
});
setErrors((prevErrors) => ({ ...prevErrors, [`productID_${index}`]: null }));
};
const handleRemoveProduct = (index) => {
const updatedTransactionProducts = [...transaction.transactionProducts];
updatedTransactionProducts.splice(index, 1);
setTransaction({
...transaction,
transactionProducts: updatedTransactionProducts,
const handleQuantityChange = (index, quantity) => {
setTransaction((prev) => {
const updatedProducts = prev.transactionProducts.map((product, i) =>
i === index ? { ...product, quantity } : product
);
return { ...prev, transactionProducts: updatedProducts };
});
setErrors((prevErrors) => ({ ...prevErrors, [`quantity_${index}`]: null }));
};
const handleSaveChanges = async () => {
if (!transaction.date || !transaction.employeeId || transaction.transactionProducts.some(product => !product.productName || !product.quantity)) {
setError('Proszę uzupełnić wszystkie pola.');
const handleRemoveProduct = async (index) => {
const token = getToken();
if (!token) {
console.error("Brak tokena, nie można usunąć produktu.");
setError("Użytkownik musi być zalogowany.");
return;
}
const productToRemove = transaction.transactionProducts[index];
console.log(productToRemove);
if (!productToRemove || !productToRemove.id) {
console.error("Nie znaleziono ID transakcyjnego produktu. Usuwanie lokalne.");
setTransaction((prev) => ({
...prev,
transactionProducts: prev.transactionProducts.filter((_, i) => i !== index),
}));
return;
}
try {
await axios.delete(
`https://localhost:7039/api/Transaction/${transaction.id}/product/${productToRemove.productID}`,
{ headers: { Authorization: `Bearer ${token}` } }
);
console.log(`Produkt o ID transakcji ${productToRemove.id} został usunięty.`);
setTransaction((prev) => ({
...prev,
transactionProducts: prev.transactionProducts.filter((_, i) => i !== index),
}));
} catch (err) {
console.error("Błąd podczas usuwania produktu:", err.response?.data || err.message);
setError(err.response?.data?.message || "Nie udało się usunąć produktu. Spróbuj ponownie.");
}
};
const handleSaveChanges = async () => {
if (!validateForm()) return;
const token = getToken();
if (!token) return;
const updatedTransaction = {
...transaction,
transactionProducts: transaction.transactionProducts.map((tp) => ({
id: tp.id || 0,
transactionId: transaction.id,
productID: tp.productID,
productName: tp.productName,
quantity: Number(tp.quantity),
})),
};
try {
const token = getToken();
if (!token) {
setError('Brak tokena. Użytkownik musi być zalogowany.');
return;
}
const response = await axios.put(`https://localhost:7039/api/transaction/${id}`, transaction, {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log('Zaktualizowana transakcja:', response.data);
navigate('/transakcje');
} catch (error) {
console.error('Błąd podczas zapisywania zmian:', error);
setError('Wystąpił błąd podczas zapisywania zmian.');
await axios.put(
`https://localhost:7039/api/transaction/${transaction.id}`,
updatedTransaction,
{ headers: { Authorization: `Bearer ${token}` } }
);
navigate("/transakcje");
} catch (err) {
console.error(err);
setError(err.response.data);
}
};
return (
<div className="bg-white p-8 rounded-lg">
<h2 className="text-2xl font-bold mb-4">Edycja Transakcji</h2>
{error && <p className="text-red-500 mb-4">{error}</p>}
<input
type="datetime-local"
name="date"
value={transaction.date}
onChange={handleInputChange}
placeholder="Data"
className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg"
/>
<input
type="number"
name="employeeId"
value={transaction.employeeId}
onChange={handleInputChange}
placeholder="Nr. Pracownika"
className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg"
/>
{isLoading ? (
<div className="text-center">Ładowanie produktów...</div>
) : (
<>
{transaction.transactionProducts.map((product, index) => (
<div key={index} className="mb-4">
<Select
name={`productName-${index}`}
value={products.find(option => option.value === product.productID) || null}
onChange={(selectedOption) => handleProductChange(index, selectedOption)}
options={products}
className="block w-full mb-2"
placeholder="Wybierz produkt..."
/>
<input
type="number"
name={`quantity-${index}`}
value={product.quantity}
onChange={(e) => {
const updatedTransactionProducts = [...transaction.transactionProducts];
updatedTransactionProducts[index].quantity = e.target.value;
setTransaction({ ...transaction, transactionProducts: updatedTransactionProducts });
}}
placeholder="Ilość"
className="block w-full mb-2 px-4 py-2 border border-gray-300 rounded-lg"
/>
<button
onClick={() => handleRemoveProduct(index)}
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
>
Usuń
</button>
</div>
))}
</>
)}
<div className="mb-4">
<input
type="datetime-local"
name="date"
value={transaction.date}
onChange={handleInputChange}
placeholder="Data"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.date && <span className="text-red-500 text-sm">{errors.date}</span>}
</div>
<div className="mb-4">
<input
type="number"
name="employeeId"
value={transaction.employeeId}
onChange={handleInputChange}
placeholder="Nr. Pracownika"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.employeeId && <span className="text-red-500 text-sm">{errors.employeeId}</span>}
</div>
{transaction.transactionProducts.map((product, index) => (
<div key={index} className="mb-4">
<Select
value={products.find((p) => p.value === product.productID) || null}
onChange={(option) => handleProductChange(index, option)}
options={products}
className="mb-2"
placeholder="Wybierz produkt"
/>
{errors[`productID_${index}`] && (
<span className="text-red-500 text-sm">{errors[`productID_${index}`]}</span>
)}
<input
type="number"
value={product.quantity}
onChange={(e) => handleQuantityChange(index, e.target.value)}
placeholder="Ilość"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors[`quantity_${index}`] && (
<span className="text-red-500 text-sm">{errors[`quantity_${index}`]}</span>
)}
<button
onClick={() => handleRemoveProduct(index)}
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
>
Usuń
</button>
</div>
))}
<button
onClick={handleAddProduct}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 my-3 rounded"
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
Dodaj produkt
</button>
<input
type="text"
name="paymentType"
value={transaction.paymentType}
onChange={handleInputChange}
placeholder="Sposób płatności"
className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg"
/>
<input
type="number"
name="discount"
value={transaction.discount}
onChange={handleInputChange}
placeholder="Rabat"
className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg"
/>
<input
type="text"
name="description"
value={transaction.description}
onChange={handleInputChange}
placeholder="Opis"
className="block w-full mb-4 px-4 py-2 border border-gray-300 rounded-lg"
/>
<div className="mb-4">
<input
type="text"
name="paymentType"
value={transaction.paymentType}
onChange={handleInputChange}
placeholder="Sposób płatności"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.paymentType && (
<span className="text-red-500 text-sm">{errors.paymentType}</span>
)}
</div>
<div className="mb-4">
<input
type="number"
name="discount"
value={transaction.discount}
onChange={handleInputChange}
placeholder="Rabat"
className="block w-full px-4 py-2 border border-gray-300 rounded-lg"
/>
{errors.discount && <span className="text-red-500 text-sm">{errors.discount}</span>}
</div>
<button
onClick={handleSaveChanges}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 my-3 rounded"
className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"
>
Zapisz zmiany
</button>

View File

@ -1,10 +1,177 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { jwtDecode } from 'jwt-decode';
const Harmonogram = () => {
const [workdays, setWorkdays] = useState([]);
const [email, setEmail] = useState(null);
const [currentDate, setCurrentDate] = useState(new Date());
const [displayDate, setDisplayDate] = useState(new Date());
const [daysInMonth, setDaysInMonth] = useState([]);
const [manualDateChange, setManualDateChange] = useState(false);
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
const decodedToken = jwtDecode(token);
setEmail(decodedToken.email);
fetchWorkdays(decodedToken.email);
}
const interval = setInterval(() => {
if (!manualDateChange) {
setCurrentDate(new Date());
}
}, 1000);
return () => clearInterval(interval);
}, [manualDateChange]);
const fetchWorkdays = async (email) => {
try {
const response = await axios.get(`https://localhost:7039/api/Workday/user/${email}/workdays`, {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` },
});
setWorkdays(response.data);
} catch (error) {
console.error('Błąd podczas pobierania dni roboczych:', error);
}
};
const handleStartWorkday = async (date) => {
const token = localStorage.getItem('token');
if (!token) {
alert('Brak tokena. Użytkownik musi być zalogowany.');
return;
}
try {
await axios.post(
'https://localhost:7039/api/workday/start',
{ date },
{
headers: { Authorization: `Bearer ${token}` },
}
);
alert('Dzień roboczy rozpoczęty!');
fetchWorkdays(email);
} catch (error) {
console.error(error);
}
};
const isWorkday = (date) => {
return workdays.includes(date);
};
const formatTime = (date) => {
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${hours}:${minutes}:${seconds}`;
};
const formatDayOfWeek = (date) => {
const daysOfWeek = ['Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela'];
return daysOfWeek[date.getDay() === 0 ? 6 : date.getDay() - 1];
};
const formatDate = (date) => {
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear();
return `${day}-${month}-${year}`;
};
const generateDaysInMonth = () => {
const firstDayOfMonth = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1);
const lastDayOfMonth = new Date(displayDate.getFullYear(), displayDate.getMonth() + 1, 0);
const firstDayWeekday = (firstDayOfMonth.getDay() === 0 ? 6 : firstDayOfMonth.getDay() - 1);
const numberOfDaysInMonth = lastDayOfMonth.getDate();
const days = [];
for (let i = 0; i < firstDayWeekday; i++) {
days.push(null);
}
for (let i = 1; i <= numberOfDaysInMonth; i++) {
days.push(i);
}
setDaysInMonth(days);
};
useEffect(() => {
generateDaysInMonth();
}, [displayDate]);
const changeMonth = (direction) => {
setManualDateChange(true);
const newDate = new Date(displayDate);
if (direction === 'previous') {
newDate.setMonth(displayDate.getMonth() - 1);
} else if (direction === 'next') {
newDate.setMonth(displayDate.getMonth() + 1);
}
setDisplayDate(newDate);
setTimeout(() => setManualDateChange(false), 1000);
};
const formatMonth = (monthIndex) => {
const months = [
'Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec',
'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień',
];
return months[monthIndex];
};
return (
<div>
<h1>Harmonogram</h1>
<div className="container mx-auto px-4 py-6">
<div className="flex justify-between items-center mb-6">
<div className="text-lg font-semibold">
<p>{formatDate(currentDate)} - {formatDayOfWeek(currentDate)}</p>
<p>{formatTime(currentDate)}</p>
</div>
</div>
<div className="flex justify-between items-center mb-4">
<button
className="bg-blue-500 text-white py-2 px-4 rounded"
onClick={() => changeMonth('previous')}
>
Poprzedni miesiąc
</button>
<h2 className="text-2xl font-bold">{formatMonth(displayDate.getMonth())} {displayDate.getFullYear()}</h2>
<button
className="bg-blue-500 text-white py-2 px-4 rounded"
onClick={() => changeMonth('next')}
>
Następny miesiąc
</button>
</div>
<div className="grid grid-cols-7 gap-4">
{['P', 'W', 'Ś', 'C', 'P', 'S', 'N'].map((day, index) => (
<div key={index} className="text-center font-semibold">{day}</div>
))}
{daysInMonth.map((day, index) => (
<div
key={index}
className={`text-center py-5 rounded-lg ${day ? 'cursor-pointer' : 'text-transparent'}
${day && 'bg-gray-200 hover:bg-gray-300 transition duration-150 ease-in-out'}
${isWorkday(formatDate(new Date(displayDate.getFullYear(), displayDate.getMonth(), day))) && 'bg-green-200'}`}
style={{
boxShadow: day ? '0 4px 6px rgba(0, 0, 0, 0.1)' : 'none',
}}
onClick={() => day && handleStartWorkday(new Date(displayDate.getFullYear(), displayDate.getMonth(), day))}
>
{day}
</div>
))}
</div>
</div>
);
};

View File

@ -81,7 +81,7 @@ const ListaProduktow = ({ onAdd }) => {
<td className="p-2 border">{product.name}</td>
<td className="p-2 border">{product.description}</td>
<td className="p-2 border">{parseFloat(product.price).toFixed(2)}</td>
<td className="p-2 border">{product.availability}</td>
<td className="p-2 border">{product.type === 0 ? "" : product.availability}</td>
<td className="p-2 border">
<button
onClick={() => handleEditProduct(product.id)}

View File

@ -16,7 +16,7 @@ const Navbar = ({ setToken }) => {
};
return (
<div className="flex items-center justify-between bg-gray-300 p-7 h-16">
<div className="flex items-center justify-between bg-gray-300 p-7 h-16 top-0">
<div className="flex items-center flex-shrink-0 text-black mr-6">
<Link to="/" className="text-2xl font-customFont font-bold tracking-wide">FIRMTRACKER</Link>
</div>

View File

@ -9,16 +9,16 @@ import raportyIcon from "../icons/raport.png";
const Sidebar = ({ userRole }) => {
return (
<div className="bg-gray-200 h-screen flex justify-center marign-0 w-max">
<ul className="">
{userRole !== 'User' && (
<>
<Link to="/panel" className="text-black px-10 py-2 block font-customFont text-center w-max">
<li className='flex items-center'>
<img src={adminIcon} alt="Obrazek 1" className="w-7 h-7 mr-2" />
Panel Administratora
</li></Link>
</>
<div className="bg-gray-200 h-screen flex-grow justify-center w-max sticky top-0 z-0">
<ul>
{userRole !== 'User' && (
<>
<Link to="/panel" className="text-black px-10 py-2 block font-customFont text-center w-max">
<li className='flex items-center'>
<img src={adminIcon} alt="Obrazek 1" className="w-7 h-7 mr-2" />
Panel Administratora
</li></Link>
</>
)}
<Link to="/produkty" className="text-black px-10 py-2 block font-customFont text-center w-max">
<li className='flex items-center'>
@ -51,6 +51,7 @@ const Sidebar = ({ userRole }) => {
)}
</ul>
</div>
);
);
}
export default Sidebar;