diff --git a/.hintrc b/.hintrc deleted file mode 100644 index 6fd8e28ca8752deb80da2ef6b8c5edeb08ce1891..0000000000000000000000000000000000000000 --- a/.hintrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": [ - "development" - ], - "hints": { - "axe/forms": [ - "default", - { - "label": "off" - } - ], - "axe/name-role-value": [ - "default", - { - "button-name": "off" - } - ] - } -} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index bfe54ca1033d644a99d87ea41aad6415d3a694fc..bc6a8fe4e0194b233fa9fa2856e92320a50ee8f5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,8 @@ import { BrowserRouter, Route, Routes } from "react-router-dom"; import Tours from "./pages/ToursPages/Tours/Tours"; import NavBar from "./components/NavBar"; import LandingPage from "./pages/LandingPage/LandingPage"; -import QuickQuestPage from "./pages/ToursPages/QuickQuest/QuickQuestPage"; +import { QuickQuestPage } from "./pages/ToursPages/QuickQuest/QuickQuestPage"; +import PackAndGoPage from "./pages/ToursPages/Pack&Go/PackAndGoPage"; function App() { return ( @@ -10,7 +11,9 @@ function App() { <NavBar /> <Routes> <Route path="/" element={<LandingPage />} /> + <Route path="/tours" element={<Tours />} /> <Route path="/Quick_quest_Catalog" element={<QuickQuestPage />} /> + <Route path="/Pack_and_go" element={<PackAndGoPage />} /> <Route path="/tours" element={<Tours />} /> </Routes> </BrowserRouter> diff --git a/src/pages/ToursPages/DummyData/cardData.ts b/src/pages/ToursPages/DummyData/cardData.ts index cdc8a5bb5ae90ce46ee19eb40c487d4c290af843..88bf07b4d901203982b3a8dfa4d5128a38d69f08 100644 --- a/src/pages/ToursPages/DummyData/cardData.ts +++ b/src/pages/ToursPages/DummyData/cardData.ts @@ -1,13 +1,31 @@ import { CardTypes } from "../ToursTypes/tourTypes"; +export const filterOptions = { + durations: [3, 6, 9], + groupSizes: [1, 2, 3, 4, 5, "5+"], + experiences: [ + "Nature", + "Culture", + "Gastronomy", + "Sports", + "Workshops", + "Adventures", + ], + guidedOptions: ["Yes", "No", "Audio"], + wheelchairAccessOptions: ["Yes", "No"], +}; + export const cardData: CardTypes[] = [ { id: 1, title: "Wine Tour and Photography", - price: "€35 per person", - duration: "3 hours", - numberOfPeople: "Solo or Group", - experienceType: "Gastronomy", + price: 35, + duration: 3, + upToPeople: 10, + + groupSize: "Solo or Group", + numberOfPeople: 1, + experience: "Gastronomy", guide: "Yes (Winery Expert)", wheelchairAccessible: true, bestTimeToVisit: "Autumn", @@ -38,10 +56,13 @@ export const cardData: CardTypes[] = [ { id: 2, title: "Wine and Cheese Pairing Experience", - price: "€40 per person", - duration: "2.5 hours", - numberOfPeople: "Solo or Group", - experienceType: "Activities", + price: 40, + duration: 2.5, + upToPeople: 5, + + groupSize: "Solo or Group", + numberOfPeople: 1, + experience: "Activities", guide: "Yes (Winery Expert)", wheelchairAccessible: true, bestTimeToVisit: "Spring", @@ -64,16 +85,20 @@ export const cardData: CardTypes[] = [ excluded: ["Alcohol outside the tour", "Additional food"], meetingPoint: "Vineyard Entrance - Demir Kapija", username: "Jane Smith", - imageUrl: "path/to/image2.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", + location: "Demir Kapija, North Macedonia", }, { id: 3, title: "Sunset Wine Tasting", - price: "€45 per person", - duration: "3 hours", - numberOfPeople: "Solo or Group", - experienceType: "Gastronomy", + price: 45, + duration: 3, + upToPeople: 6, + groupSize: "Solo or Group", + numberOfPeople: 1, + experience: "Gastronomy", guide: "Yes (Winery Expert)", wheelchairAccessible: false, bestTimeToVisit: "Summer", @@ -95,16 +120,21 @@ export const cardData: CardTypes[] = [ excluded: ["Personal drinks", "Transportation outside designated routes"], meetingPoint: "Sunset Viewpoint - Demir Kapija", username: "Mike Taylor", - imageUrl: "path/to/image3.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", + location: "Demir Kapija, North Macedonia", }, { id: 4, title: "Wine Harvesting Experience", - price: "€50 per person", - duration: "4 hours", - numberOfPeople: "Group", - experienceType: "Culture", + price: 50, + duration: 4, + upToPeople: 10, + + groupSize: "Group", + numberOfPeople: 2, + experience: "Culture", guide: "Yes (Vineyard Owner)", wheelchairAccessible: false, bestTimeToVisit: "Autumn", @@ -126,16 +156,21 @@ export const cardData: CardTypes[] = [ excluded: ["Personal transportation", "Additional meals"], meetingPoint: "Vineyard Field - Demir Kapija", username: "Sarah Clark", - imageUrl: "path/to/image4.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", + location: "Demir Kapija, North Macedonia", }, { id: 5, title: "Private Wine Tasting Tour", - price: "€80 per person", - duration: "3.5 hours", - numberOfPeople: "Solo or Private Group", - experienceType: "Gastronomy", + price: 80, + duration: 3.5, + upToPeople: 10, + + groupSize: "Solo or Private Group", + numberOfPeople: 1, + experience: "Gastronomy", guide: "Yes (Winery Expert)", wheelchairAccessible: true, bestTimeToVisit: "All Year Round", @@ -160,16 +195,21 @@ export const cardData: CardTypes[] = [ ], meetingPoint: "Private Entrance - Demir Kapija", username: "Emily Davis", - imageUrl: "path/to/image5.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", + location: "Demir Kapija, North Macedonia", }, { id: 6, title: "Wine and Art Tour", - price: "€55 per person", - duration: "3 hours", - numberOfPeople: "Solo or Group", - experienceType: "Art", + price: 55, + duration: 3, + upToPeople: 10, + + groupSize: "Solo or Group", + numberOfPeople: 1, + experience: "Art", guide: "Yes (Winery Expert + Local Artist)", wheelchairAccessible: true, bestTimeToVisit: "Spring", @@ -191,16 +231,20 @@ export const cardData: CardTypes[] = [ excluded: ["Transportation outside the tour", "Meals beyond snacks"], meetingPoint: "Winery Entrance - Demir Kapija", username: "Oliver Martin", - imageUrl: "path/to/image6.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", location: "Demir Kapija, North Macedonia", }, { id: 7, title: "Wine & Cooking Masterclass", - price: "€60 per person", - duration: "4 hours", - numberOfPeople: "Group", - experienceType: "Culture", + price: 60, + duration: 4, + upToPeople: 10, + + groupSize: "Group", + numberOfPeople: 2, + experience: "Culture", guide: "Yes (Chef & Winery Expert)", wheelchairAccessible: true, bestTimeToVisit: "Winter", @@ -222,16 +266,21 @@ export const cardData: CardTypes[] = [ excluded: ["Transportation outside the tour", "Additional meals"], meetingPoint: "Winery Kitchen - Demir Kapija", username: "Sophia Green", - imageUrl: "path/to/image7.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", + location: "Demir Kapija, North Macedonia", }, { id: 8, title: "Vineyard Picnic Experience", - price: "€30 per person", - duration: "2 hours", - numberOfPeople: "Solo or Group", - experienceType: "Nature", + price: 30, + duration: 2, + upToPeople: 8, + + groupSize: "Solo or Group", + numberOfPeople: 1, + experience: "Nature", guide: "No", wheelchairAccessible: true, bestTimeToVisit: "Spring", @@ -252,7 +301,8 @@ export const cardData: CardTypes[] = [ excluded: ["Personal drinks", "Additional meals"], meetingPoint: "Vineyard Picnic Area - Demir Kapija", username: "Liam Walker", - imageUrl: "path/to/image8.jpg", + imageUrl: + "src/assets/images/tours-page/Quick Quest Tour Example/Wine Tour.png", location: "Demir Kapija, North Macedonia", }, ]; diff --git a/src/pages/ToursPages/DummyData/toursData.ts b/src/pages/ToursPages/DummyData/toursData.ts index c1e13549a403e7be7a9921ec0b9edd00381477bf..3f03b1f1bbd873ca94906abe33c04bddf31cc5bb 100644 --- a/src/pages/ToursPages/DummyData/toursData.ts +++ b/src/pages/ToursPages/DummyData/toursData.ts @@ -73,6 +73,7 @@ export const tours: TourTypes[] = [ content1: "Relax. Your journey is ready.", showButton: true, hideButton: false, + destination: "/Pack_and_go", }, { id: 3, diff --git a/src/pages/ToursPages/Pack&Go/PackAndGoPage.tsx b/src/pages/ToursPages/Pack&Go/PackAndGoPage.tsx index db1907a1aae5ce642b3035fa1d5e912e2c94fbae..3e803a6f03ab0c725bf5584707bdee7b1638638a 100644 --- a/src/pages/ToursPages/Pack&Go/PackAndGoPage.tsx +++ b/src/pages/ToursPages/Pack&Go/PackAndGoPage.tsx @@ -1,10 +1,10 @@ -import React from "react"; import PackAndGo from "../ToursComponents/Pack&Go"; +import { tours } from "../DummyData/toursData"; const PackAndGoPage = () => { return ( <div> - <PackAndGo /> + <PackAndGo {...tours[0]} hideButton={true} /> </div> ); }; diff --git a/src/pages/ToursPages/QuickQuest/QuickQuestPage.tsx b/src/pages/ToursPages/QuickQuest/QuickQuestPage.tsx index 84b0486ef7d6fa61551834f6744cfd9e7cd82151..0083905820e2fd1c41d919809970137f5140edce 100644 --- a/src/pages/ToursPages/QuickQuest/QuickQuestPage.tsx +++ b/src/pages/ToursPages/QuickQuest/QuickQuestPage.tsx @@ -1,101 +1,14 @@ -import Layout from "../../../components/Layout"; import { tours } from "../DummyData/toursData"; +import { FormContainer } from "../ToursComponents/FiltersContainer"; import QuickQuest from "../ToursComponents/QuickQuest"; -import FilterForm from "../ToursComponents/FilterForm"; -import TourCard from "../ToursComponents/TourCard"; -import { cardData } from "../DummyData/cardData"; -import { useState } from "react"; - -const QuickQuestPage = () => { - const [date, setDate] = useState(""); +export const QuickQuestPage = () => { return ( <> <div className="border-b-[3px] border-darkYellow"> <QuickQuest {...tours[0]} hideButton={true} hideBackground={true} /> </div> - - <Layout> - <div className="grid grid-cols-10 h-full py-[50px] gap-5"> - <div className="col-span-2 h-full"> - <FilterForm /> - </div> - - {/* Right Column - Content */} - <div className="col-span-8 grid grid-rows-[auto,1fr] gap-4"> - {/* First Row with 3 Columns */} - - <form className="row-span-1 grid grid-cols-10 gap-4 h-[58px]"> - <div className="col-span-6 w-full"> - <div className="relative w-full h-full"> - <input - type="text" - id="searchInput" - className="w-full h-full bg-darkerWhite py-2 pl-10 pr-4 border border-lightGrey rounded-lg " - placeholder="Search" - /> - <img - src="src\assets\images\tours-page\Search-icon.png.png" - alt="searc-icon" - className="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500" - /> - </div> - </div> - - <div className="col-span-2 rounded"> - <input - type="date" - value={date} - onChange={(e) => setDate(e.target.value)} - className="w-full h-full p-2 border border-gray-300 rounded-lg focus:outline-none content-center" - /> - </div> - - <button - type="submit" - className="col-span-2 bg-gray-300 rounded text-darkGreen h-full" - > - Search - </button> - </form> - - {/* Second Row */} - <div className="h-full w-full"> - <h6 className="text-subHeading text-darkGreen"> - Based on your search filters - </h6> - <div className="p-6 gap-6 flex flex-wrap"> - {cardData.map((tour) => ( - <TourCard - key={tour.id} - id={0} - title={tour.title} - price={tour.price} - duration={tour.duration} - numberOfPeople={tour.numberOfPeople} - experienceType={tour.experienceType} - guide={tour.guide} - wheelchairAccessible={tour.wheelchairAccessible} - bestTimeToVisit={tour.bestTimeToVisit} - ageSuitability={tour.ageSuitability} - difficultyRating={tour.difficultyRating} - description={tour.description} - importantInfo={tour.importantInfo} - included={tour.included} - excluded={tour.excluded} - meetingPoint={tour.meetingPoint} - imageUrl={tour.imageUrl} - username={tour.username} - location={tour.location} - /> - ))} - </div> - </div> - </div> - </div> - </Layout> + <FormContainer /> </> ); }; - -export default QuickQuestPage; diff --git a/src/pages/ToursPages/Tours/Tours.tsx b/src/pages/ToursPages/Tours/Tours.tsx index 6180b0ba33c15b2c2ab3eb3c27659bda753d361a..5c1803b19ea9b63d6adbf9b43d94bdf4177ba35c 100644 --- a/src/pages/ToursPages/Tours/Tours.tsx +++ b/src/pages/ToursPages/Tours/Tours.tsx @@ -1,3 +1,4 @@ +import DNATors from "../../../components/DNATors"; import PackAndGo from "../ToursComponents/Pack&Go"; import QuickQuest from "../ToursComponents/QuickQuest"; import TripItYourself from "../ToursComponents/TripYourself"; @@ -8,6 +9,7 @@ const Tours = () => { <QuickQuest /> <PackAndGo /> <TripItYourself /> + <DNATors /> </> ); }; diff --git a/src/pages/ToursPages/ToursComponents/Date.tsx b/src/pages/ToursPages/ToursComponents/Date.tsx deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/pages/ToursPages/ToursComponents/FilterForm.tsx b/src/pages/ToursPages/ToursComponents/FilterForm.tsx index 615d3b0ef9b037625379fd44b4786d2044bd7dd3..8cf31534638e7a978df08e2d0ca4aed566e04599 100644 --- a/src/pages/ToursPages/ToursComponents/FilterForm.tsx +++ b/src/pages/ToursPages/ToursComponents/FilterForm.tsx @@ -1,84 +1,113 @@ -import { useState } from "react"; -import { FilterState } from "../ToursTypes/tourTypes"; +import React, { useState } from "react"; +import { filterOptions } from "../DummyData/cardData"; -interface TourFiltersProps { - onFilterChange: (filters: FilterState) => void; -} +type Filters = { + maxPrice: number; + durations: Set<number>; + experiencetype: Set<string>; + groupSize: string | ""; + guided: "Yes" | "No" | "Audio" | ""; + wheelchairAccess: boolean | null; +}; -export default function TourFilters({ onFilterChange }: TourFiltersProps) { - const [filters, setFilters] = useState<FilterState>({ +const FilterForm = () => { + const [filters, setFilters] = useState<Filters>({ maxPrice: 500, - durations: new Set(), - groupSize: null, - experiencetype: new Set(), - guided: null, - wheelchairAccess: null, + durations: new Set([3, 6, 9]), + experiencetype: new Set(["Nature", "Culture", "Gastronomy"]), + groupSize: "", + guided: "", + wheelchairAccess: true, }); - // Reset all filters + const handleFilterChange = ( + filterType: keyof Filters, + value: string | number | boolean + ) => { + setFilters((prevFilters) => { + if (filterType === "durations" || filterType === "experiencetype") { + const updatedSet = new Set(prevFilters[filterType] as Set<any>); + + if (updatedSet.has(value)) { + updatedSet.delete(value); + } else { + updatedSet.add(value); + } + + return { + ...prevFilters, + [filterType]: updatedSet, + }; + } else { + return { + ...prevFilters, + [filterType]: value, + }; + } + }); + }; + const resetFilters = () => { - const defaultFilters: FilterState = { + setFilters({ maxPrice: 500, - durations: new Set<number>(), - groupSize: null, - experiencetype: new Set<string>(), - guided: null, + durations: new Set(), + experiencetype: new Set(), + groupSize: "", + guided: "", wheelchairAccess: null, - }; - setFilters(defaultFilters); - onFilterChange(defaultFilters); + }); }; return ( - <div className="w-full p-4 shadow-md border rounded-lg border-lightGrey"> - {/* Header with Reset Button */} - <div className="flex justify-between bg-lightGrey p-3 rounded-t-lg shadow-md"> - <img - src="/images/filter-icon.png" - alt="filter-icon" - className="w-[30px] h-[30px]" - /> + <div className="w-full shadow-md border rounded-lg border-lightGrey"> + <div className="flex justify-between p-3 bg-lightGrey rounded-t-lg shadow-md"> + <div className="bg-lightGrey"> + <img + src="src\assets\images\tours-page\Filter-icon.png.png" + alt="filter-icon" + className="h-[30px]" + /> + </div> + <button onClick={resetFilters} - className="text-sm text-gray-700 hover:text-red-500" + className="text-sm text-gray-700 hover:text-red-500 w-[30px]" > - Reset Filters + <img + src="src\assets\images\tours-page\Reset-Filters.png.png" + alt="resert-button" + className="w-full" + /> </button> </div> <div className="flex flex-col gap-4 p-3"> {/* Price Slider */} <div> - <h6 className="font-semibold text-sm"> - Max Price: ${filters.maxPrice} - </h6> + <h6 className="font-semibold text-sm">Price</h6> <input type="range" min="0" max="500" - value={filters.maxPrice} + value="0" onChange={(e) => handleFilterChange("maxPrice", Number(e.target.value)) } className="w-full" /> - <div className="flex justify-between text-sm"> - <span>$0</span> - <span>${filters.maxPrice}</span> - </div> </div> {/* Duration */} <div> - <h6 className="font-semibold text-sm">Duration</h6> - <div className="grid grid-cols-3 gap-2"> - {[3, 6, 9].map((duration) => ( + <h6 className="font-semibold text-sm mb-2">Duration</h6> + <div className="grid grid-cols-3 gap-2 "> + {filterOptions.durations.map((duration) => ( <button key={duration} onClick={() => handleFilterChange("durations", duration)} - className={`p-2 rounded border ${ + className={`p-2 rounded border text-[12px] ${ filters.durations.has(duration) - ? "bg-blue-500 text-white" + ? "bg-slate-500" : "bg-gray-200 hover:bg-gray-300" }`} > @@ -90,15 +119,15 @@ export default function TourFilters({ onFilterChange }: TourFiltersProps) { {/* Group Size */} <div> - <h6 className="font-semibold text-sm">Number of People</h6> + <h6 className="font-semibold text-sm mb-2">Number of People</h6> <div className="grid grid-cols-3 gap-2"> - {[1, 2, 3, 4, 5, "5+"].map((size) => ( + {filterOptions.groupSizes.map((size) => ( <button key={size.toString()} onClick={() => handleFilterChange("groupSize", size)} - className={`p-2 rounded border ${ + className={`p-2 rounded border text-[12px] ${ filters.groupSize === size - ? "bg-blue-500 text-white" + ? "bg-slate-500" : "bg-gray-200 hover:bg-gray-300" }`} > @@ -110,22 +139,15 @@ export default function TourFilters({ onFilterChange }: TourFiltersProps) { {/* Type */} <div> - <h6 className="font-semibold text-sm">Type</h6> + <h6 className="font-semibold text-sm mb-2">Type</h6> <div className="grid grid-cols-2 gap-2"> - {[ - "Nature", - "Culture", - "Gastronomy", - "Sports", - "Workshops", - "Adventures", - ].map((type) => ( + {filterOptions.experiences.map((type) => ( <button key={type} onClick={() => handleFilterChange("experiencetype", type)} - className={`p-2 rounded border ${ + className={`p-2 rounded border text-[12px] ${ filters.experiencetype.has(type) - ? "bg-blue-500 text-white" + ? "bg-slate-500" : "bg-gray-200 hover:bg-gray-300" }`} > @@ -137,15 +159,15 @@ export default function TourFilters({ onFilterChange }: TourFiltersProps) { {/* Guided */} <div> - <h6 className="font-semibold text-sm">Guided</h6> + <h6 className="font-semibold text-sm mb-2">Guided</h6> <div className="grid grid-cols-3 gap-2"> - {["Yes", "No", "Audio"].map((option) => ( + {filterOptions.guidedOptions.map((option) => ( <button key={option} onClick={() => handleFilterChange("guided", option)} - className={`p-2 rounded border ${ + className={`p-2 rounded border text-[12px] ${ filters.guided === option - ? "bg-blue-500 text-white" + ? "bg-slate-500" : "bg-gray-200 hover:bg-gray-300" }`} > @@ -157,17 +179,17 @@ export default function TourFilters({ onFilterChange }: TourFiltersProps) { {/* Wheelchair Access */} <div> - <h6 className="font-semibold text-sm">Wheelchair Access</h6> + <h6 className="font-semibold text-sm mb-2">Wheelchair Access</h6> <div className="grid grid-cols-2 gap-2"> - {["Yes", "No"].map((option) => ( + {filterOptions.wheelchairAccessOptions.map((option) => ( <button key={option} onClick={() => handleFilterChange("wheelchairAccess", option === "Yes") } - className={`p-2 rounded border ${ + className={`p-2 rounded border text-[12px] ${ filters.wheelchairAccess === (option === "Yes") - ? "bg-blue-500 text-white" + ? "bg-slate-500" : "bg-gray-200 hover:bg-gray-300" }`} > @@ -179,4 +201,6 @@ export default function TourFilters({ onFilterChange }: TourFiltersProps) { </div> </div> ); -} +}; + +export default FilterForm; diff --git a/src/pages/ToursPages/ToursComponents/FiltersContainer.tsx b/src/pages/ToursPages/ToursComponents/FiltersContainer.tsx new file mode 100644 index 0000000000000000000000000000000000000000..815c70dfc0a91153e71917fced6ce488537a8780 --- /dev/null +++ b/src/pages/ToursPages/ToursComponents/FiltersContainer.tsx @@ -0,0 +1,92 @@ +import { useState } from "react"; +import Layout from "../../../components/Layout"; +import TourCard from "./TourCard"; + +import { cardData } from "../DummyData/cardData"; +import FilterForm from "./FilterForm"; + +export const FormContainer = () => { + const [date, setDate] = useState(""); + return ( + <Layout> + <div className="grid grid-cols-10 h-full py-[50px] gap-5"> + <div className="col-span-2 h-full"> + <FilterForm /> + </div> + + {/* Right Column - Content */} + <div className="col-span-8 grid grid-rows-[auto,1fr] gap-4"> + {/* First Row with 3 Columns */} + + <form className="row-span-1 grid grid-cols-10 gap-4 h-[58px]"> + <div className="col-span-6 w-full"> + <div className="relative w-full h-full"> + <input + type="text" + id="searchInput" + className="w-full h-full bg-darkerWhite py-2 pl-10 pr-4 border border-lightGrey rounded-lg " + placeholder="Search" + /> + <img + src="src\assets\images\tours-page\Search-icon.png.png" + alt="searc-icon" + className="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500" + /> + </div> + </div> + + <div className="col-span-2 rounded"> + <input + type="date" + value={date} + onChange={(e) => setDate(e.target.value)} + className="w-full h-full p-2 border border-gray-300 rounded-lg focus:outline-none content-center" + /> + </div> + + <button + type="submit" + className="col-span-2 bg-gray-300 rounded text-darkGreen h-full" + > + Search + </button> + </form> + + {/* Second Row */} + <div className="h-full w-full"> + <h6 className="text-subHeading text-darkGreen"> + Based on your search filters + </h6> + <div className="p-6 gap-6 flex flex-wrap"> + {cardData.map((tour) => ( + <TourCard + key={tour.id} + id={0} + title={tour.title} + price={tour.price} + duration={tour.duration} + numberOfPeople={tour.numberOfPeople} + experience={tour.experience} + guide={tour.guide} + wheelchairAccessible={tour.wheelchairAccessible} + bestTimeToVisit={tour.bestTimeToVisit} + ageSuitability={tour.ageSuitability} + difficultyRating={tour.difficultyRating} + description={tour.description} + importantInfo={tour.importantInfo} + included={tour.included} + excluded={tour.excluded} + meetingPoint={tour.meetingPoint} + imageUrl={tour.imageUrl} + username={tour.username} + location={tour.location} + groupSize={tour.groupSize} + /> + ))} + </div> + </div> + </div> + </div> + </Layout> + ); +}; diff --git a/src/pages/ToursPages/ToursComponents/Pack&Go.tsx b/src/pages/ToursPages/ToursComponents/Pack&Go.tsx index 61c5a7bfaf916addbbe458e2a8dc552fe7709985..d3eb8a1971a48cff4e19f063d79af0c1b6aded91 100644 --- a/src/pages/ToursPages/ToursComponents/Pack&Go.tsx +++ b/src/pages/ToursPages/ToursComponents/Pack&Go.tsx @@ -1,25 +1,30 @@ import { tours } from "../DummyData/toursData"; +import { FormContainer } from "./FiltersContainer"; import ToursLayout from "./ToursLayout"; -const PackAndGo = () => { +const PackAndGo = ({ hideButton = false }: { hideButton?: boolean }) => { return ( - <div> - <ToursLayout - id={tours[1].id} - title={tours[1].title} - subtitle={tours[1].subtitle} - content={tours[1].content} - listItems={tours[1].listItems} - imageSrc={tours[1].imageSrc} - content1={tours[1].content1} - themeColor={tours[1].themeColor} - subtitleColor={tours[1].subtitleColor} - bgColor={tours[1].bgColor} - showButton={tours[1].showButton} - destination={tours[1].destination} - reverse={tours[1].reverse} - /> - </div> + <> + <div className="border-b-[3px] border-darkYellow"> + <ToursLayout + id={tours[1].id} + title={tours[1].title} + subtitle={tours[1].subtitle} + content={tours[1].content} + listItems={tours[1].listItems} + imageSrc={tours[1].imageSrc} + content1={tours[1].content1} + themeColor={tours[1].themeColor} + subtitleColor={tours[1].subtitleColor} + bgColor={tours[1].bgColor} + showButton={tours[1].showButton} + destination={tours[1].destination} + reverse={tours[1].reverse} + hideButton={hideButton} + /> + </div> + <FormContainer /> + </> ); }; diff --git a/src/pages/ToursPages/ToursComponents/TourCard.tsx b/src/pages/ToursPages/ToursComponents/TourCard.tsx index 98befa1c761bc855ac368913c9a31874b3106e62..fb3e12ee0b8c8b3e848b6f3ed0c13396a1bad9d2 100644 --- a/src/pages/ToursPages/ToursComponents/TourCard.tsx +++ b/src/pages/ToursPages/ToursComponents/TourCard.tsx @@ -1,32 +1,17 @@ import { CardTypes } from "../ToursTypes/tourTypes"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faHeart as faSolidHeart } from "@fortawesome/free-solid-svg-icons"; -import { faHeart as faRegularHeart } from "@fortawesome/free-regular-svg-icons"; const TourCard: React.FC<CardTypes> = ({ - id, title, price, duration, - numberOfPeople, - experienceType, - guide, - wheelchairAccessible, + upToPeople, + experience, bestTimeToVisit, - ageSuitability, - difficultyRating, - description, - importantInfo, - included, - excluded, - meetingPoint, imageUrl, - username, location, }) => { return ( <div className="bg-white rounded-xl shadow-md overflow-hidden w-[240px] max-h-[450px]"> - {/* Image Section */} <div className=" relative"> <img src={imageUrl} @@ -41,12 +26,11 @@ const TourCard: React.FC<CardTypes> = ({ /> </div> - {/* Details Section */} <div className="p-2 text-slate-800 h-[220px] "> <div className="flex justify-between items-center mb-2"> <p className="font-bold text-smallerSize">{title}</p> <p className="font-bold text-smallerSize bg-slate-800 text-white p-[5px] rounded"> - {experienceType} + {experience} </p> </div> @@ -55,15 +39,15 @@ const TourCard: React.FC<CardTypes> = ({ {location} </p> - <div className="flex justify-between "> - <ul className="text-[15px] "> - <li>{duration}</li> - <li>{numberOfPeople}</li> - <li>{price}</li> + <div className="flex justify-between items-end"> + <ul className="text-[15px]"> + <li>{duration} hours</li> + <li>Up to {upToPeople} people</li> + <li>€{price} per person</li> </ul> - <div className="relative"> - <p className="absolute bottom-0 right-0 text-right text-[12px]"> + <div className=""> + <p className="text-right text-[12px]"> Best <br /> experience <br /> in {bestTimeToVisit} </p> diff --git a/src/pages/ToursPages/ToursTypes/tourTypes.ts b/src/pages/ToursPages/ToursTypes/tourTypes.ts index 128d00ebb6e88651636532886302524e14673ff8..62fd36b98249db887875c37f0b4232e47c9dfc4c 100644 --- a/src/pages/ToursPages/ToursTypes/tourTypes.ts +++ b/src/pages/ToursPages/ToursTypes/tourTypes.ts @@ -3,6 +3,7 @@ export interface ListItem { label: string; text: string; } + export type TourTypes = { id: number; imageSrc: string; @@ -20,33 +21,56 @@ export type TourTypes = { listItems: ListItem[]; }; -export interface FilterState { - maxPrice: number; - durations: Set<number>; - groupSize: number | null; - experiencetype: Set<string>; - guided: string | null; - wheelchairAccess: boolean | null; -} - export type CardTypes = { id: number; title: string; - price: string; - duration: string; - numberOfPeople: string; - experienceType: string; + price: number; + upToPeople: number; + duration: string | number; + groupSize: string | number; + experience: string; guide: string; wheelchairAccessible: boolean; bestTimeToVisit: string; + ageSuitability?: string; + difficultyRating?: string; + description?: string; + importantInfo?: string[]; + included?: string[]; + excluded?: string[]; + meetingPoint: string; + imageUrl: string; + username?: string; + location: string; + numberOfPeople: number; +}; + +export interface Tour { + numberOfPeople: number; + title: string; + id: number; + duration: string | number; + groupSize: string | number; + price: number; + experience: string; + guide: string; + wheelchairAccessible: string; + bestTimeToVisit: string; ageSuitability: string; difficultyRating: string; description: string; - importantInfo: string[]; - included: string[]; - excluded: string[]; + importantInfo: string; + included: string; + excluded: string; meetingPoint: string; imageUrl: string; username: string; location: string; +} + +export type FilterState = { + duration: number | null; + groupSize: number | string | null; + price: [number, number]; + numberOfPeople: number; };