This commit is contained in:
Sean Edmunds
2025-04-15 20:21:25 -05:00
parent 2e72b76e95
commit 78dec160b6
34 changed files with 225 additions and 466 deletions

View File

@@ -1,7 +1,7 @@
import { Divider, Modal, Stack } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { modalClasses } from 'styles';
import type { Provider } from 'types';
import type { Application, Provider } from 'types';
import HelpSection from './HelpSection';
export function HelpModal({
@@ -12,8 +12,16 @@ export function HelpModal({
closeProviderModal,
applicationData,
providerData,
}: any) {
const { theme, isMobile } = useCommonHooks();
}: {
setSearchValue: (value: string) => void;
setProviderLabel: (label: string) => void;
setProviderURL: (url: string) => void;
providerModalOpened: boolean;
closeProviderModal: () => void;
applicationData: Application[];
providerData: Provider[];
}) {
const { theme, isMobile, modalStyle } = useCommonHooks();
return (
<Modal.Root
size={'60%'}
@@ -28,14 +36,7 @@ export function HelpModal({
setProviderURL('https://www.google.com/search?q=');
closeProviderModal();
}}
style={{
'--color-text-pri': theme.primaryColor,
'--color-text-acc': theme.accentColor,
'--color-background': theme.backgroundColor,
'--color-border': theme.borderColor,
'--color-search-background': theme.searchColor,
'--image-background': `url(${theme.backgroundImage})`,
}}
style={modalStyle}
closeOnEscape
closeOnClickOutside
>
@@ -59,7 +60,7 @@ export function HelpModal({
<Divider my={8} color={theme.accentColor} />
<HelpSection
name={'Available Applications'}
items={applicationData.map((application: any) => {
items={applicationData.map((application: Application) => {
return {
name: application.url,
command: `!${application.baseUrl.substring(1).toLowerCase()}`,

View File

@@ -2,7 +2,7 @@ import { Divider, Group } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import HintItem from './HintItem';
function HelpSection({ name, items }: any) {
function HelpSection({ name, items }: { name: string; items: object[] }) {
const { theme } = useCommonHooks();
return (
<>
@@ -30,7 +30,7 @@ function HelpSection({ name, items }: any) {
}}
>
{items
?.sort((a: any, b: any) => (a.command > b.command ? 1 : -1))
?.toSorted((a: any, b: any) => (a.command > b.command ? 1 : -1))
.map((item: any) => (
<HintItem key={item.command} command={item.command} name={item.name} />
))}

View File

@@ -1,6 +1,6 @@
import { Group, Text } from '@mantine/core';
function HintItem({ command, name }: any) {
function HintItem({ command, name }: { command: string; name: string }) {
return (
<Group
gap={0}

View File

@@ -1,17 +1,12 @@
import { Stack } from '@mantine/core';
import { stackClasses } from 'styles';
function Loading({ loaded }: any) {
export function Loading({ loaded }: any) {
return (
<Stack
align='center'
justify='center'
pos={'fixed'}
className={stackClasses.fadeAway}
classNames={stackClasses}
data-loaded={loaded}
/>
);
}
export default Loading;

View File

@@ -15,53 +15,9 @@ export function ThemeProvider({
'--image-background': `linear-gradient(${theme.backgroundColor}33, ${theme.backgroundColor}33), url(/backgrounds/${theme.backgroundImage})`,
'--toastify-color-light': `hwb(from ${theme.primaryColor} h w b / 0.25)`,
'--toastify-color-dark': `hwb(from ${theme.primaryColor} h w b / 0.25)`,
'--toastify-color-info': '#3498db',
'--toastify-color-success': '#07bc0c',
'--toastify-color-warning': '#f1c40f',
'--toastify-color-error': 'hsl(6, 78%, 57%)',
'--toastify-color-transparent': 'rgba(255, 255, 255, 0.7)',
'--toastify-icon-color-info': 'var(--toastify-color-info)',
'--toastify-icon-color-success': 'var(--toastify-color-success)',
'--toastify-icon-color-warning': 'var(--toastify-color-warning)',
'--toastify-icon-color-error': 'var(--toastify-color-error)',
'--toastify-container-width': 'fit-content',
'--toastify-toast-width': '320px',
'--toastify-toast-offset': '16px',
'--toastify-toast-top':
'max(var(--toastify-toast-offset), env(safe-area-inset-top))',
'--toastify-toast-right':
'max(var(--toastify-toast-offset), env(safe-area-inset-right))',
'--toastify-toast-left':
'max(var(--toastify-toast-offset), env(safe-area-inset-left))',
'--toastify-toast-bottom':
'max(var(--toastify-toast-offset), env(safe-area-inset-bottom))',
'--toastify-toast-background': '#fff',
'--toastify-toast-padding': '14px',
'--toastify-toast-min-height': '64px',
'--toastify-toast-max-height': '800px',
'--toastify-toast-bd-radius': '6px',
'--toastify-toast-shadow': '0px 4px 12px rgba(0, 0, 0, 0.1)',
'--toastify-font-family': 'sans-serif',
'--toastify-z-index': '9999',
'--toastify-text-color-light': theme.primaryColor,
'--toastify-text-color-dark': theme.primaryColor,
/* Used only for colored theme */
'--toastify-text-color-info': '#fff',
'--toastify-text-color-success': '#fff',
'--toastify-text-color-warning': '#fff',
'--toastify-text-color-error': '#fff',
'--toastify-spinner-color': '#616161',
'--toastify-spinner-color-empty-area': '#e0e0e0',
'--toastify-color-progress-light': theme.accentColor,
'--toastify-color-progress-dark': '#bb86fc',
'--toastify-color-progress-info': 'var(--toastify-color-info)',
'--toastify-color-progress-success': 'var(--toastify-color-success)',
'--toastify-color-progress-warning': 'var(--toastify-color-warning)',
'--toastify-color-progress-error': 'var(--toastify-color-error)',
/* used to control the opacity of the progress trail */
'--toastify-color-progress-bgo': 0.2,
}}
>

View File

@@ -4,9 +4,11 @@ import { useSunStateAPI } from 'hooks/useAPI';
import { useEffect, useState } from 'react';
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
import { WiBarometer, WiHumidity, WiSunrise, WiSunset } from 'react-icons/wi';
import { themeIconClasses } from 'styles';
import type { CurrentWeather as CW } from 'types';
import WeatherIcon from './WeatherIcon';
export default function CurrentWeather({ current }: any) {
export default function CurrentWeather({ current }: { current: CW }) {
const { currentLocation, isMobile } = useCommonHooks();
const { data: sunStateData } = useSunStateAPI({
lat: currentLocation.lat,
@@ -34,19 +36,21 @@ export default function CurrentWeather({ current }: any) {
{current ? (
<Stack
gap={0}
w={'100%'}
justify='space-between'
style={{
width: '100%',
backgroundColor: 'var(--color-search-background)',
padding: '1rem',
borderRadius: '8px',
paddingBottom: '.5rem',
}}
c={'var(--color-text-pri)'}
>
<Group gap={0} px={16} w={'100%'} justify='space-between'>
<Group
gap={0}
justify='space-between'
style={{ width: '100%', paddingLeft: 16 }}
>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'right',
@@ -55,7 +59,7 @@ export default function CurrentWeather({ current }: any) {
Current Weather
</Text>
</Group>
<Group gap={8} w={'100%'} justify='space-between'>
<Group gap={8} justify='space-between'>
<Stack gap={0} w={isMobile ? '40%' : '45%'}>
<Group gap={0} justify='flex-end'>
<WeatherIcon
@@ -78,7 +82,6 @@ export default function CurrentWeather({ current }: any) {
</Text>
</Group>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'right',
@@ -97,10 +100,8 @@ export default function CurrentWeather({ current }: any) {
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<FaLongArrowAltUp size={32} />
</ThemeIcon>
@@ -117,10 +118,8 @@ export default function CurrentWeather({ current }: any) {
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<FaLongArrowAltDown size={32} />
</ThemeIcon>
@@ -139,10 +138,8 @@ export default function CurrentWeather({ current }: any) {
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<WiSunrise size={32} />
</ThemeIcon>
@@ -157,10 +154,8 @@ export default function CurrentWeather({ current }: any) {
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<WiSunset size={32} />
</ThemeIcon>
@@ -177,10 +172,8 @@ export default function CurrentWeather({ current }: any) {
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<WiHumidity size={32} />
</ThemeIcon>
@@ -205,10 +198,8 @@ export default function CurrentWeather({ current }: any) {
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<FaWind size={32} />
</ThemeIcon>
@@ -233,10 +224,8 @@ export default function CurrentWeather({ current }: any) {
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
className={themeIconClasses.weatherIcon}
classNames={themeIconClasses}
>
<WiBarometer size={32} />
</ThemeIcon>

View File

@@ -19,9 +19,8 @@ export default function ExtendedForecast({ forecast }: any) {
paddingBottom: '.5rem',
}}
>
<Group gap={0} px={16} mb={8} w={'100%'}>
<Group gap={0} style={{ width: '100%', marginBottom: '8px', paddingLeft: '16px' }}>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'left',

View File

@@ -1,5 +1,4 @@
import { Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import {
Area,
CartesianGrid,
@@ -13,8 +12,6 @@ import {
} from 'recharts';
export default function WeatherGraphs({ hourlyForecast }: any) {
const { theme } = useCommonHooks();
function CustomTooltip({ payload, active }: any) {
if (active) {
return (
@@ -50,7 +47,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
<ComposedChart data={hourlyForecast}>
<XAxis
type='category'
stroke={theme.primaryColor}
stroke={'var(--color-text-pri)'}
dataKey={(data: any) => {
return new Date(data.startTime).toLocaleTimeString('en-US', {
hour: 'numeric',
@@ -59,7 +56,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
}}
/>
<YAxis
stroke={theme.primaryColor}
stroke={'var(--color-text-pri)'}
unit={'°F'}
domain={['dataMin', 'dataMax']}
/>
@@ -70,8 +67,8 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
type='monotone'
name='Temperature'
dataKey='temperature'
stroke={theme.primaryColor}
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
stroke={'var(--color-text-pri)'}
dot={{ stroke: 'var(--color-text-pri)', strokeWidth: 1 }}
/>
<Line
unit={'°F'}
@@ -80,8 +77,8 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
dataKey={(data: any) => {
return (data.dewpoint.value * 9) / 5 + 32;
}}
stroke={theme.accentColor}
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
stroke={'var(--color-text-acc)'}
dot={{ stroke: 'var(--color-text-pri)', strokeWidth: 1 }}
/>
<Legend style={{ background: 'var(--color-search-background)' }} />
</ComposedChart>
@@ -90,7 +87,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
<ComposedChart data={hourlyForecast}>
<XAxis
type='category'
stroke={theme.primaryColor}
stroke={'var(--color-text-pri)'}
dataKey={(data: any) => {
return new Date(data.startTime).toLocaleTimeString('en-US', {
hour: 'numeric',
@@ -98,7 +95,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
});
}}
/>
<YAxis stroke={theme.primaryColor} unit={'%'} domain={[0, 100]} />
<YAxis stroke={'var(--color-text-pri)'} unit={'%'} domain={[0, 100]} />
<CartesianGrid stroke='#f5f5f522' />
<Tooltip content={<CustomTooltip />} />
<Area
@@ -108,9 +105,9 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
dataKey={(data: any) => {
return data.probabilityOfPrecipitation.value;
}}
stroke={theme.primaryColor}
fill={theme.primaryColor}
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
stroke={'var(--color-text-pri)'}
fill={'var(--color-text-pri)'}
dot={{ stroke: 'var(--color-text-pri)', strokeWidth: 1 }}
/>
<Area
unit={'%'}
@@ -119,9 +116,9 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
dataKey={(data: any) => {
return data.relativeHumidity.value;
}}
stroke={theme.accentColor}
fill={theme.accentColor}
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
stroke={'var(--color-text-acc)'}
fill={'var(--color-text-acc)'}
dot={{ stroke: 'var(--color-text-pri)', strokeWidth: 1 }}
/>
<Legend style={{ background: 'var(--color-search-background)' }} />
</ComposedChart>

View File

@@ -4,20 +4,29 @@ import { modalClasses } from 'styles';
import { useCommonHooks, useWeatherAPI } from 'hooks';
import { useEffect, useState } from 'react';
import type { CurrentWeather as CW, ExtendedForecast as EF } from 'types';
import CurrentWeather from './CurrentWeather';
import ExtendedForecast from './ExtendedForecast';
import WeatherGraphs from './WeatherGraphs';
export function WeatherModal({
current,
extendedForecast,
weatherModalOpened,
setSearchValue,
setProviderLabel,
setProviderURL,
current,
extendedForecast,
closeWeatherModal,
weatherModalOpened,
}: any) {
const { theme, isMobile, currentUser, currentLocation } = useCommonHooks();
}: {
current: CW;
extendedForecast: EF[];
weatherModalOpened: boolean;
setSearchValue: (value: string) => void;
setProviderLabel: (label: string) => void;
setProviderURL: (url: string) => void;
closeWeatherModal: () => void;
}) {
const { isMobile, currentUser, currentLocation, modalStyle } = useCommonHooks();
const { data: hourly } = useWeatherAPI({
endpoint: 'hourly',
office: currentLocation.office,
@@ -46,14 +55,7 @@ export function WeatherModal({
setProviderURL('https://www.google.com/search?q=');
closeWeatherModal();
}}
style={{
'--color-text-pri': theme.primaryColor,
'--color-text-acc': theme.accentColor,
'--color-background': theme.backgroundColor,
'--color-border': theme.borderColor,
'--color-search-background': theme.searchColor,
'--image-background': `url(${theme.backgroundImage})`,
}}
style={modalStyle}
closeOnEscape
closeOnClickOutside
>
@@ -61,7 +63,7 @@ export function WeatherModal({
<Modal.Content>
<Modal.Header>
<Modal.Title>
<Group gap={8} style={{ borderBottom: `1px solid ${theme.borderColor}` }}>
<Group gap={8} style={{ borderBottom: '1px solid var(--color-border)' }}>
<Text fz={18} fw={200}>
Weather Forecast for{' '}
</Text>

View File

@@ -2,3 +2,4 @@ export { HelpModal } from './HelpModal/HelpModal';
export { WeatherModal } from './WeatherModal/WeatherModal';
export { ThemeProvider } from './ThemeProvider';
export { MainLayout } from './MainLayout';
export { Loading } from './Loading';