diff --git a/.gitignore b/.gitignore index c87c9b3..4fef46f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +scripts/service_key.json diff --git a/app/[type]/[nameID]/OpeningHours.tsx b/app/[type]/[nameID]/OpeningHours.tsx index 62e2e36..0a2ca9e 100644 --- a/app/[type]/[nameID]/OpeningHours.tsx +++ b/app/[type]/[nameID]/OpeningHours.tsx @@ -1,54 +1,63 @@ -import { OpeningHours } from "@/typings"; -import { MONTHS_CZECH } from "@/utils/constants"; -import React from "react"; - -const test: OpeningHours = { - free: true, - forbidden_gone: false, - forbidden_reconstruction: false, - forbidden_temporary: false, - lunch_break: false, - lunch_end: 0, - lunch_start: 0, - months_all: false, - months_range: [4, 9], - occasionally: false, - occasionally_text: "", - time_end: 20, - time_start: 8, - week_all: false, - week_some: [], - unknown: false, -}; +import OpeningHoursDialog from "@/app/komunita/OpeningHoursDialog"; +import { OpeningHours, Tower } from "@/typings"; +import { DAYS_CZECH, MONTHS_CZECH, OpeningHoursForbiddenType, OpeningHoursType } from "@/utils/constants"; +import React, { ReactNode } from "react"; function capitalizeFirstLetter(string: string): string { return string.charAt(0).toUpperCase() + string.slice(1); } +const getDaysString = (days?: number[]): string => { + if (!days) return "Každý den"; + if (days.length == 7) return "Každý den"; + return days.map((e) => DAYS_CZECH.at(e)?.slice(0, 2)).join("·"); +}; + +const getLunchString = (openingHours: OpeningHours): string => { + if (!openingHours.lunch_break) return ""; + return `\n Přestávka ${openingHours.lunch_start} - ${openingHours.lunch_end} h`; +}; + +const isErrorColor = (openingHours: OpeningHours): boolean => { + if (openingHours.type === OpeningHoursType.Forbidden) return true; + if (openingHours.type === OpeningHoursType.Occasionally) return true; + if (openingHours.type === OpeningHoursType.Unknown) return true; + return false; +}; + const generateHeading = (openingHours: OpeningHours, type: string): string => { - if (openingHours.unknown) return "Neznámá otevírací doba."; + if (openingHours.type === OpeningHoursType.Unknown) return "Neznámá otevírací doba."; const typeCap = capitalizeFirstLetter(type); - if (openingHours.free) return `${typeCap} je volně přístupná.`; - if (openingHours.forbidden_gone) return `${typeCap} je označena jako zaniklá.`; - if (openingHours.forbidden_reconstruction) return `${typeCap} je právě v rekonstrukci.`; - if (openingHours.forbidden_temporary) return `${typeCap} je dočasně uzavřena.`; - if (openingHours.occasionally) return `${typeCap} je příležitostně přístupná.`; + if (openingHours.type === OpeningHoursType.NonStop) return `${typeCap} je volně přístupná.`; + if (openingHours.type === OpeningHoursType.Forbidden) { + if (openingHours.forbidden_type === OpeningHoursForbiddenType.Reconstruction) return `${typeCap} je právě v rekonstrukci.`; + if (openingHours.forbidden_type === OpeningHoursForbiddenType.Temporary) return `${typeCap} je dočasně uzavřena.`; + return `${typeCap} je označena jako zaniklá.`; + } + if (openingHours.type === OpeningHoursType.Occasionally) return `${typeCap} je přístupná pouze příležitostně.`; return `${ - openingHours.months_all ? "Celoročně" : MONTHS_CZECH.at(openingHours.months_range[0]) + " - " + MONTHS_CZECH.at(openingHours.months_range[1]) - } | ${openingHours.week_all ? "Každý den" : "Po·Út·St·Čt·Pá"} | ${openingHours.time_start} - ${openingHours.time_end} h`; + openingHours.months?.length === 0 + ? "Celoročně" + : MONTHS_CZECH.at(openingHours.months ? openingHours.months[0] : 0) + + " - " + + MONTHS_CZECH.at(openingHours.months ? openingHours.months[1] : 0) + } | ${getDaysString(openingHours.days)} | ${openingHours.time_start} - ${openingHours.time_end} h`; }; -function OpeningHours() { +function OpeningHours({ tower, openingHours, children }: { tower?: Tower; openingHours?: OpeningHours; children?: ReactNode }) { + const OH: OpeningHours = tower ? tower.openingHours : openingHours || { type: 0 }; return (
-

Otevírací doba

-

{generateHeading(test, "rozhledna")}

+

Otevírací doba

+

{generateHeading(OH, tower?.type || "rozhledna")}

+ {OH.lunch_break &&

{getLunchString(OH)}

} + {OH.note &&

{OH.note}

}
-
Navrhnout úpravu
+ {children}
); } diff --git a/app/[type]/[nameID]/page.tsx b/app/[type]/[nameID]/page.tsx index 99fa4ec..ad927c9 100644 --- a/app/[type]/[nameID]/page.tsx +++ b/app/[type]/[nameID]/page.tsx @@ -15,6 +15,7 @@ import Admission from "./Admission"; import Navbar from "@/app/Navbar"; import MainInfoPhone from "./MainInfoPhone"; import RatingBox from "./RatingBox"; +import OpeningHoursDialog from "@/app/komunita/OpeningHoursDialog"; const URL = "https://firebasestorage.googleapis.com/v0/b/"; const BUCKET = "lookout-towers.appspot.com/"; @@ -81,7 +82,9 @@ async function TowerPage({ params: { type, nameID } }: PageProps) { className={"flex flex-col gap-12 items-center justify-center self-center mb-6 mx-1 sm:mx-3 flex-1 max-w-screen-xl w-full"} >
- + + +
diff --git a/app/komunita/OpeningHoursDialog.tsx b/app/komunita/OpeningHoursDialog.tsx index d584768..2ab31ed 100644 --- a/app/komunita/OpeningHoursDialog.tsx +++ b/app/komunita/OpeningHoursDialog.tsx @@ -1,11 +1,11 @@ "use client"; -import { DAYS_CZECH, MONTHS_CZECH } from "@/utils/constants"; +import { DAYS_CZECH, MONTHS_CZECH, OpeningHoursForbiddenType, OpeningHoursType } from "@/utils/constants"; import React, { useEffect, useRef, useState } from "react"; +import OpeningHours from "../[type]/[nameID]/OpeningHours"; +import { Tower } from "@/typings"; -function OpeningHoursDialog() { +function OpeningHoursDialog({ tower }: { tower: Tower }) { const [step, setStep] = useState(1); - const [stepperData, setStepperData] = useState(null); - const [type, setType] = useState(""); const [occasionallyText, setOccasionallyText] = useState(""); @@ -49,6 +49,9 @@ function OpeningHoursDialog() { } break; case 2: + if ((type === "some_months" || type === "every_month") && weekType === "") { + return setErrorText("Nebyla zvolena žádná možnost."); + } if ((type === "some_months" || type === "every_month") && weekType === "some_days" && daysSelected.length === 0) { return setErrorText("Není vybrán žádný den."); } @@ -93,6 +96,49 @@ function OpeningHoursDialog() { setDayDoLunch(""); }; + const mapTypeEnum = (type: string): number => { + switch (type) { + case "freely_accessible": + return OpeningHoursType.NonStop; + case "some_months": + case "every_month": + return OpeningHoursType.Hours; + case "forbidden": + return OpeningHoursType.Forbidden; + case "occasionally": + return OpeningHoursType.Occasionally; + default: + return OpeningHoursType.Unknown; + } + }; + + const generateFinalOpeningHours = (): OpeningHours => { + let obj: OpeningHours = { + type: mapTypeEnum(type), + }; + if (type === "forbidden") { + if (goneType === "reconstruction") obj.forbidden_type = OpeningHoursForbiddenType.Reconstruction; + if (goneType === "gone") obj.forbidden_type = OpeningHoursForbiddenType.Gone; + if (goneType === "temporary") obj.forbidden_type = OpeningHoursForbiddenType.Temporary; + } + if (type === "forbidden" && goneText) obj.note = goneText; + if (type === "occasionally" && occasionallyText) obj.note = occasionallyText; + if (type === "every_month") obj.months = []; + if (type === "some_months") obj.months = [MONTHS_CZECH.indexOf(od_), MONTHS_CZECH.indexOf(do_)]; + if (type === "some_months" || type === "every_month") { + if (weekType === "every_day") obj.days = [0, 1, 2, 3, 4, 5, 6]; + if (weekType === "some_days") obj.days = daysSelected.map((e) => DAYS_CZECH.indexOf(e)).sort((a, b) => a - b); + obj.time_start = parseInt(dayOd.toString()); + obj.time_end = parseInt(dayDo.toString()); + if (lunchBreak) { + obj.lunch_break = true; + obj.lunch_start = parseInt(dayOdLunch.toString()); + obj.lunch_end = parseInt(dayDoLunch.toString()); + } + } + return obj; + }; + // months checker useEffect(() => { if (step === 1 && type === "some_months" && od_ && do_) { @@ -129,12 +175,15 @@ function OpeningHoursDialog() { return ( <> - +
dialogRef?.current?.showModal()} + > + Navrhnout úpravu +
-

Úprava otevírací doby [věže X]

+

Úprava otevírací doby {tower.name}

  • Stav
  • @@ -407,7 +456,7 @@ function OpeningHoursDialog() {
-
FINAL SCREEN
+
+

Takto bude vypadat nová dlaždice s otevírací dobou:

+ +
{errorText &&

{errorText}

} @@ -453,6 +505,9 @@ function OpeningHoursDialog() { > {type === "freely_accessible" || step === 3 ? "Dokončit" : "Pokračovat"} +
diff --git a/app/komunita/page.tsx b/app/komunita/page.tsx index 56a93fa..dfc3dd7 100644 --- a/app/komunita/page.tsx +++ b/app/komunita/page.tsx @@ -1,12 +1,10 @@ import React from "react"; import Navbar from "../Navbar"; -import OpeningHoursDialog from "./OpeningHoursDialog"; function ComunityPage() { return (
- Otevřeno, zavírá 20:00 diff --git a/ideas/openingHoursExample.json b/ideas/openingHoursExample.json index d404b32..4457524 100644 --- a/ideas/openingHoursExample.json +++ b/ideas/openingHoursExample.json @@ -21,3 +21,15 @@ } ] } + +{ + "type": 2, + "months": [1,2,3,4,5,6], + "days": [1,2,3,4,5,6], + "time_start": 8, + "time_end": 16, + "lunch_break": true, + "lunch_start": 12, + "lunch_end": 13, + "note": "ahoj, sth" +} diff --git a/scripts/operation_every_tower.ts b/scripts/operation_every_tower.ts new file mode 100644 index 0000000..711c879 --- /dev/null +++ b/scripts/operation_every_tower.ts @@ -0,0 +1,113 @@ +const admin = require("firebase-admin"); +const serviceAccount = require("./service_key.json"); + +admin.initializeApp({ + credential: admin.credential.cert(serviceAccount), + databaseURL: "https://lookout-towers-default-rtdb.europe-west1.firebasedatabase.app", +}); + +const db = admin.firestore(); +const towersRef = db.collection("towers"); + +enum OpeningHoursType { + Unknown, + NonStop, + Occasionally, + Hours, + Forbidden +} + +enum OpeningHoursForbiddenType { + Reconstruction, + Temporary, + Gone +} + +type OpeningHours = { + type: OpeningHoursType; + months?: number[]; + days?: number[]; + forbidden_type?: OpeningHoursForbiddenType; + time_start?: number; + time_end?: number; + lunch_break?: boolean; + lunch_start?: number; + lunch_end?: number; + note?: string; +} + +const unknownObject: OpeningHours = { + type: OpeningHoursType.Unknown +} + +const freeObject: OpeningHours = { + type: OpeningHoursType.NonStop +} + +const goneObject : OpeningHours = { + type: OpeningHoursType.Forbidden, + forbidden_type: OpeningHoursForbiddenType.Gone +} + +const generateNoteObject = (note: string): OpeningHours => { + return { + type: OpeningHoursType.Unknown, + note: note + } +} + +towersRef.get().then((querySnapshot : any) => { + querySnapshot.forEach(async (doc : any) => { + const towerDoc = towersRef.doc(doc.id) + const data = await towerDoc.get().then((e : any) => e.data()) + console.log("changing ", data.name) + if (!data.openingHours) { + await towerDoc.update({openingHours: unknownObject}) + } else { + if (typeof data.openingHours === 'object') { + return + } + if (data.openingHours === "neznámé") { + await towerDoc.update({openingHours: unknownObject}) + } + else if (data.openingHours === "volně přístupná") { + await towerDoc.update({openingHours: freeObject}) + } + else if (data.openingHours === "dlouhodobě uzavřena") { + await towerDoc.update({openingHours: goneObject}) + } + else { + await towerDoc.update({openingHours: generateNoteObject(data.openingHours || "")}) + } + } + }); +}); + + + + +/* const dod = async (id: string) => { + const towerDoc = towersRef.doc(id) + const data = await towerDoc.get().then((e : any) => e.data()) + if (!data.openingHours) { + await towerDoc.update({openingHours: unknownObject}) + } else { + if ("type" in data.openingHours) { + return + } + if (data.openingHours === "neznámé") { + await towerDoc.update({openingHours: unknownObject}) + } + else if (data.openingHours === "volně přístupná") { + await towerDoc.update({openingHours: freeObject}) + } + else if (data.openingHours === "dlouhodobě uzavřena") { + await towerDoc.update({openingHours: goneObject}) + } + else { + await towerDoc.update({openingHours: generateNoteObject(data.openingHours || "")}) + } + } +}; + +dod("fo9s2ELP7TtsD61xXM5e"); */ diff --git a/typings.d.ts b/typings.d.ts index 4a1a428..4cb254c 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -1,4 +1,5 @@ import { GeoPoint, Timestamp } from "firebase/firestore"; +import { OpeningHoursForbiddenType, OpeningHoursType } from "./utils/constants"; export type GPS = { latitude: number, @@ -49,7 +50,7 @@ export type TowerFirebase = { name: string; nameID: string; opened: Timestamp; - openingHours?: string; //todo + openingHours: OpeningHours; price?: number; //todo province?: string; stairs: number; @@ -81,7 +82,7 @@ export type Tower = { name: string; nameID: string; opened: Date; - openingHours?: string; //todo + openingHours: OpeningHours; price?: number; //todo province?: string; stairs: number; @@ -105,21 +106,14 @@ export type Rating = { } export type OpeningHours = { - unknown?: boolean; - free: boolean; - months_all: boolean; - months_range: number[]; - occasionally: boolean; - occasionally_text: string; - forbidden_reconstruction: boolean; - forbidden_temporary: boolean; - forbidden_gone: boolean; - week_all: boolean; - week_some: number[]; - time_start: number; - time_end: number; - lunch_break: boolean; - lunch_start: number; - lunch_end: number; + type: OpeningHoursType; + months?: number[]; + days?: number[]; + forbidden_type?: OpeningHoursForbiddenType; + time_start?: number; + time_end?: number; + lunch_break?: boolean; + lunch_start?: number; + lunch_end?: number; note?: string; } \ No newline at end of file diff --git a/utils/constants.ts b/utils/constants.ts index 139f3fc..b6160d7 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -303,4 +303,18 @@ export const DAYS_CZECH = [ "Pátek", "Sobota", "Neděle" -] \ No newline at end of file +] + +export enum OpeningHoursType { + Unknown, + NonStop, + Occasionally, + Hours, + Forbidden +} + +export enum OpeningHoursForbiddenType { + Reconstruction, + Temporary, + Gone +} \ No newline at end of file