From 045563e5903c304e3a00f8cacf6c9a31da522800 Mon Sep 17 00:00:00 2001 From: KacperWojdak Date: Thu, 19 Dec 2024 22:40:00 +0100 Subject: [PATCH 1/7] Interactive map, Markers and kebab list with details --- frontend/src/components/KebabsList.js | 138 ++++++++++++++++++++++++++ frontend/src/img/kebab_icon.png | Bin 0 -> 12699 bytes frontend/src/pages/Map.js | 80 +++++++++++---- 3 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 frontend/src/components/KebabsList.js create mode 100644 frontend/src/img/kebab_icon.png diff --git a/frontend/src/components/KebabsList.js b/frontend/src/components/KebabsList.js new file mode 100644 index 0000000..01f5cb6 --- /dev/null +++ b/frontend/src/components/KebabsList.js @@ -0,0 +1,138 @@ +import React, { useState, useEffect } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faArrowDown } from '@fortawesome/free-solid-svg-icons'; + +const daysTranslations = { + monday: 'Poniedziałek', + tuesday: 'Wtorek', + wednesday: 'Środa', + thursday: 'Czwartek', + friday: 'Piątek', + saturday: 'Sobota', + sunday: 'Niedziela', +}; + +const dayOrder = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']; + +const translateStatus = (status) => { + const statusMap = { + exists: 'Istnieje', + closed: 'Zamknięty', + planned: 'Planowany', + }; + return statusMap[status] || 'Nieznany'; + }; + + export default function KebabsList({ kebabs, activeKebabIndex }) { + const [openIndex, setOpenIndex] = useState(null); + + useEffect(() => { + if (activeKebabIndex !== null) { + setOpenIndex(activeKebabIndex); + } + }, [activeKebabIndex]); + + const toggleDetails = (index) => { + setOpenIndex(openIndex === index ? null : index); + }; + + return ( +
+ {kebabs.map((kebab, index) => ( +
+
toggleDetails(index)} + > +
+
+ {kebab.name} +
+
+

{kebab.name}

+

{kebab.address}

+
+
+ + +
+ +
+
+

Godziny otwarcia:

+ {dayOrder + .filter((day) => kebab.opening_hours[day]) + .map((day) => ( +

+ {daysTranslations[day]}: {kebab.opening_hours[day]} +

+ ))} + + {kebab.meats && kebab.meats.length > 0 && ( +
+

Mięsa:

+

{kebab.meats.join(', ')}

+
+ )} + + {kebab.sauces && kebab.sauces.length > 0 && ( +
+

Sosy:

+

{kebab.sauces.join(', ')}

+
+ )} + + {kebab.status && ( +
+

Status:

+

{translateStatus(kebab.status)}

+
+ )} + +
+

+ Rzemieślniczy: {kebab.is_crafted ? 'Tak' : 'Nie'} +

+

+ Na miejscu: {kebab.is_premises ? 'Tak' : 'Nie'} +

+

+ Sieciówka: {kebab.is_chainstore ? 'Tak' : 'Nie'} +

+
+ + {kebab.ordering_options && kebab.ordering_options.length > 0 && ( +
+

Opcje dostawy:

+
+ {kebab.ordering_options.map((option, index) => ( +

+ {option} +

+ ))} +
+
+ )} +
+
+
+ ))} +
+ ); +} diff --git a/frontend/src/img/kebab_icon.png b/frontend/src/img/kebab_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d02906e92767ff50de320424cfe05b8af5a696 GIT binary patch literal 12699 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 q+;L!$BPo06MWCh^6e=axE@ { + axiosClient + .get('/kebabs') + .then((response) => { + setKebabs(response.data); + }) + .catch((error) => { + console.error('Błąd pobierania kebabów:', error); + }); + }, []); + + const kebabIcon = new L.Icon({ + iconUrl: kebab_icon, + iconSize: [30, 30], + iconAnchor: [15, 30], + popupAnchor: [0, -30], + }); return (
-
- + + + {kebabs.map((kebab, index) => ( + + + {kebab.name}
+ {kebab.address}
+ +
+
+ ))}
-
-

LISTA / TABELA

+ +
+
+
- ) + ); } From bd0810946a60b595b4a19a16e46b13d9a4dd7e79 Mon Sep 17 00:00:00 2001 From: KacperWojdak Date: Mon, 6 Jan 2025 22:33:33 +0100 Subject: [PATCH 2/7] List with kebabs p1 --- frontend/src/components/KebabsList.js | 14 +- frontend/src/components/SearchPanel.js | 169 +++++++++++++++++++++++++ frontend/src/pages/AdminPanel.js | 69 +++++----- frontend/src/pages/Map.js | 52 +++++++- 4 files changed, 257 insertions(+), 47 deletions(-) create mode 100644 frontend/src/components/SearchPanel.js diff --git a/frontend/src/components/KebabsList.js b/frontend/src/components/KebabsList.js index 01f5cb6..0e8502a 100644 --- a/frontend/src/components/KebabsList.js +++ b/frontend/src/components/KebabsList.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faArrowDown } from '@fortawesome/free-solid-svg-icons'; @@ -25,10 +25,17 @@ const translateStatus = (status) => { export default function KebabsList({ kebabs, activeKebabIndex }) { const [openIndex, setOpenIndex] = useState(null); + const kebabRefs = useRef([]); useEffect(() => { if (activeKebabIndex !== null) { setOpenIndex(activeKebabIndex); + if (kebabRefs.current[activeKebabIndex]) { + kebabRefs.current[activeKebabIndex].scrollIntoView({ + behavior: 'smooth', + block: 'center', + }); + } } }, [activeKebabIndex]); @@ -41,7 +48,10 @@ const translateStatus = (status) => { {kebabs.map((kebab, index) => (
(kebabRefs.current[index] = el)} + className={`p-4 rounded-lg shadow-md bg-white ${ + activeKebabIndex === index ? 'border-2 border-blue-500' : '' + }`} >
{ + const now = new Date(); + const currentHour = now.getHours(); + const currentMinute = now.getMinutes(); + const currentTime = currentHour + currentMinute / 60; // Godzina w formacie dziesiętnym + const currentDay = now.toLocaleString('en-US', { weekday: 'long' }).toLowerCase(); + return { currentTime, currentDay }; + }; + + const isOpenNow = (kebab) => { + const { currentTime, currentDay } = getCurrentTimeDetails(); + + if (!kebab.opening_hours || !kebab.opening_hours[currentDay]) { + return false; // Brak danych dla bieżącego dnia + } + + const [opening, closing] = kebab.opening_hours[currentDay] + .split('-') + .map((time) => { + const [hour, minute] = time.split(':').map(Number); + return hour + minute / 60; // Zamiana na format dziesiętny + }); + + return currentTime >= opening && currentTime < closing; + }; + + const handleSearchChange = (e) => { + const query = e.target.value; + setSearchQuery(query); + + let filteredKebabs = query + ? kebabs.filter((kebab) => + kebab.name.toLowerCase().includes(query.toLowerCase()) + ) + : kebabs; + + if (showOpenNow) { + filteredKebabs = filteredKebabs.filter(isOpenNow); + } + + filteredKebabs = sortKebabs(filteredKebabs, sortOrder); + + onSearch(filteredKebabs); + }; + + const handleSortChange = (order) => { + setSortOrder(order); + + let filteredKebabs = sortKebabs(kebabs, order); + + if (searchQuery) { + filteredKebabs = filteredKebabs.filter((kebab) => + kebab.name.toLowerCase().includes(searchQuery.toLowerCase()) + ); + } + + if (showOpenNow) { + filteredKebabs = filteredKebabs.filter(isOpenNow); + } + + onSearch(filteredKebabs); + }; + + const sortKebabs = (kebabs, order) => { + return [...kebabs].sort((a, b) => { + if (order === 'asc') { + return a.name.localeCompare(b.name); + } else { + return b.name.localeCompare(a.name); + } + }); + }; + + const toggleOpenNow = () => { + setShowOpenNow(!showOpenNow); + + let filteredKebabs = kebabs; + + if (searchQuery) { + filteredKebabs = filteredKebabs.filter((kebab) => + kebab.name.toLowerCase().includes(searchQuery.toLowerCase()) + ); + } + + if (!showOpenNow) { + filteredKebabs = filteredKebabs.filter(isOpenNow); + } + + filteredKebabs = sortKebabs(filteredKebabs, sortOrder); + + onSearch(filteredKebabs); + }; + + return ( +
+ +
Sortowanie po nazwie:
+
+ + +
+ + {/* Filtrowanie */} +
setIsFilterOpen(!isFilterOpen)} + > + Filtrowanie + +
+
+
+ +
+
+
+ ); +} diff --git a/frontend/src/pages/AdminPanel.js b/frontend/src/pages/AdminPanel.js index ea00602..a41e07d 100644 --- a/frontend/src/pages/AdminPanel.js +++ b/frontend/src/pages/AdminPanel.js @@ -174,43 +174,34 @@ export default function AdminPanel() { ? JSON.parse(kebab.opening_hours || "{}") : kebab.opening_hours || {}; - setSelectedKebab({ - ...kebab, - logo: kebab.logo, - opening_hours: parsedOpeningHours, - ordering_options: Array.isArray(kebab.ordering_options) - ? kebab.ordering_options - : JSON.parse(kebab.ordering_options || "[]"), - sauces: Array.isArray(kebab.sauces) - ? kebab.sauces - : JSON.parse(kebab.sauces || "[]"), - pages: Array.isArray(kebab.pages) - ? kebab.pages - : JSON.parse(kebab.pages || "[]"), - }); - - setInitialKebab({ - ...kebab, - opening_hours: parsedOpeningHours, - ordering_options: Array.isArray(kebab.ordering_options) - ? kebab.ordering_options - : JSON.parse(kebab.ordering_options || "[]"), - sauces: Array.isArray(kebab.sauces) - ? kebab.sauces - : JSON.parse(kebab.sauces || "[]"), - pages: Array.isArray(kebab.pages) - ? kebab.pages - : JSON.parse(kebab.pages || "[]"), - }); - - setLocalSauces(Array.isArray(kebab.sauces) ? kebab.sauces : JSON.parse(kebab.sauces || "[]")); - setLocalMeats([...kebab.meats]); - setLocalStatus(kebab.status || "exists"); - setLocalOpeningHours(parsedOpeningHours); - setLocalLogo(null); - setLocalOrderingOptions(Array.isArray(kebab.ordering_options) ? [...kebab.ordering_options] : []); - setLocalPages([...kebab.pages]); - setIsKebabModalOpen(true); + setSelectedKebab({ + ...kebab, + opening_hours: kebab.opening_hours || {}, + ordering_options: Array.isArray(kebab.ordering_options) + ? kebab.ordering_options + : [], + sauces: Array.isArray(kebab.sauces) ? kebab.sauces : [], + pages: kebab.pages || {}, + }); + + setInitialKebab({ + ...kebab, + opening_hours: kebab.opening_hours || {}, + ordering_options: Array.isArray(kebab.ordering_options) + ? kebab.ordering_options + : [], + sauces: Array.isArray(kebab.sauces) ? kebab.sauces : [], + pages: kebab.pages || {}, + }); + + setLocalSauces(Array.isArray(kebab.sauces) ? kebab.sauces : []); + setLocalMeats([...kebab.meats]); + setLocalStatus(kebab.status || "exists"); + setLocalOpeningHours(kebab.opening_hours || {}); + setLocalLogo(null); + setLocalOrderingOptions(Array.isArray(kebab.ordering_options) ? kebab.ordering_options : []); + setLocalPages(kebab.pages || {}); + setIsKebabModalOpen(true); }; const handleLogoChange = (file) => { @@ -848,7 +839,7 @@ export default function AdminPanel() { setSelectedKebab({ ...selectedKebab, @@ -868,7 +859,7 @@ export default function AdminPanel() { setSelectedKebab({ ...selectedKebab, diff --git a/frontend/src/pages/Map.js b/frontend/src/pages/Map.js index 0b5e3ab..13151f2 100644 --- a/frontend/src/pages/Map.js +++ b/frontend/src/pages/Map.js @@ -3,6 +3,7 @@ import '../index.css'; import Header from '../components/Header.js'; import Footer from '../components/Footer.js'; import KebabsList from '../components/KebabsList.js'; +import SearchPanel from '../components/SearchPanel.js'; import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; @@ -16,6 +17,7 @@ export default function Map() { ]; const [kebabs, setKebabs] = useState([]); + const [filteredKebabs, setFilteredKebabs] = useState([]); const [activeKebabIndex, setActiveKebabIndex] = useState(null); useEffect(() => { @@ -23,6 +25,7 @@ export default function Map() { .get('/kebabs') .then((response) => { setKebabs(response.data); + setFilteredKebabs(response.data); }) .catch((error) => { console.error('Błąd pobierania kebabów:', error); @@ -36,6 +39,37 @@ export default function Map() { popupAnchor: [0, -30], }); + const handleSearch = (filtered) => { + setFilteredKebabs(filtered); + }; + + const handleSort = (sortOrder) => { + const sortedKebabs = [...filteredKebabs].sort((a, b) => { + if (sortOrder === 'asc') { + return a.name.localeCompare(b.name); + } else { + return b.name.localeCompare(a.name); + } + }); + setFilteredKebabs(sortedKebabs); + }; + + const scrollToKebab = (index) => { + setActiveKebabIndex(index); + + setTimeout(() => { + const kebabElement = document.getElementById(`kebab-${index}`); + if (kebabElement) { + const rect = kebabElement.getBoundingClientRect(); + const offset = window.scrollY + rect.top - 150; + window.scrollTo({ + top: offset, + behavior: 'smooth', + }); + } + }, 0); + }; + return (
@@ -55,10 +89,10 @@ export default function Map() { attribution='© OpenStreetMap contributors' /> - {kebabs.map((kebab, index) => ( + {filteredKebabs.map((kebab, index) => ( @@ -66,7 +100,7 @@ export default function Map() { {kebab.address}
@@ -76,11 +110,17 @@ export default function Map() {
-
- +
+
+ +
+
-
); From 0f3821279fcfa1a8178d3daec7a4e9f562010410 Mon Sep 17 00:00:00 2001 From: KacperWojdak Date: Tue, 7 Jan 2025 20:12:52 +0100 Subject: [PATCH 3/7] =?UTF-8?q?Wysy=C5=82anie=20sugestii?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Footer.js | 2 +- frontend/src/components/Login.js | 25 ++++-- frontend/src/pages/Home.js | 121 ++++++++++++++++++++++++------ 3 files changed, 114 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/Footer.js b/frontend/src/components/Footer.js index 0ecde75..e558d20 100644 --- a/frontend/src/components/Footer.js +++ b/frontend/src/components/Footer.js @@ -4,7 +4,7 @@ import React from 'react' export default function Footer() { return (
-

© 2024 Legnica Kebab City Tour. Wszelkie prawa zastrzeżone.

+

©kibolAPP 2024 Legnica Kebab City Tour. Wszelkie prawa zastrzeżone.

) } diff --git a/frontend/src/components/Login.js b/frontend/src/components/Login.js index cb8d531..16bf088 100644 --- a/frontend/src/components/Login.js +++ b/frontend/src/components/Login.js @@ -14,22 +14,31 @@ export default function Login({ toggleForm }) { const { login } = useAppContext() const handleLogin = async (e) => { - e.preventDefault() + e.preventDefault(); try { const response = await axiosClient.post('/login', { email, password, - }) + }); + if (response.status === 200) { - toast.success('Logowanie zakończone sukcesem!', { autoClose: 2000 }) - login(response.data.token) - setTimeout(() => navigate('/map'), 2000) + toast.success('Logowanie zakończone sukcesem!', { autoClose: 2000 }); + login(response.data.token); + + const userResponse = await axiosClient.get('/getCurrentUser', { + headers: { Authorization: `Bearer ${response.data.token}` }, + }); + + console.log('Zalogowany użytkownik:', userResponse.data); + + setTimeout(() => navigate('/map'), 2000); } } catch (error) { - toast.error('Błąd logowania. Sprawdź swoje dane.', { autoClose: 2000 }) - console.error('Error logging in:', error) + toast.error('Błąd logowania. Sprawdź swoje dane.', { autoClose: 2000 }); + console.error('Error logging in:', error); } - } + }; + return (
diff --git a/frontend/src/pages/Home.js b/frontend/src/pages/Home.js index 0b70d40..729942d 100644 --- a/frontend/src/pages/Home.js +++ b/frontend/src/pages/Home.js @@ -1,27 +1,61 @@ -import '../index.css' -import kebab_logo from '../img/kebab_logo.png' -import { useNavigate } from 'react-router-dom' -import Footer from '../components/Footer.js' -import { useEffect, useState } from 'react' -import 'react-toastify/dist/ReactToastify.css' -import { toast, ToastContainer } from 'react-toastify' +import '../index.css'; +import kebab_logo from '../img/kebab_logo.png'; +import { useNavigate } from 'react-router-dom'; +import Footer from '../components/Footer.js'; +import { useEffect, useState } from 'react'; +import 'react-toastify/dist/ReactToastify.css'; +import { toast, ToastContainer } from 'react-toastify'; +import axiosClient from '../axiosClient.js'; export default function Home() { - const navigate = useNavigate() - const [isLoggedIn, setIsLoggedIn] = useState(false) + const navigate = useNavigate(); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); + const [suggestion, setSuggestion] = useState(''); useEffect(() => { - const token = localStorage.getItem('authToken') + const token = localStorage.getItem('authToken'); if (token) { - setIsLoggedIn(true) + setIsLoggedIn(true); } - }, []) + }, []); const handleLogout = () => { - localStorage.removeItem('authToken') - setIsLoggedIn(false) - toast.success('Wylogowano pomyślnie!', { autoClose: 2000 }) - } + localStorage.removeItem('authToken'); + setIsLoggedIn(false); + toast.success('Wylogowano pomyślnie!', { autoClose: 2000 }); + }; + + const handleSuggestionSubmit = async () => { + const token = localStorage.getItem('authToken'); + + if (!suggestion.trim()) { + toast.error('Proszę wpisać treść sugestii.'); + return; + } + + try { + const userResponse = await axiosClient.get('/getCurrentUser', { + headers: { Authorization: `Bearer ${token}` }, + }); + + const user = userResponse.data.user?.name || 'Anonimowy użytkownik'; + + await axiosClient.post( + '/suggestions', + { user, contents: suggestion }, + { headers: { Authorization: `Bearer ${token}` } } + ); + + toast.success('Sugestia została wysłana!'); + setIsModalOpen(false); + setSuggestion(''); + } catch (error) { + toast.error('Nie udało się wysłać sugestii. Spróbuj ponownie później.'); + console.error('Błąd podczas wysyłania sugestii:', error); + } + }; + return (
@@ -35,8 +69,7 @@ export default function Home() { LEGNICA KEBAB CITY TOUR

- Legnica Kebab City Tour jest to aplikacja oraz witryna internetowa służąca pomocą w odnalezieniu lokalizacji wszystkich dostępnych, w planach oraz zamkniętych punktów gastronomicznych serwujących słynne Kebaby. Poniższe przyciski pokierują Cię dalej. Wybierz przycisk "Mapa" aby bezpośrednio odnaleźć Kebaby rozsiane po Legnicy. Możesz też utworzyć konto lub zalogować się aby dodać Twojego ulubionego Kebaba do zakładki "Ulubione", dzięki czemu łatwiej go odnajdziesz!! -

+ Legnica Kebab City Tour jest to aplikacja oraz witryna internetowa służąca pomocą w odnalezieniu lokalizacji wszystkich dostępnych, w planach oraz zamkniętych punktów gastronomicznych serwujących słynne Kebaby. Poniższe przyciski pokierują Cię dalej. Wybierz przycisk "Mapa" aby bezpośrednio odnaleźć Kebaby rozsiane po Legnicy. Możesz też utworzyć konto lub zalogować się aby na mapie dodać Twojego ulubionego Kebaba, dzięki czemu łatwiej go odnajdziesz!! Dodatkowo po zalogowaniu pojawi się przycisk "Sugestia", nie krępuj się i zostaw nam swoją opinię!

+ <> + + + ) : (