Skip to content

Commit

Permalink
new timemachine modal from navbar
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperMitic committed Oct 26, 2024
1 parent b1130b8 commit 30888dd
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 120 deletions.
11 changes: 0 additions & 11 deletions client/app/(time)/layout.tsx

This file was deleted.

61 changes: 0 additions & 61 deletions client/app/(time)/timemachine/page.tsx

This file was deleted.

88 changes: 83 additions & 5 deletions client/components/navbar/Clock.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import React, { useState, useEffect } from "react";
import { Modal, ModalContent, ModalHeader, ModalBody } from "@nextui-org/react";
import TimeModifierClient from "@/components/timemachine/content";
import {
changeCurrentTime,
resetTime,
getCurrentTime,
} from "@/actions/setTime";

export const Clock = () => {
const [time, setTime] = useState<Date | null>(null);
const [isOpen, setIsOpen] = useState(false);

// Fetch the current time from the server (db)
async function fetchCurrentTime() {
try {
const res = await fetch("/api/config/time", {
Expand All @@ -27,6 +36,7 @@ export const Clock = () => {
}
}

// Update the timer every second
useEffect(() => {
fetchCurrentTime();

Expand All @@ -40,7 +50,44 @@ export const Clock = () => {
}, 1000);

return () => clearInterval(timer);
}, []);
}, [isOpen]);

if (!time) {
return <div>Loading...</div>;
}

const handleTimeChange = async (formData: FormData) => {
const time = formData.get("time") as string;
try {
await changeCurrentTime(new Date(time));
await fetchCurrentTime();
return { success: true };
} catch (error: any) {
console.log(error);
return { success: false, error: error.message };
}
};

const handleTimeReset = async () => {
try {
await resetTime();
await fetchCurrentTime();
return { success: true };
} catch (error: any) {
console.log(error);
return { success: false, error: error.message };
}
};

const handleGetCurrentTime = async () => {
try {
const result = await getCurrentTime();
return { currentTime: result.currentTime };
} catch (error: any) {
console.log(error);
return { currentTime: "", error: error.message };
}
};

if (!time) {
return <div>Loading...</div>;
Expand All @@ -54,9 +101,40 @@ export const Clock = () => {
};

return (
<div className="text-md font-light flex flex-col items-center leading-tight">
<div>{formatDate(time)}</div>
<div>{time.toLocaleTimeString()}</div>
</div>
<>
<div
className="text-md font-light flex flex-col items-center leading-tight cursor-pointer hover:opacity-80"
onClick={() => setIsOpen(true)}
>
<div>{formatDate(time)}</div>
<div>{time.toLocaleTimeString()}</div>
</div>

<Modal
isOpen={isOpen}
onOpenChange={setIsOpen}
size="sm"
placement="center"
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1 items-center">
Time Machine
</ModalHeader>
<ModalBody>
<TimeModifierClient
onSubmit={handleTimeChange}
onReset={handleTimeReset}
onGetCurrentTime={handleGetCurrentTime}
onClose={() => setIsOpen(false)}
initialTime={time}
/>
</ModalBody>
</>
)}
</ModalContent>
</Modal>
</>
);
};
99 changes: 60 additions & 39 deletions client/components/timemachine/content.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
"use client";
import React from "react";
import { now, getLocalTimeZone } from "@internationalized/date";
import { DatePicker, Button } from "@nextui-org/react";
import {
now,
getLocalTimeZone,
parseZonedDateTime,
parseDateTime,
parseDate,
CalendarDateTime,
} from "@internationalized/date";
import { DatePicker } from "@nextui-org/react";
import { Card, CardBody, Button, Input } from "@nextui-org/react";

interface TimeModifierClientProps {
onSubmit: (
formData: FormData,
) => Promise<{ success: boolean; error?: string }>;
onReset: () => Promise<{ success: boolean; error?: string }>;
onGetCurrentTime: () => Promise<{ currentTime: string; error?: string }>;
onClose?: () => void; // Aggiungiamo questa prop per gestire la chiusura del modal
initialTime: Date;
}

