Skip to content

Commit

Permalink
enforce user timezones
Browse files Browse the repository at this point in the history
  • Loading branch information
kenny-io committed Nov 13, 2024
1 parent 9b1da08 commit bbd5eb9
Showing 1 changed file with 51 additions and 70 deletions.
121 changes: 51 additions & 70 deletions frontend/src/app/uptime/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,104 +12,85 @@ export default async function Home() {
// Calculate timestamp for 24 hours ago
const twentyFourHoursAgo = Date.now() - (24 * 60 * 60 * 1000);

// Format time consistently using users's timezone
const formatTimeToLocal = (timestamp: number) => {
return new Date(timestamp).toLocaleTimeString(undefined, {
hour: 'numeric',
minute: '2-digit',
hour12: true
}).toLowerCase();
};

// Format date with time for tooltips
const formatDateTimeToLocal = (timestamp: number) => {
return new Date(timestamp).toLocaleString(undefined, {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit'
});
};

return (
<main className="flex flex-col items-center p-4 sm:p-8 md:p-16 lg:p-24 bg-white">
<h1 className="text-black font-regular my-2 text-lg sm:text-xl text-left justify-start w-full max-w-[930px]">Uptime Monitor</h1>
<div className="flex w-full max-w-[930px] h-full gap-2 gap-y-5 p-2 items-center flex-wrap">
<div className="flex w-full max-w-[930px] h-full gap-2 gap-y-3 sm:gap-y-5 p-2 items-center flex-wrap">
{services.map((service: Service, index: any) => {
// Filter services to only show last 24 hours
const last24HourServices = service.last10services.filter(s =>
Number(s.status.labels.timestamp) > twentyFourHoursAgo
);

return (
<div className="w-full p-3 sm:p-4 md:p-6 bg-white border border-gray-200 rounded-lg shadow" key={index + service.name} >
<h5 className="text-black text-lg sm:text-xl font-bold tracking-tight">{service.name}</h5>
<h5 className="text-black text-base sm:text-lg md:text-xl font-bold tracking-tight">{service.name}</h5>
<div className="flex justify-between">
<div className="flex flex-col flex-1">
<div className="w-full flex gap-[1px] mt-2 px-2 sm:px-4">
<div className="w-full sm:w-[95%] flex gap-[1px] sm:gap-[2px] overflow-x-auto">
{last24HourServices.map((lastService, index) => {
const dateTime = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}).format(Number(lastService.status.labels.timestamp))

return (
<div
className={`has-tooltip min-w-[8px] sm:min-w-[10px] h-6 sm:h-8 flex cursor-pointer ${lastService.status.value === 1 ? 'bg-green-500' : 'bg-red-500'}`}
key={lastService.name + index}
onClick={() => {
alert(
`Status: ${lastService.status.value === 1 ? 'Up' : 'Down'}\n` +
`Time: ${new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit'
}).format(Number(lastService.status.labels.timestamp))}\n` +
`${lastService.status.value === 0 ? 'Error: Service was unreachable' : 'Service was operating normally'}`
)
}}>
<span className='tooltip rounded shadow-lg p-1 bg-gray-100 text-orange-950 -mt-8 text-xs sm:text-sm'>{new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit'
}).format(Number(lastService.status.labels.timestamp))}</span>
&nbsp;
</div>
)
})}
<div className="w-[95%] flex gap-[1px] sm:gap-[2px]">
{last24HourServices.map((lastService, index) => {
const timestamp = Number(lastService.status.labels.timestamp);

return (
<div
className={`has-tooltip w-[8px] sm:w-[10px] h-full flex cursor-pointer ${lastService.status.value === 1 ? 'bg-green-500' : 'bg-red-500'}`}
key={lastService.name + index}
onClick={() => {
alert(
`Status: ${lastService.status.value === 1 ? 'Up' : 'Down'}\n` +
`Time: ${formatDateTimeToLocal(timestamp)}\n` +
`${lastService.status.value === 0 ? 'Error: Service was unreachable' : 'Service was operating normally'}`
)
}}>
<span className='tooltip rounded shadow-lg p-1 bg-gray-100 text-orange-950 -mt-8 text-xs sm:text-sm'>
{formatDateTimeToLocal(timestamp)}
</span>
&nbsp;
</div>
)
})}
</div>
</div>
</div>
</div>
<div className="inline-flex items-center ml-2">
<label className="relative flex items-center p-2 sm:p-3 rounded-full cursor-pointer" htmlFor="amber">
{
service.status.value === 1 ? (
<input type="checkbox"
className="before:content[''] peer relative h-4 w-4 sm:h-5 sm:w-5 rounded-full cursor-pointer appearance-none border border-blue-gray-200 transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-green-500 checked:bg-green-500 checked:before:bg-green-500 hover:before:opacity-10"
id="amber" checked readOnly />
) : (
<input type="checkbox"
className="before:content[''] peer relative h-4 w-4 sm:h-5 sm:w-5 rounded-full cursor-pointer appearance-none border border-blue-gray-200 transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity checked:border-red-500 checked:bg-red-500 checked:before:bg-red-500 hover:before:opacity-10"
id="amber" checked readOnly />
)
}
<span
className="absolute text-white transition-opacity opacity-0 pointer-events-none top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100">
<svg xmlns="http://www.w3.org/2000/svg" className="h-3 w-3 sm:h-3.5 sm:w-3.5" viewBox="0 0 20 20" fill="currentColor"
stroke="currentColor" strokeWidth="1">
<path fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"></path>
</svg>
</span>
</label>
</div>
</div>
<div className="mt-2 flex w-full justify-between items-center gap-2 text-xs sm:text-sm">
<div className="mt-2 flex w-full justify-between items-center gap-1 sm:gap-2 text-xs sm:text-sm md:text-base">
<div className="item light legend-item-date-range">
<span className="availability-time-line-legend-day-count">
{formatDistanceToNow(new Date(Number(last24HourServices[0]?.status.labels.timestamp)))} ago
</span>
</div>
<div className="spacer border h-[0.5px] flex-1 hidden sm:block"></div>
<div className="legend-item legend-item-uptime-value legend-item-pc5t8fy4tf59">
<div className="spacer border h-[0.5px] flex-1"></div>
<div className="legend-item legend-item-uptime-value whitespace-nowrap">
<span id="font-bold">
<var data-var="uptime-percent">
{(last24HourServices.filter(s => s.status.value === 1).length / last24HourServices.length * 100).toFixed(2)}
</var>
</span>
% uptime
</div>
<div className="spacer border h-[0.5px] flex-1 hidden sm:block"></div>
<div className="legend-item light legend-item-date-range">{new Date().toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }).toLowerCase()}</div>
<div className="spacer border h-[0.5px] flex-1"></div>
<div className="legend-item light legend-item-date-range">
{formatTimeToLocal(Date.now())}
</div>
</div>
</div>
)})}
Expand Down

0 comments on commit bbd5eb9

Please sign in to comment.