commit
e5ac72258e
5 changed files with 354 additions and 902 deletions
1069
package-lock.json
generated
1069
package-lock.json
generated
File diff suppressed because it is too large
Load diff
12
package.json
12
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "raceway",
|
"name": "raceway",
|
||||||
"version": "0.0.15",
|
"version": "0.0.16",
|
||||||
"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.0",
|
"next": "^16.3.5",
|
||||||
"react": "19.2.8",
|
"react": "19.3.0",
|
||||||
"react-dom": "19.2.8"
|
"react-dom": "19.3.0"
|
||||||
},
|
},
|
||||||
"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.0",
|
"eslint-config-next": "16.3.5",
|
||||||
"sass": "^1.102.0",
|
"sass": "^1.104.1",
|
||||||
"tailwindcss": "^4"
|
"tailwindcss": "^4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,64 +4,50 @@
|
||||||
"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",
|
"timeStart": "07:30",
|
||||||
"timeEnd": "09",
|
"timeEnd": "09:00"
|
||||||
"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",
|
"timeStart": "07:30",
|
||||||
"timeEnd": "19",
|
"timeEnd": "19:30"
|
||||||
"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",
|
"timeStart": "10:00",
|
||||||
"timeEnd": "12",
|
"timeEnd": "12:00"
|
||||||
"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",
|
"timeStart": "12:00",
|
||||||
"timeEnd": "14",
|
"timeEnd": "14:00"
|
||||||
"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",
|
"timeStart": "14:00",
|
||||||
"timeEnd": "16",
|
"timeEnd": "16:00"
|
||||||
"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",
|
"timeStart": "16:00",
|
||||||
"timeEnd": "18",
|
"timeEnd": "18:00"
|
||||||
"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",
|
"timeStart": "18:00",
|
||||||
"timeEnd": "20",
|
"timeEnd": "20:00"
|
||||||
"textStart": "6 PM",
|
|
||||||
"textEnd": "8 PM"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,25 @@ 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 timeStart = parseInt(item.timeStart);
|
const startMinutes = timeToMinutes(item.timeStart);
|
||||||
const timeEnd = parseInt(item.timeEnd);
|
const endMinutes = timeToMinutes(item.timeEnd);
|
||||||
|
|
||||||
return currentHour >= timeStart && currentHour < timeEnd;
|
return (
|
||||||
|
currentMinutes >= startMinutes &&
|
||||||
|
currentMinutes < endMinutes
|
||||||
|
);
|
||||||
}) || [];
|
}) || [];
|
||||||
|
|
||||||
setDailyItems(
|
setDailyItems(
|
||||||
|
|
@ -128,6 +137,48 @@ 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) || [];
|
||||||
|
|
@ -156,25 +207,28 @@ 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}>
|
||||||
{item.title}
|
<span>{item.title}</span>
|
||||||
|
|
||||||
|
<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}>
|
|
||||||
{item.textStart && item.textEnd ? (
|
<span className={styles.listItemProgress}>
|
||||||
<>
|
<span
|
||||||
{item.textStart} - {item.textEnd}
|
className={styles.listItemProgressBar}
|
||||||
</>
|
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}>
|
||||||
|
|
|
||||||
|
|
@ -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,12 +104,23 @@
|
||||||
|
|
||||||
.listItemTitle {
|
.listItemTitle {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: flex;
|
||||||
|
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 {
|
||||||
|
|
@ -121,16 +132,6 @@
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +139,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue