Refactoring theme files
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -18,8 +18,8 @@
|
|||||||
"@tanstack/react-query-persist-client": "^5.83.0",
|
"@tanstack/react-query-persist-client": "^5.83.0",
|
||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"jotai": "^2.12.5",
|
"jotai": "^2.12.5",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.1",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^7.7.1",
|
"react-router-dom": "^7.7.1",
|
||||||
"recharts": "^3.1.0"
|
"recharts": "^3.1.0"
|
||||||
@@ -3562,24 +3562,24 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"version": "19.1.0",
|
"version": "19.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
|
||||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "19.1.0",
|
"version": "19.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
|
||||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
"integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.26.0"
|
"scheduler": "^0.26.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^19.1.0"
|
"react": "^19.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-icons": {
|
"node_modules/react-icons": {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
"@tanstack/react-query-persist-client": "^5.83.0",
|
"@tanstack/react-query-persist-client": "^5.83.0",
|
||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"jotai": "^2.12.5",
|
"jotai": "^2.12.5",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.1",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^7.7.1",
|
"react-router-dom": "^7.7.1",
|
||||||
"recharts": "^3.1.0"
|
"recharts": "^3.1.0"
|
||||||
|
|||||||
@@ -19,6 +19,25 @@ import Search from './components/Search/Search';
|
|||||||
import SettingsButton from './components/SettingsButton/SettingsButton';
|
import SettingsButton from './components/SettingsButton/SettingsButton';
|
||||||
|
|
||||||
export function Homepage() {
|
export function Homepage() {
|
||||||
|
const {
|
||||||
|
appFilter,
|
||||||
|
bookmarkFilter,
|
||||||
|
isMobile,
|
||||||
|
setCurrentUser,
|
||||||
|
currentLocation,
|
||||||
|
setCurrentLocation,
|
||||||
|
} = useCommonHooks();
|
||||||
|
const dateOptions: Intl.DateTimeFormatOptions = !isMobile
|
||||||
|
? {
|
||||||
|
weekday: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
|
||||||
|
const date = new Date().toLocaleDateString('en-US', dateOptions);
|
||||||
|
|
||||||
const { data: personalData, isFetched: personalIsFetched } = useQueryAPI({
|
const { data: personalData, isFetched: personalIsFetched } = useQueryAPI({
|
||||||
endpoint: 'api/personalData',
|
endpoint: 'api/personalData',
|
||||||
});
|
});
|
||||||
@@ -29,58 +48,6 @@ export function Homepage() {
|
|||||||
} = useQueryAPI({
|
} = useQueryAPI({
|
||||||
endpoint: 'api/displayedGreeting',
|
endpoint: 'api/displayedGreeting',
|
||||||
});
|
});
|
||||||
const {
|
|
||||||
appFilter,
|
|
||||||
bookmarkFilter,
|
|
||||||
isMobile,
|
|
||||||
setCurrentUser,
|
|
||||||
currentLocation,
|
|
||||||
setCurrentLocation,
|
|
||||||
} = useCommonHooks();
|
|
||||||
const [personal, setPersonal] = useState<PersonalData>();
|
|
||||||
const [message, setMessage] = useState<Message>();
|
|
||||||
const [displayedGreeting, setDisplayedGreeting] = useState<string | undefined>('');
|
|
||||||
const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] =
|
|
||||||
useDisclosure(false);
|
|
||||||
const dateOptions: Intl.DateTimeFormatOptions = !isMobile
|
|
||||||
? {
|
|
||||||
weekday: 'long',
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric',
|
|
||||||
}
|
|
||||||
: {};
|
|
||||||
const date = new Date().toLocaleDateString('en-US', dateOptions);
|
|
||||||
useEffect(() => {
|
|
||||||
if (messageData && isMessagesFetched) {
|
|
||||||
setMessage(messageData[0]);
|
|
||||||
}
|
|
||||||
}, [messageData, isMessagesFetched]);
|
|
||||||
useEffect(() => {
|
|
||||||
if (personalData && personalIsFetched) {
|
|
||||||
setCurrentUser(personalData[0]);
|
|
||||||
setPersonal(personalData[0]);
|
|
||||||
}
|
|
||||||
}, [personalData, personalIsFetched]);
|
|
||||||
useEffect(() => {
|
|
||||||
if (personal) {
|
|
||||||
setDisplayedGreeting(() => {
|
|
||||||
if (Math.floor(Math.random() * 100) > 10 || message === undefined) {
|
|
||||||
switch (Math.floor(new Date().getHours() / 6)) {
|
|
||||||
case 0:
|
|
||||||
return `Good night, ${personal?.firstName}!`;
|
|
||||||
case 1:
|
|
||||||
return `Good morning, ${personal?.firstName}!`;
|
|
||||||
case 2:
|
|
||||||
return `Good afternoon, ${personal?.firstName}!`;
|
|
||||||
case 3:
|
|
||||||
return `Good evening, ${personal?.firstName}!`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return message?.message;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [message, personal, isMessagesFetching]);
|
|
||||||
const { data: weatherMetadata } = useOSMAPI({
|
const { data: weatherMetadata } = useOSMAPI({
|
||||||
address: personalData?.[0]?.physicalAddress,
|
address: personalData?.[0]?.physicalAddress,
|
||||||
});
|
});
|
||||||
@@ -112,6 +79,10 @@ export function Homepage() {
|
|||||||
x: points?.properties.gridX ?? currentLocation.x,
|
x: points?.properties.gridX ?? currentLocation.x,
|
||||||
y: points?.properties.gridY ?? currentLocation.y,
|
y: points?.properties.gridY ?? currentLocation.y,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [personal, setPersonal] = useState<PersonalData>();
|
||||||
|
const [message, setMessage] = useState<Message>();
|
||||||
|
const [displayedGreeting, setDisplayedGreeting] = useState<string | undefined>('');
|
||||||
const [current, setCurrent] = useState<CW>({
|
const [current, setCurrent] = useState<CW>({
|
||||||
icon: '',
|
icon: '',
|
||||||
textDescription: '',
|
textDescription: '',
|
||||||
@@ -126,7 +97,6 @@ export function Homepage() {
|
|||||||
windDirection: 0,
|
windDirection: 0,
|
||||||
pressure: 0,
|
pressure: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [extendedForecast, setExtendedForecast] = useState<EF[]>([
|
const [extendedForecast, setExtendedForecast] = useState<EF[]>([
|
||||||
{
|
{
|
||||||
detailedForecast: '',
|
detailedForecast: '',
|
||||||
@@ -137,6 +107,39 @@ export function Homepage() {
|
|||||||
temperatureUnit: 'F',
|
temperatureUnit: 'F',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] =
|
||||||
|
useDisclosure(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (messageData && isMessagesFetched) {
|
||||||
|
setMessage(messageData[0]);
|
||||||
|
}
|
||||||
|
}, [messageData, isMessagesFetched]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (personalData && personalIsFetched) {
|
||||||
|
setCurrentUser(personalData[0]);
|
||||||
|
setPersonal(personalData[0]);
|
||||||
|
}
|
||||||
|
}, [personalData, personalIsFetched]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (personal) {
|
||||||
|
setDisplayedGreeting(() => {
|
||||||
|
if (Math.floor(Math.random() * 100) > 10 || message === undefined) {
|
||||||
|
switch (Math.floor(new Date().getHours() / 6)) {
|
||||||
|
case 0:
|
||||||
|
return `Good night, ${personal?.firstName}!`;
|
||||||
|
case 1:
|
||||||
|
return `Good morning, ${personal?.firstName}!`;
|
||||||
|
case 2:
|
||||||
|
return `Good afternoon, ${personal?.firstName}!`;
|
||||||
|
case 3:
|
||||||
|
return `Good evening, ${personal?.firstName}!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message?.message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [message, personal, isMessagesFetching]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (weather !== undefined && basicWeather !== undefined) {
|
if (weather !== undefined && basicWeather !== undefined) {
|
||||||
setCurrent({
|
setCurrent({
|
||||||
@@ -221,9 +224,6 @@ export function Homepage() {
|
|||||||
greet={displayedGreeting}
|
greet={displayedGreeting}
|
||||||
date={date}
|
date={date}
|
||||||
current={current}
|
current={current}
|
||||||
setCurrent={setCurrent}
|
|
||||||
weather={weather}
|
|
||||||
basicWeather={basicWeather}
|
|
||||||
openWeatherModal={openWeatherModal}
|
openWeatherModal={openWeatherModal}
|
||||||
/>
|
/>
|
||||||
<Applications contentType={appFilter} />
|
<Applications contentType={appFilter} />
|
||||||
@@ -232,13 +232,7 @@ export function Homepage() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Stack align='center'>
|
<Stack align='center'>
|
||||||
<LargeHeader
|
<LargeHeader greet={displayedGreeting} date={date} />
|
||||||
greet={displayedGreeting}
|
|
||||||
date={date}
|
|
||||||
weather={weather}
|
|
||||||
basicWeather={basicWeather}
|
|
||||||
setCurrent={setCurrent}
|
|
||||||
/>
|
|
||||||
<Grid grow columns={24} pos={'absolute'} bottom={'1rem'} w={'50%'}>
|
<Grid grow columns={24} pos={'absolute'} bottom={'1rem'} w={'50%'}>
|
||||||
<CurrentWeather current={current} />
|
<CurrentWeather current={current} />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ function Applications({ contentType }: { contentType: string[] }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (applicationData && !isApplicationDataFetching) {
|
if (applicationData && !isApplicationDataFetching) {
|
||||||
setApplications(
|
setApplications(
|
||||||
applicationData.sort((a: Application, b: Application) => {
|
applicationData
|
||||||
|
.sort((a: Application, b: Application) => {
|
||||||
switch (appSort) {
|
switch (appSort) {
|
||||||
case 'A>Z':
|
case 'A>Z':
|
||||||
return a.name > b.name ? 1 : -1;
|
return a.name > b.name ? 1 : -1;
|
||||||
@@ -34,10 +35,15 @@ function Applications({ contentType }: { contentType: string[] }) {
|
|||||||
case 'Custom':
|
case 'Custom':
|
||||||
return a.index > b.index ? 1 : -1;
|
return a.index > b.index ? 1 : -1;
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
?.filter(
|
||||||
|
(application: Application) =>
|
||||||
|
contentType.includes(application.filterName) || contentType.includes('All'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [applicationData, isApplicationDataFetching, appSort]);
|
}, [applicationData, isApplicationDataFetching, appSort, contentType]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{applications.length > 0 && contentType.length > 0 && (
|
{applications.length > 0 && contentType.length > 0 && (
|
||||||
@@ -60,13 +66,7 @@ function Applications({ contentType }: { contentType: string[] }) {
|
|||||||
gridTemplateColumns: `repeat(${appDensity}, 1fr)`,
|
gridTemplateColumns: `repeat(${appDensity}, 1fr)`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{applications
|
{applications.map((application: Application) => {
|
||||||
?.filter(
|
|
||||||
(application: Application) =>
|
|
||||||
contentType.includes(application.filterName) ||
|
|
||||||
contentType.includes('All'),
|
|
||||||
)
|
|
||||||
.map((application: Application) => {
|
|
||||||
return (
|
return (
|
||||||
<AppItem
|
<AppItem
|
||||||
key={application.name}
|
key={application.name}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ function Bookmarks({ contentType }: { contentType: string[] }) {
|
|||||||
return category;
|
return category;
|
||||||
});
|
});
|
||||||
setGroups(
|
setGroups(
|
||||||
groupList.sort((a: BookmarkGroup, b: BookmarkGroup) => {
|
groupList
|
||||||
|
.sort((a: BookmarkGroup, b: BookmarkGroup) => {
|
||||||
switch (bookmarkSort) {
|
switch (bookmarkSort) {
|
||||||
case 'A>Z':
|
case 'A>Z':
|
||||||
return a.categoryName > b.categoryName ? 1 : -1;
|
return a.categoryName > b.categoryName ? 1 : -1;
|
||||||
@@ -47,10 +48,14 @@ function Bookmarks({ contentType }: { contentType: string[] }) {
|
|||||||
case 'Custom':
|
case 'Custom':
|
||||||
return a.categoryIndex > b.categoryIndex ? 1 : -1;
|
return a.categoryIndex > b.categoryIndex ? 1 : -1;
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
?.filter(
|
||||||
|
(category: BookmarkGroup) =>
|
||||||
|
contentType.includes(category.filterName) || contentType.includes('All'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [groupData, groupsIsFetched, bookmarkSort]);
|
}, [groupData, groupsIsFetched, bookmarkSort, contentType]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -79,21 +84,13 @@ function Bookmarks({ contentType }: { contentType: string[] }) {
|
|||||||
gridTemplateColumns: `repeat(${bookmarkDensity}, 1fr)`,
|
gridTemplateColumns: `repeat(${bookmarkDensity}, 1fr)`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{groups
|
{groups.map((category: BookmarkGroup) => {
|
||||||
?.filter(
|
|
||||||
(category: BookmarkGroup) =>
|
|
||||||
contentType.includes(category.filterName) ||
|
|
||||||
contentType.includes('All'),
|
|
||||||
)
|
|
||||||
|
|
||||||
.map((category: BookmarkGroup) => {
|
|
||||||
return (
|
return (
|
||||||
<BookmarkGroups
|
<BookmarkGroups
|
||||||
key={category.categoryName}
|
key={category.categoryName}
|
||||||
category={category.categoryName}
|
category={category.categoryName}
|
||||||
bookmarks={bookmarks.filter(
|
bookmarks={bookmarks.filter(
|
||||||
(bookmark: Bookmark) =>
|
(bookmark: Bookmark) => bookmark.category === category.categoryName,
|
||||||
bookmark.category === category.categoryName,
|
|
||||||
)}
|
)}
|
||||||
bookmarkScale={bookmarkScale}
|
bookmarkScale={bookmarkScale}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -8,17 +8,11 @@ function Header({
|
|||||||
greet,
|
greet,
|
||||||
date,
|
date,
|
||||||
current,
|
current,
|
||||||
setCurrent,
|
|
||||||
weather,
|
|
||||||
basicWeather,
|
|
||||||
openWeatherModal,
|
openWeatherModal,
|
||||||
}: {
|
}: {
|
||||||
greet: string | undefined;
|
greet: string | undefined;
|
||||||
date: string;
|
date: string;
|
||||||
current: CurrentWeather;
|
current: CurrentWeather;
|
||||||
setCurrent: (current: CurrentWeather) => void;
|
|
||||||
weather: any;
|
|
||||||
basicWeather: any;
|
|
||||||
openWeatherModal: () => void;
|
openWeatherModal: () => void;
|
||||||
}) {
|
}) {
|
||||||
const [time, setTime] = useState(new Date());
|
const [time, setTime] = useState(new Date());
|
||||||
@@ -30,43 +24,6 @@ function Header({
|
|||||||
setTime(newDate);
|
setTime(newDate);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
|
||||||
if (weather !== undefined && basicWeather !== undefined) {
|
|
||||||
setCurrent({
|
|
||||||
icon: weather.features[0]?.properties.icon?.replace('medium', 'large') ?? '',
|
|
||||||
textDescription: weather.features[0]?.properties.textDescription,
|
|
||||||
temperature: Math.round(
|
|
||||||
(weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
highTemp: Math.round(
|
|
||||||
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
lowTemp: Math.round(
|
|
||||||
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
precipitation:
|
|
||||||
weather.features[0]?.properties.precipitationLastHour.value ?? 'N/A',
|
|
||||||
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
|
|
||||||
heatIndex:
|
|
||||||
basicWeather.properties.heatIndex?.values[0].value === null
|
|
||||||
? null
|
|
||||||
: Math.round(
|
|
||||||
(basicWeather.properties.heatIndex.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
windChill:
|
|
||||||
basicWeather.properties.windChill?.values[0].value === null
|
|
||||||
? null
|
|
||||||
: Math.round(
|
|
||||||
(basicWeather.properties.windChill.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934),
|
|
||||||
windDirection: weather.features[0]?.properties.windDirection.value,
|
|
||||||
pressure: Math.round(
|
|
||||||
weather.features[0]?.properties.barometricPressure.value / 3386.38,
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [weather, basicWeather]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
|
|||||||
@@ -2,21 +2,8 @@ import { Stack, Text } from '@mantine/core';
|
|||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { CurrentWeather as CW } from 'types';
|
|
||||||
|
|
||||||
function LargeHeader({
|
function LargeHeader({ greet, date }: { greet: string | undefined; date: string }) {
|
||||||
greet,
|
|
||||||
date,
|
|
||||||
setCurrent,
|
|
||||||
weather,
|
|
||||||
basicWeather,
|
|
||||||
}: {
|
|
||||||
greet: string | undefined;
|
|
||||||
date: string;
|
|
||||||
weather: any;
|
|
||||||
basicWeather: any;
|
|
||||||
setCurrent: (current: CW) => void;
|
|
||||||
}) {
|
|
||||||
const [time, setTime] = useState(new Date());
|
const [time, setTime] = useState(new Date());
|
||||||
const { isMobile, currentUser, fixDigits, theme } = useCommonHooks();
|
const { isMobile, currentUser, fixDigits, theme } = useCommonHooks();
|
||||||
|
|
||||||
@@ -27,44 +14,6 @@ function LargeHeader({
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (weather !== undefined && basicWeather !== undefined) {
|
|
||||||
setCurrent({
|
|
||||||
icon: weather.features[0]?.properties.icon?.replace('medium', 'large') ?? '',
|
|
||||||
textDescription: weather.features[0]?.properties.textDescription,
|
|
||||||
temperature: Math.round(
|
|
||||||
(weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
highTemp: Math.round(
|
|
||||||
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
lowTemp: Math.round(
|
|
||||||
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
precipitation:
|
|
||||||
weather.features[0]?.properties.precipitationLastHour.value ?? 'N/A',
|
|
||||||
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
|
|
||||||
heatIndex:
|
|
||||||
basicWeather.properties.heatIndex?.values[0].value === null
|
|
||||||
? null
|
|
||||||
: Math.round(
|
|
||||||
(basicWeather.properties.heatIndex.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
windChill:
|
|
||||||
basicWeather.properties.windChill?.values[0].value === null
|
|
||||||
? null
|
|
||||||
: Math.round(
|
|
||||||
(basicWeather.properties.windChill.values[0].value * 9) / 5 + 32,
|
|
||||||
),
|
|
||||||
windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934),
|
|
||||||
windDirection: weather.features[0]?.properties.windDirection.value,
|
|
||||||
pressure: Math.round(
|
|
||||||
weather.features[0]?.properties.barometricPressure.value / 3386.38,
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [weather, basicWeather]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap={0} pos={'absolute'} align='center' justify='center' top={0}>
|
<Stack gap={0} pos={'absolute'} align='center' justify='center' top={0}>
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ import {
|
|||||||
scrollAreaClasses,
|
scrollAreaClasses,
|
||||||
textInputClasses,
|
textInputClasses,
|
||||||
} from 'styles';
|
} from 'styles';
|
||||||
import { AddBackground } from './AddBackground';
|
import { AddBackground } from './components/AddBackground';
|
||||||
import { BackgroundLightbox } from './BackgroundLightbox';
|
import { BackgroundLightbox } from './components/BackgroundLightbox';
|
||||||
import { DeleteBackground } from './DeleteBackground';
|
import { DeleteBackground } from './components/DeleteBackground';
|
||||||
import { EditBackground } from './EditBackground';
|
import { EditBackground } from './components/EditBackground';
|
||||||
|
|
||||||
export function BackgroundModal({
|
export function BackgroundModal({
|
||||||
backgroundModalOpened,
|
backgroundModalOpened,
|
||||||
|
|||||||
@@ -1,5 +1 @@
|
|||||||
export { AddBackground } from './AddBackground';
|
|
||||||
export { BackgroundLightbox } from './BackgroundLightbox';
|
|
||||||
export { BackgroundModal } from './BackgroundModal';
|
export { BackgroundModal } from './BackgroundModal';
|
||||||
export { DeleteBackground } from './DeleteBackground';
|
|
||||||
export { EditBackground } from './EditBackground';
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { useEffect, useState } from 'react';
|
|||||||
import { FiChevronRight } from 'react-icons/fi';
|
import { FiChevronRight } from 'react-icons/fi';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { ThemePlaylistCard } from './ThemePlaylistCard';
|
import { ThemePlaylistCard } from './components/ThemePlaylistCard';
|
||||||
import { ThemePlaylistModal } from './ThemePlaylistModal';
|
import { ThemePlaylistModal } from './components/ThemePlaylistModal';
|
||||||
|
|
||||||
export function ThemePlaylists() {
|
export function ThemePlaylists() {
|
||||||
const themesEndpoint = 'api/themes';
|
const themesEndpoint = 'api/themes';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { useState } from 'react';
|
|||||||
import { FiEdit, FiTrash } from 'react-icons/fi';
|
import { FiEdit, FiTrash } from 'react-icons/fi';
|
||||||
import { scrollAreaClasses } from 'styles';
|
import { scrollAreaClasses } from 'styles';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { ThemeMiniCard } from '../Themes';
|
import { ThemeMiniCard } from '../../Themes';
|
||||||
|
|
||||||
export function ThemePlaylistCard({
|
export function ThemePlaylistCard({
|
||||||
cardPlaylist,
|
cardPlaylist,
|
||||||
@@ -3,7 +3,8 @@ import { useCommonHooks } from 'hooks';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { modalClasses, textInputClasses } from 'styles';
|
import { modalClasses, textInputClasses } from 'styles';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { ThemePreviewMiddleware, TimeOfDay } from '../Themes';
|
import { ThemePreviewMiddleware } from '../../Themes';
|
||||||
|
import { TimeOfDay } from './TimeOfDay';
|
||||||
|
|
||||||
export function ThemePlaylistModal({
|
export function ThemePlaylistModal({
|
||||||
opened,
|
opened,
|
||||||
@@ -1,3 +1 @@
|
|||||||
export { ThemePlaylistCard } from './ThemePlaylistCard';
|
|
||||||
export { ThemePlaylistModal } from './ThemePlaylistModal';
|
|
||||||
export { ThemePlaylists } from './ThemePlaylists';
|
export { ThemePlaylists } from './ThemePlaylists';
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import {
|
|||||||
import { DeleteItemModal } from 'components';
|
import { DeleteItemModal } from 'components';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { MiniAppItem, MiniGroupItem, ThemeManagementPill } from '.';
|
import { MiniAppItem } from './components/MiniAppItem';
|
||||||
|
import { MiniGroupItem } from './components/MiniGroupItem';
|
||||||
|
import { ThemeManagementPill } from './components/ThemeManagementPill';
|
||||||
|
|
||||||
export function ThemeCard({
|
export function ThemeCard({
|
||||||
cardTheme,
|
cardTheme,
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { ThemeCard } from './ThemeCard';
|
||||||
@@ -4,8 +4,8 @@ import { useCommonHooks, useMutationAPI } from 'hooks';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { modalClasses, textInputClasses } from 'styles';
|
import { modalClasses, textInputClasses } from 'styles';
|
||||||
import type { Theme } from 'types';
|
import type { Theme } from 'types';
|
||||||
import { NewThemeStarter } from './NewThemeStarter';
|
import { NewThemeStarter } from './components/NewThemeStarter';
|
||||||
import { ThemeEditor } from './ThemeEditor';
|
import { ThemeEditor } from './components/ThemeEditor';
|
||||||
|
|
||||||
export function ThemeModal({
|
export function ThemeModal({
|
||||||
opened,
|
opened,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { useState } from 'react';
|
|||||||
import { FaArrowRight } from 'react-icons/fa';
|
import { FaArrowRight } from 'react-icons/fa';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { Theme } from 'types';
|
import type { Theme } from 'types';
|
||||||
import { ThemeCard } from '../ThemeCard';
|
import { ThemeCard } from '../../ThemeCard';
|
||||||
import { ThemeMiniCard } from '../ThemeMiniCard';
|
import { ThemeMiniCard } from '../../ThemeMiniCard';
|
||||||
import { ThemePreviewMiddleware } from '../ThemePreviewMiddleware';
|
import { ThemePreviewMiddleware } from '../../ThemePreviewMiddleware';
|
||||||
|
|
||||||
export function NewThemeStarter({
|
export function NewThemeStarter({
|
||||||
allThemes,
|
allThemes,
|
||||||
@@ -20,7 +20,7 @@ import { FaShuffle } from 'react-icons/fa6';
|
|||||||
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi';
|
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi';
|
||||||
import { scrollAreaClasses, textClasses, textInputClasses } from 'styles';
|
import { scrollAreaClasses, textClasses, textInputClasses } from 'styles';
|
||||||
import { BackgroundProperties, type Theme } from 'types';
|
import { BackgroundProperties, type Theme } from 'types';
|
||||||
import { ThemeModalContent } from '../ThemeModalContent';
|
import { ThemeModalContent } from './ThemeModalContent';
|
||||||
|
|
||||||
export function ThemeEditor({
|
export function ThemeEditor({
|
||||||
backgroundList,
|
backgroundList,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Select, Stack, Text } from '@mantine/core';
|
import { Group, Select, Stack, Text } from '@mantine/core';
|
||||||
|
import { AppItem } from 'components';
|
||||||
import { selectClasses } from 'styles';
|
import { selectClasses } from 'styles';
|
||||||
import type { Theme } from 'types';
|
import type { Theme } from 'types';
|
||||||
import { ThemeExampleApp } from './ThemeExampleApp';
|
|
||||||
|
|
||||||
export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
||||||
return (
|
return (
|
||||||
@@ -73,7 +73,7 @@ export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
|||||||
gap: '.25rem',
|
gap: '.25rem',
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
borderBottom: '0px solid',
|
borderBottom: '0px solid',
|
||||||
display: 'grid',
|
display: 'flex',
|
||||||
gridColumnGap: '5px',
|
gridColumnGap: '5px',
|
||||||
gridRowGap: '5px',
|
gridRowGap: '5px',
|
||||||
gridTemplateColumns: '1fr 1fr 1fr',
|
gridTemplateColumns: '1fr 1fr 1fr',
|
||||||
@@ -83,10 +83,46 @@ export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignContent: 'center',
|
alignContent: 'center',
|
||||||
}}
|
}}
|
||||||
|
w={'100%'}
|
||||||
>
|
>
|
||||||
<ThemeExampleApp selectedTheme={selectedTheme} />
|
<Group
|
||||||
<ThemeExampleApp selectedTheme={selectedTheme} />
|
style={{
|
||||||
<ThemeExampleApp selectedTheme={selectedTheme} />
|
'--mantine-color-primary-0': selectedTheme?.primaryColor,
|
||||||
|
'--mantine-color-accent-0': selectedTheme?.accentColor,
|
||||||
|
'--mantine-color-background-0': selectedTheme?.backgroundColor,
|
||||||
|
'--mantine-color-border-0': selectedTheme?.borderColor,
|
||||||
|
'--mantine-color-search-0': selectedTheme?.searchColor,
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr 1fr',
|
||||||
|
}}
|
||||||
|
w={'100%'}
|
||||||
|
display={'grid'}
|
||||||
|
>
|
||||||
|
<AppItem
|
||||||
|
url='https://google.com'
|
||||||
|
icon='FaGoogle'
|
||||||
|
name='Google'
|
||||||
|
enabled={1}
|
||||||
|
scale={1}
|
||||||
|
linksActive={false}
|
||||||
|
/>
|
||||||
|
<AppItem
|
||||||
|
url='https://google.com'
|
||||||
|
icon='FaGoogle'
|
||||||
|
name='Google'
|
||||||
|
enabled={1}
|
||||||
|
scale={1}
|
||||||
|
linksActive={false}
|
||||||
|
/>
|
||||||
|
<AppItem
|
||||||
|
url='https://google.com'
|
||||||
|
icon='FaGoogle'
|
||||||
|
name='Google'
|
||||||
|
enabled={1}
|
||||||
|
scale={1}
|
||||||
|
linksActive={false}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack gap={0} w={'100%'}>
|
<Stack gap={0} w={'100%'}>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { ThemeModal } from './ThemeModal';
|
||||||
@@ -2,7 +2,7 @@ import { Group, Overlay, Popover } from '@mantine/core';
|
|||||||
import { useLongPress } from '@mantine/hooks';
|
import { useLongPress } from '@mantine/hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ThemeMiniCard } from './ThemeMiniCard';
|
import { ThemeMiniCard } from './ThemeMiniCard';
|
||||||
import { ThemeModalContent } from './ThemeModalContent';
|
import { ThemeModalContent } from './ThemeModal/components/ThemeModalContent';
|
||||||
|
|
||||||
export function ThemePreviewMiddleware({
|
export function ThemePreviewMiddleware({
|
||||||
newThemeList,
|
newThemeList,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { switchClasses, textClasses } from 'styles';
|
|||||||
import type { Theme, ThemePlaylist } from 'types';
|
import type { Theme, ThemePlaylist } from 'types';
|
||||||
import { BackgroundModal } from '../Backgrounds';
|
import { BackgroundModal } from '../Backgrounds';
|
||||||
import { ThemeCard } from './ThemeCard';
|
import { ThemeCard } from './ThemeCard';
|
||||||
import { ThemeModal } from './ThemeModal/ThemeModal';
|
import { ThemeModal } from './ThemeModal';
|
||||||
|
|
||||||
export function Themes() {
|
export function Themes() {
|
||||||
const backgroundsEndpoint = 'api/backgrounds';
|
const backgroundsEndpoint = 'api/backgrounds';
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
export { MiniAppItem } from './MiniAppItem';
|
|
||||||
export { MiniGroupItem } from './MiniGroupItem';
|
|
||||||
export { ThemeCard } from './ThemeCard';
|
|
||||||
export { ThemeExampleApp } from './ThemeExampleApp';
|
|
||||||
export { ThemeManagementPill } from './ThemeManagementPill';
|
|
||||||
export { ThemeMiniCard } from './ThemeMiniCard';
|
export { ThemeMiniCard } from './ThemeMiniCard';
|
||||||
export { ThemeModal } from './ThemeModal/ThemeModal';
|
|
||||||
export { ThemeModalContent } from './ThemeModalContent';
|
|
||||||
export { ThemePreviewMiddleware } from './ThemePreviewMiddleware';
|
export { ThemePreviewMiddleware } from './ThemePreviewMiddleware';
|
||||||
export { ThemeSelect } from './ThemeSelect';
|
|
||||||
export { Themes } from './Themes';
|
export { Themes } from './Themes';
|
||||||
export { TimeOfDay } from './TimeOfDay';
|
|
||||||
|
|||||||
Reference in New Issue
Block a user