Compare commits

..

No commits in common. "e5ac72258ecf33231c40667977bfdcee7eef8280" and "1ef137340845f204ce0c519109fb8958a47a90a8" have entirely different histories.

5 changed files with 902 additions and 354 deletions

1069
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{ {
"name": "raceway", "name": "raceway",
"version": "0.0.16", "version": "0.0.15",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
@ -10,16 +10,16 @@
}, },
"dependencies": { "dependencies": {
"@marzzelo/windir": "^1.2.3", "@marzzelo/windir": "^1.2.3",
"next": "^16.3.5", "next": "^16.3.0",
"react": "19.3.0", "react": "19.2.8",
"react-dom": "19.3.0" "react-dom": "19.2.8"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
"babel-plugin-react-compiler": "1.0.0", "babel-plugin-react-compiler": "1.0.0",
"eslint": "^10", "eslint": "^10",
"eslint-config-next": "16.3.5", "eslint-config-next": "16.3.0",
"sass": "^1.104.1", "sass": "^1.102.0",
"tailwindcss": "^4" "tailwindcss": "^4"
} }
} }

View file

@ -4,50 +4,64 @@
"title": "Opening Checklist", "title": "Opening Checklist",
"desc": "Complete the opening checklist to ensure all equipment is operational and ready for the day.", "desc": "Complete the opening checklist to ensure all equipment is operational and ready for the day.",
"type": "3", "type": "3",
"timeStart": "07:30", "timeStart": "07",
"timeEnd": "09:00" "timeEnd": "09",
"textStart": "7 AM",
"textEnd": "9 AM"
}, },
{ {
"title": "Daily Maintenance Checklist", "title": "Daily Maintenance Checklist",
"desc": "Perform daily maintenance tasks to keep equipment running smoothly.", "desc": "Perform daily maintenance tasks to keep equipment running smoothly.",
"type": "3", "type": "3",
"timeStart": "07:30", "timeStart": "07",
"timeEnd": "19:30" "timeEnd": "19",
"textStart": "7 AM",
"textEnd": "7 PM"
}, },
{ {
"title": "Site Inspection Checklist", "title": "Site Inspection Checklist",
"desc": "Conduct a thorough inspection of the site to identify any potential issues.", "desc": "Conduct a thorough inspection of the site to identify any potential issues.",
"type": "4", "type": "4",
"timeStart": "10:00", "timeStart": "10",
"timeEnd": "12:00" "timeEnd": "12",
"textStart": "10 AM",
"textEnd": "12 PM"
}, },
{ {
"title": "Site Inspection Checklist", "title": "Site Inspection Checklist",
"desc": "Conduct a thorough inspection of the site to identify any potential issues.", "desc": "Conduct a thorough inspection of the site to identify any potential issues.",
"type": "4", "type": "4",
"timeStart": "12:00", "timeStart": "12",
"timeEnd": "14:00" "timeEnd": "14",
"textStart": "12 PM",
"textEnd": "2 PM"
}, },
{ {
"title": "Site Inspection Checklist", "title": "Site Inspection Checklist",
"desc": "Conduct a thorough inspection of the site to identify any potential issues.", "desc": "Conduct a thorough inspection of the site to identify any potential issues.",
"type": "4", "type": "4",
"timeStart": "14:00", "timeStart": "14",
"timeEnd": "16:00" "timeEnd": "16",
"textStart": "2 PM",
"textEnd": "4 PM"
}, },
{ {
"title": "Site Inspection Checklist", "title": "Site Inspection Checklist",
"desc": "Conduct a thorough inspection of the site to identify any potential issues.", "desc": "Conduct a thorough inspection of the site to identify any potential issues.",
"type": "4", "type": "4",
"timeStart": "16:00", "timeStart": "16",
"timeEnd": "18:00" "timeEnd": "18",
"textStart": "4 PM",
"textEnd": "6 PM"
}, },
{ {
"title": "Closing Checklist", "title": "Closing Checklist",
"desc": "Complete the closing checklist to ensure all equipment is properly shut down for the day and ready for tomorrow.", "desc": "Complete the closing checklist to ensure all equipment is properly shut down for the day and ready for tomorrow.",
"type": "3", "type": "3",
"timeStart": "18:00", "timeStart": "18",
"timeEnd": "20:00" "timeEnd": "20",
"textStart": "6 PM",
"textEnd": "8 PM"
} }
] ]
} }

View file