const TimeModifierClient: React.FC<TimeModifierClientProps> = ({
onSubmit,
onReset,
onGetCurrentTime,
onClose,
initialTime,
}) => {
const [time, setTime] = React.useState(
now(getLocalTimeZone()).toDate().toISOString(),
);
const [time, setTime] = React.useState(initialTime.toISOString());
const [state, setState] = React.useState({ success: false, error: null });
const [currentTime, setCurrentTime] = React.useState<string | null>(null);

Expand All @@ -37,52 +47,63 @@ const TimeModifierClient: React.FC<TimeModifierClientProps> = ({
const handleReset = async () => {
const response = await onReset();
setState(response as any);
};

const handleGetCurrentTime = async () => {
try {
const response = await onGetCurrentTime();
if (response.currentTime) {
setCurrentTime(response.currentTime);
} else if (response.error) {
setState({ success: false, error: null });
}
} catch (error: any) {
setState({ success: false, error: null });
if (response.success) {
// Chiudi il modal dopo un breve delay per mostrare il messaggio di successo
setTimeout(() => {
onClose?.();
}, 1000);
}
};

// Convert Date to type DateValue for
const convertToCalendarDateTime = (date: Date) => {
return new CalendarDateTime(
date.getFullYear(),
date.getMonth() + 1,
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
);
};

return (
<form onSubmit={handleSubmit}>
<div className="flex justify-items-center flex-col gap-5">
<h2 className="text-center bold">Time Machine</h2>
<form onSubmit={handleSubmit} className="px-4 py-2">
<div className="flex justify-items-center flex-col gap-4 items-center">
<DatePicker
label="Travel to ..."
variant="bordered"
hideTimeZone
showMonthAndYearPickers
defaultValue={now(getLocalTimeZone())}
onChange={(date) => setTime(date.toDate().toISOString())}
// Usa initialTime come valore di default
defaultValue={convertToCalendarDateTime(initialTime)}
onChange={(date) =>
setTime(date.toDate(getLocalTimeZone()).toISOString())
}
className="max-w-60"
/>
<input type="hidden" name="time" value={time} />
<Button color="primary" variant="shadow" type="submit">
Change Current Time
</Button>
<Button color="secondary" variant="shadow" onClick={handleReset}>
Reset Time
</Button>
<Button color="success" variant="shadow" onClick={handleGetCurrentTime}>
Get Current Time
</Button>
{currentTime && (
<p className="text-blue-500">
Current Time: {new Date(currentTime).toLocaleString()}
</p>
)}
{state.success && (
<p className="text-green-500">Time changed successfully!</p>
)}
{state.error && <p className="text-red-500">{state.error}</p>}

<div className="flex gap-2 justify-center">
<Button color="primary" variant="shadow" type="submit">
Change Time
</Button>
<Button color="danger" variant="shadow" onClick={handleReset}>
Reset Time
</Button>
</div>

<div className="min-h-[20px]">
{state.success && (
<p className="text-green-500 text-center text-sm">
Time changed successfully!
</p>
)}
{state.error && (
<p className="text-red-500 text-center text-sm">{state.error}</p>
)}
</div>
</div>
</form>
);
Expand Down
10 changes: 6 additions & 4 deletions server/src/routes/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ function createTimeRouter(db) {
const router = express.Router();

router.post("/time", cookieJwtAuth, function (req, res, next) {
if (req.user.role !== "admin") {
// TODO: Remove this
/*if (req.user.role !== "admin") {
return res
.status(403)
.json({ message: "You are not authorized to change the time" });
}
}*/

if (!req.body.date) {
return res.status(400).json({ message: "Time required" });
Expand All @@ -27,11 +28,12 @@ function createTimeRouter(db) {
});

router.delete("/time", cookieJwtAuth, function (req, res, next) {
if (req.user.role !== "admin") {
// TODO: Remove this
/*if (req.user.role !== "admin") {
return res
.status(403)
.json({ message: "You are not authorized to change the time" });
}
}*/

try {
db.changeDateTime(null, true);
Expand Down

0 comments on commit 30888dd

Please sign in to comment.