Untitled
unknown
javascript
2 years ago
7.5 kB
7
Indexable
'use client';
import { useEffect, useState } from "react";
import data from './data.json';
export default function Page() {
return (
<MainComponent>
<HeaderComponent/>
<TableComponent/>
</MainComponent>
)
}
function MainComponent({children}:{children:React.ReactNode}){
return (
<div className="flex flex-col items-center">
{children}
</div>
)
}
function HeaderComponent(){
return (
<div className="bg-[#F45B69] flex h-12 w-full justify-around ">
<div className="flex flex-row child:flex-1 items-center w-full divide-x divide-slate-600 text-white">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 10.5v6m3-3H9m4.06-7.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
</svg>
<div className=" text-center ">Prev</div>
<div className=" text-center ">Current</div>
<div className=" text-center ">Next</div>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</div>
</div>
)
}
function TableComponent(){
const hours = [8,9,10,11,12,13,14,15,16,17,18,19,20,21,22];
return (
<div className="bg-[#2e3f45] text-white w-full p-5 pb-3">
<div className="flex flex-col">
<div className="flex flex-row ">
<div className="w-10 flex-none"></div>
<div className="flex flex-row w-full">
{
data.map(day =>
<div key={day.id} className="flex-1 text-center font-bold">
<div className="">{day["day"].slice(0, 3)}</div>
<div className="mx-5 rounded-full border-2 ">{day["date"]}</div>
<div className="h-3 border-l-0.1"></div>
</div>
)
}
</div>
</div>
<div className="flex flex-row">
<div className="flex flex-col">
{hours.map(hour =>
<div key={hour} className="flex flex-row h-12">
<div className="w-8 text-right pr-1 relative bottom-3 text-sm">{hour}u</div>
<div className="w-2 border-t-0.1"></div>
</div>
)}
</div>
<div className="flex flex-row w-full">
{
data.map(day =>
<div key={day.id} className="flex-1 grid grid-cols-1">
{hours
.filter(hour => !day.timeslots.some(timeslot => timeslot.start < hour && hour < timeslot.end ))
.map((hour, i, arr) =>
<div key={hour} className={`border-t-0.1 border-l-0.1 h-full ${rowspan(arr[i+1] - hour)}`}>
{day.timeslots.filter(timeslot => (timeslot.start == hour)).map(timeslot => <TimeslotComponent key={timeslot.id} title={timeslot.title} names={timeslot.names}/> )}
</div>)
}
</div>
)
}
</div>
</div>
</div>
</div>
)
}
function TimeslotComponent({title, names}:{title:string, names:string[]}){
const myName = "Saba"
const [available, setAvailable] = useState(!!names.includes(myName));
const [show, setShow] = useState(false);
useEffect(() => {
if (available) {
if (!names.includes(myName)){
names.push(myName)
}
}else {
names.splice(names.findIndex(name => name == myName), 1)
}
}, [available])
return (
<div className="relative z-1 h-full">
<div className="absolute right-0 left-0 top-0 p-0.5 bg-zinc-50 m-0.5">
<div className=" pt-0 p-1 lg:text-sm text-xs font-mono rounded-lg rounded-bl-none rounded-tr-none rounded-tl-none min-h-full w-full bg-[#7c4145]" onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)} >
<div className="lg:flex justify-between">
<div className="font-white font-semibold capitalize lg:underline underline-offset-4 decoration-pink-500 decoration-2 lg:mt-1">{title}</div>
<IsAvailableButton available={available} setAvailable={setAvailable}/>
</div>
{show && <div className=" capitalize">{names.map(name => <div className="block">{name}</div>)}</div>}
</div>
</div>
<div className="bg-[#3F565F] w-1 ml-0.5 h-full z-0">
</div>
</div>
)
}
function IsAvailableButton({available, setAvailable}:{available:boolean, setAvailable:React.Dispatch<React.SetStateAction<boolean>>}){
if (available) {
return <button className="bg-green-500 border-transparent text-white font-semibold px-1 lg:mt-1 border rounded hover:border-green-500 hover:bg-transparent hover:text-green-700" onClick={() => setAvailable(false)}>Free</button>
}else{
return <button className="bg-red-500 border-transparent text-white font-semibold px-1 lg:mt-1 border rounded hover:border-red-500 hover:bg-transparent hover:text-red-700" onClick={() => setAvailable(true)}>Busy</button>
}
}
function rowspan(i:number){
const rowspans = [
'row-span-1','row-span-2','row-span-3','row-span-4','row-span-5','row-span-6','row-span-7','row-span-8',
'row-span-9','row-span-10','row-span-11','row-span-12','row-span-13','row-span-14','row-span-15','row-span-16',
'row-span-17','row-span-18','row-span-19','row-span-20','row-span-21','row-span-22','row-span-23','row-span-24'
];
return rowspans[i-1];
}
Editor is loading...