@ -93,25 +93,16 @@ export default function WeatherPage() {
const [dailyItems, setDailyItems] = useState([]); const [dailyItems, setDailyItems] = useState([]);
useEffect(() => { useEffect(() => {
const timeToMinutes = (time) => {
const [hours, minutes] = time.split(":").map(Number);
return hours * 60 + minutes;
};
const updateDailyItems = () => { const updateDailyItems = () => {
const now = new Date(); const now = new Date();
const currentHour = now.getHours();
const currentMinutes = now.getHours() * 60 + now.getMinutes();
const filteredItems = const filteredItems =
List?.List?.filter((item) => { List?.List?.filter((item) => {
const startMinutes = timeToMinutes(item.timeStart); const timeStart = parseInt(item.timeStart);
const endMinutes = timeToMinutes(item.timeEnd); const timeEnd = parseInt(item.timeEnd);
return ( return currentHour >= timeStart && currentHour < timeEnd;
currentMinutes >= startMinutes &&
currentMinutes < endMinutes
);
}) || []; }) || [];
setDailyItems( setDailyItems(
@ -137,48 +128,6 @@ export default function WeatherPage() {
return () => clearInterval(interval); return () => clearInterval(interval);
}, [List]); }, [List]);
// show the percentage of time between timeStart and timeEnd for each of the daily tasks and update it automatically ocne a second. show the decimal places up to 5 decimals
const getTaskProgress = (item) => {
if (!item.timeStart || !item.timeEnd) return 0;
const [startHour, startMinute] = item.timeStart.split(":").map(Number);
const [endHour, endMinute] = item.timeEnd.split(":").map(Number);
const now = new Date();
const start = new Date(now);
start.setHours(startHour, startMinute, 0, 0);
const end = new Date(now);
end.setHours(endHour, endMinute, 0, 0);
const current = now.getTime();
const startTime = start.getTime();
const endTime = end.getTime();
const total = endTime - startTime;
const elapsed = current - startTime;
if (total <= 0) return 0;
return Math.min(Math.max(elapsed / total, 0), 1) * 100;
};
const formatTime = (time) => {
if (!time || time === "--") return "--";
const [hours, minutes] = time.split(":").map(Number);
const date = new Date();
date.setHours(hours, minutes, 0, 0);
return date.toLocaleTimeString([], {
hour: "numeric",
minute: "2-digit",
});
};
const weatherAlerts = weather?.alerts || []; const weatherAlerts = weather?.alerts || [];
const futureForecasts = weather?.daily?.data.slice(1, 4) || []; const futureForecasts = weather?.daily?.data.slice(1, 4) || [];
@ -207,28 +156,25 @@ export default function WeatherPage() {
{dailyItems?.map((item, index) => ( {dailyItems?.map((item, index) => (
<span key={index} className={styles.dailyListItem}> <span key={index} className={styles.dailyListItem}>
<span className={styles.listItemTitle}> <span className={styles.listItemTitle}>
<span>{item.title}</span> {item.title}
<span className={styles.listItemTime}>
{formatTime(item.timeStart)} -{" "}
{formatTime(item.timeEnd)}
</span>
</span> </span>
<span className={styles.listItemDesc}> <span className={styles.listItemDesc}>
{item.desc} {item.desc}
</span> </span>
<span className={styles.listItemTime}>
<span className={styles.listItemProgress}> {item.textStart && item.textEnd ? (
<span <>
className={styles.listItemProgressBar} {item.textStart} - {item.textEnd}
style={{ </>
width: `${getTaskProgress(item)}%`, ) : (
}} <>
/> {item.timeStart}:00 - {item.timeEnd}
:00
</>
)}
</span> </span>
</span> </span>
))} )) || "Test"}
</span> </span>
<span className={styles.lists}> <span className={styles.lists}>
<span className={styles.listHeader}> <span className={styles.listHeader}>

View file

@ -79,8 +79,8 @@
.lists { .lists {
flex: 1 1 100%; flex: 1 1 100%;
border-radius: 10px; border-radius: 10px;
/* background: #17171b; */ background: #17171b;
/* border: 1px solid rgba(200, 200, 200, 0.2); */ border: 1px solid rgba(200, 200, 200, 0.2);
.listHeader { .listHeader {
margin: 5px; margin: 5px;
@ -104,23 +104,12 @@
.listItemTitle { .listItemTitle {
width: 100%; width: 100%;
display: flex; display: block;
align-items: center;
justify-content: space-between;
font-size: 16pt; font-size: 16pt;
font-weight: bold; font-weight: bold;
margin: 0 0 5px 0; margin: 0 0 5px 0;
color: rgba(255, 255, 255, 0.95); color: rgba(255, 255, 255, 0.95);
border-bottom: 1px solid rgba(200, 200, 200, 0.2); border-bottom: 1px solid rgba(200, 200, 200, 0.2);
padding-bottom: 5px;
.listItemTime {
font-size: 8pt;
font-weight: normal;
white-space: nowrap;
color: rgba(255, 255, 255, 0.65);
margin-left: 10px;
}
} }
.listItemDesc { .listItemDesc {
@ -132,6 +121,16 @@
color: rgba(255, 255, 255, 0.75); color: rgba(255, 255, 255, 0.75);
} }
.listItemTime {
width: 100%;
font-size: 8pt;
display: block;
text-align: right;
padding: 5px 0 0 0;
color: rgba(255, 255, 255, 0.8);
border-top: 1px solid rgba(200, 200, 200, 0.075);
}
&:last-child { &:last-child {
border-radius: 2px 2px 5px 5px; border-radius: 2px 2px 5px 5px;
} }
@ -139,24 +138,6 @@
} }
} }
.listItemProgress {
display: block;
width: 100%;
height: 6px;
margin-top: 8px;
background: #333;
border-radius: 999px;
overflow: hidden;
}
.listItemProgressBar {
display: block;
height: 100%;
background: #4caf50;
border-radius: 999px;
transition: width 0.5s linear;
}
.weatherContainer { .weatherContainer {
flex: 1 1 30%; flex: 1 1 30%;
margin: 0 0 0 5px; margin: 0 0 0 5px;