Skip to content

Commit

Permalink
opening hours on tower site
Browse files Browse the repository at this point in the history
  • Loading branch information
dowl-air committed Jul 13, 2023
1 parent 6e045e5 commit 3453db3
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 67 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
scripts/service_key.json
77 changes: 43 additions & 34 deletions app/[type]/[nameID]/OpeningHours.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div
className={`card card-compact sm:card-normal min-w-[300px] max-w-[420px] sm:h-[225px] flex-1 overflow-hidden shadow-xl group bg-[rgba(255,255,255,0.05)]`}
>
<div className="card-body">
<h2 className="card-title text-xl">Otevírací doba</h2>
<p className={`text-lg ${test.unknown && "text-error"}`}>{generateHeading(test, "rozhledna")}</p>
<h2 className={`card-title text-xl ${isErrorColor(OH) && "text-error"}`}>Otevírací doba</h2>
<p className={`text-lg ${isErrorColor(OH) && "text-error"}`}>{generateHeading(OH, tower?.type || "rozhledna")}</p>
{OH.lunch_break && <p className={`text-lg ${isErrorColor(OH) && "text-error"}`}>{getLunchString(OH)}</p>}
{OH.note && <p>{OH.note}</p>}
</div>
<div className="btn btn-warning btn-sm hidden absolute top-[0.1rem] right-[0.5rem] group-hover:inline-flex">Navrhnout úpravu</div>
{children}
</div>
);
}
Expand Down
5 changes: 4 additions & 1 deletion app/[type]/[nameID]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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/";
Expand Down Expand Up @@ -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"}
>
<div className={"flex flex-wrap gap-3 w-full items-center justify-center"}>
<OpeningHours />
<OpeningHours tower={tower}>
<OpeningHoursDialog tower={tower} />
</OpeningHours>
<Admission />
<Parameters {...tower} />
</div>
Expand Down
77 changes: 66 additions & 11 deletions app/komunita/OpeningHoursDialog.tsx
Original file line number Diff line number Diff line change
@@ -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<number>(1);
const [stepperData, setStepperData] = useState<any>(null);

const [type, setType] = useState<string>("");

const [occasionallyText, setOccasionallyText] = useState<string>("");
Expand Down Expand Up @@ -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.");
}
Expand Down Expand Up @@ -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_) {
Expand Down Expand Up @@ -129,12 +175,15 @@ function OpeningHoursDialog() {

return (
<>
<button className="btn" onClick={() => dialogRef?.current?.showModal()}>
open modal
</button>
<div
className="btn btn-warning btn-sm hidden absolute top-[0.1rem] right-[0.5rem] group-hover:inline-flex"
onClick={() => dialogRef?.current?.showModal()}
>
Navrhnout úpravu
</div>
<dialog ref={dialogRef} id="modal_opening_hours" className="modal modal-bottom sm:modal-middle">
<div className="modal-box flex flex-col gap-3">
<h3 className="font-bold text-lg self-center text-base-content">Úprava otevírací doby [věže X]</h3>
<h3 className="font-bold text-lg self-center text-base-content">Úprava otevírací doby {tower.name}</h3>

<ul className="steps mb-2 text-base-content">
<li className="step step-primary">Stav</li>
Expand Down Expand Up @@ -407,7 +456,7 @@ function OpeningHoursDialog() {
</label>
<textarea
id="popis_gone_"
className="textarea textarea-primary"
className="textarea textarea-primary text-base-content"
placeholder="Odkaz nebo popis..."
maxLength={300}
value={goneText}
Expand All @@ -423,7 +472,7 @@ function OpeningHoursDialog() {
</label>
<textarea
id="popis_occ_"
className="textarea textarea-primary"
className="textarea textarea-primary text-base-content"
placeholder="Odkaz nebo popis..."
maxLength={300}
value={occasionallyText}
Expand All @@ -433,7 +482,10 @@ function OpeningHoursDialog() {
></textarea>
</div>

<div className={`${step === 4 ? "flex" : "hidden"} flex-col text-base-content`}>FINAL SCREEN</div>
<div className={`${step === 4 ? "flex" : "hidden"} flex-col items-center gap-3 text-base-content`}>
<h3>Takto bude vypadat nová dlaždice s otevírací dobou: </h3>
<OpeningHours openingHours={generateFinalOpeningHours()} />
</div>

{errorText && <p className="text-error self-end">{errorText}</p>}

Expand All @@ -453,6 +505,9 @@ function OpeningHoursDialog() {
>
{type === "freely_accessible" || step === 3 ? "Dokončit" : "Pokračovat"}
</button>
<button className={`btn btn-primary ${step === 4 ? "inline-flex" : "hidden"}`} onClick={() => {}}>
Odeslat
</button>
</div>
</div>
<form method="dialog" className="modal-backdrop">
Expand Down
2 changes: 0 additions & 2 deletions app/komunita/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from "react";
import Navbar from "../Navbar";
import OpeningHoursDialog from "./OpeningHoursDialog";

function ComunityPage() {
return (
<div>
<Navbar />
<OpeningHoursDialog />
<span className="inline-flex items-center bg-green-100 text-green-800 text-xs font-medium mr-2 px-2.5 py-0.5 rounded-full dark:bg-green-900 dark:text-green-300">
<span className="w-2 h-2 mr-1 bg-green-500 rounded-full"></span>
Otevřeno, zavírá 20:00
Expand Down
12 changes: 12 additions & 0 deletions ideas/openingHoursExample.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Loading

0 comments on commit 3453db3

Please sign in to comment.