salat
Version:
Daily Moroccan prayers time, right in your console, at the tip of your fingers
58 lines (57 loc) • 4.99 kB
JavaScript
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import { ProgressBar } from "#components/ProgressBar";
import { RamadanInfo } from "#components/RamadanInfo";
import { useHijriDate } from "#hooks/useHijriDate";
import { usePrayerTimes } from "#hooks/usePrayerTimes";
import { getImsakTime, getNextPrayer, getPrayerProgress, getRamadanData, tConv24 } from "#services/utils/time";
import { format } from "date-fns";
import { Box, Text, useApp, useInput } from "ink";
import { useEffect, useState } from "react";
const App = ({ cityNameArg, once, onReset }) => {
const { exit } = useApp();
const { prayerTimes, tomorrowTimes, error, loading, resolvedCityName } = usePrayerTimes({
cityNameArg,
});
const { hijriDate } = useHijriDate();
const [currentTime, setCurrentTime] = useState(new Date());
useInput((input) => {
const key = input.toLowerCase();
if (key === "c" && onReset) {
onReset();
}
});
useEffect(() => {
if (once)
return;
const timer = setInterval(() => {
setCurrentTime(new Date());
}, 1000);
return () => clearInterval(timer);
}, [once]);
useEffect(() => {
if (once && !loading && (prayerTimes || error)) {
exit();
}
}, [once, loading, prayerTimes, error, exit]);
if (loading) {
return (_jsx(Box, { padding: 1, children: _jsxs(Text, { color: "yellow", children: ["Loading prayer times for ", resolvedCityName, "..."] }) }));
}
if (error) {
return (_jsx(Box, { padding: 1, children: _jsxs(Text, { color: "red", bold: true, children: ["Error: ", error] }) }));
}
if (!prayerTimes) {
return (_jsx(Box, { padding: 1, children: _jsx(Text, { color: "red", bold: true, children: "Could not fetch prayer times." }) }));
}
const nextPrayerData = getNextPrayer(prayerTimes, currentTime);
const progress = getPrayerProgress(prayerTimes, currentTime, nextPrayerData.prayer);
const ramadanData = getRamadanData(prayerTimes, tomorrowTimes, currentTime);
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, borderStyle: "round", borderColor: "green", width: 60, children: [_jsxs(Box, { flexDirection: "column", alignItems: "center", gap: 1, children: [_jsx(Box, { borderStyle: "single", borderColor: "green", children: _jsxs(Text, { bold: true, color: "green", children: ["\uD83C\uDDF2\uD83C\uDDE6 ", resolvedCityName, ", Morocco \uD83C\uDDF2\uD83C\uDDE6"] }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "white", bold: true, children: ["\uD83D\uDCC5 ", format(currentTime, "EEEE, MMMM do yyyy")] }) }), hijriDate && (_jsxs(Text, { color: "gray", dimColor: true, children: ["\uD83D\uDD4C ", hijriDate] }))] }), _jsx(Box, { flexDirection: "column", alignItems: "center", marginY: 1, padding: 1, borderStyle: "single", borderColor: "yellow", children: _jsx(RamadanInfo, { data: ramadanData }) }), _jsx(Box, { flexDirection: "column", marginY: 1, children: Object.entries({
"Imsak *": getImsakTime(prayerTimes.Fajr),
...prayerTimes,
}).map(([prayer, time]) => {
const isNext = prayer === nextPrayerData.prayer;
const isImsak = prayer === "Imsak *";
return (_jsxs(Box, { justifyContent: "space-between", paddingX: 2, backgroundColor: isNext ? "green" : undefined, children: [_jsx(Box, { children: _jsxs(Text, { color: isNext ? "white" : (isImsak ? "gray" : "white"), bold: isNext, children: [isNext ? "> " : " ", prayer.padEnd(12)] }) }), _jsx(Box, { children: _jsx(Text, { color: isNext ? "white" : (isImsak ? "gray" : "white"), bold: isNext, children: tConv24(time) }) })] }, prayer));
}) }), _jsx(Box, { paddingX: 2, marginTop: 1, children: _jsx(Text, { dimColor: true, color: "gray", italic: true, children: "* Imsak is 10 min before Fajr for safety" }) }), _jsxs(Box, { marginTop: 1, paddingX: 2, paddingY: 1, flexDirection: "column", alignItems: "center", borderStyle: "single", borderColor: "yellow", children: [_jsxs(Text, { children: ["Next: ", _jsx(Text, { color: "green", bold: true, children: nextPrayerData.prayer }), " in ", _jsx(Text, { color: "yellow", bold: true, children: nextPrayerData.timeLeft })] }), _jsxs(Box, { flexDirection: "column", alignItems: "center", marginY: 1, children: [_jsx(ProgressBar, { progress: progress, width: 50 }), _jsxs(Box, { justifyContent: "space-between", width: 50, marginTop: 0, children: [_jsx(Text, { color: "gray", dimColor: true, children: "0%" }), _jsxs(Text, { color: "green", bold: true, children: [Math.round(progress * 100), "%"] }), _jsx(Text, { color: "gray", dimColor: true, children: "100%" })] })] })] }), !once && (_jsx(Box, { marginTop: 1, justifyContent: "center", children: _jsx(Text, { dimColor: true, color: "gray", children: "[C] Change City \u2022 [Ctrl+C] Exit" }) }))] }));
};
export default App;