Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FU-345] base schedule #95

Merged
merged 12 commits into from
Jan 6, 2025
Prev Previous commit
Next Next commit
FU-345 feat: add time selector
eujin-shin committed Dec 16, 2024
commit a35f3d2014b4a6a88e6269a6649b6ebcc545f42d
32 changes: 32 additions & 0 deletions src/components/inputs/input.css.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,38 @@ import sprinkles from "@/styles/sprinkles.css";
import { texts } from "@/styles/text.css";
import { style, styleVariants } from "@vanilla-extract/css";

export const timeSelectorStyles = styleVariants({
container: [
sprinkles({
backgroundColor: "white",
borderColor: "stroke-grey",
color: "text-01",
}),
texts["body-01"],
{
position: "relative",
borderRadius: 8,
borderWidth: 1,
borderStyle: "solid",
padding: "8px 18px",
},
],
dropdown: [
sprinkles({ borderColor: "stroke-grey" }),
{
padding: "8px 0px 8px 8px",
borderWidth: 1,
borderStyle: "solid",
borderRadius: 8,
boxShadow: "0px 10px 25px 0px #00000026",
display: "flex",
maxHeight: 180,
},
],
list: { overflowY: "scroll", padding: 0 },
selectedValue: [sprinkles({ backgroundColor: "blue", color: "white" })],
});

const baseCheckbox = style({
borderRadius: 4,
height: 24,
108 changes: 108 additions & 0 deletions src/components/inputs/time-selector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { DateTime } from "luxon";
import { TimeUnitType } from "calender-types";
import { Menu } from "@mantine/core";
import { timeSelectorStyles } from "./input.css";

const TimeSelector = ({
time,
setTime,
minTime,
maxTime,
unit,
}: {
time: string;
setTime: (newTime: string) => void;
minTime?: string;
maxTime?: string;
unit: TimeUnitType;
}) => {
const hours = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23,
];
const minutes = [0, 30];
const timeValue = DateTime.fromFormat(time, "HH:mm:ss");

function setHour(hour: number) {
const newTimeValue = timeValue.set({ hour });
setTime(newTimeValue.toFormat("HH:mm:ss"));
}

function setMinute(minute: number) {
const newTimeValue = timeValue.set({ minute });
setTime(newTimeValue.toFormat("HH:mm:ss"));
}

function checkAbility(hour: number, minute: number) {
return (
(!minTime ||
DateTime.fromObject({ hour, minute }) >
DateTime.fromFormat(minTime, "HH:mm:ss")) &&
(!maxTime ||
DateTime.fromObject({ hour, minute }) <
DateTime.fromFormat(maxTime, "HH:mm:ss"))
);
}

function formatHour(hour: number) {
const hourValue = DateTime.fromObject({ hour, minute: 0 });
return unit === "SIXTY_MINUTES"
? hourValue.toFormat("HH:mm")
: hourValue.toFormat("HH");
}

return (
<Menu withArrow position="bottom">
<Menu.Target>
<button className={timeSelectorStyles.container} type="button">
{timeValue.toFormat("HH:mm")}
</button>
</Menu.Target>
<Menu.Dropdown className={timeSelectorStyles.dropdown}>
<div className={timeSelectorStyles.list}>
<div>
{hours
.filter((hour) => checkAbility(hour, timeValue.minute))
.map((hour) => (
<Menu.Item
key={hour}
autoFocus={hour === timeValue.hour}
onClick={() => setHour(hour)}
className={
hour === timeValue.hour
? timeSelectorStyles.selectedValue
: undefined
}
>
<span>{formatHour(hour)}</span>
</Menu.Item>
))}
</div>
</div>
{unit === "THIRTY_MINUTES" && (
<div className={timeSelectorStyles.list}>
<div>
{minutes
.filter((minute) => checkAbility(timeValue.hour, minute))
.map((minute) => (
<Menu.Item
key={minute}
onClick={() => setMinute(minute)}
className={
minute === timeValue.minute
? timeSelectorStyles.selectedValue
: undefined
}
>
<span>{minute}</span>
</Menu.Item>
))}
</div>
</div>
)}
</Menu.Dropdown>
</Menu>
);
};

export default TimeSelector;