homepage/src/pages/index.jsx

179 lines
5.6 KiB
React
Raw Normal View History

/* eslint-disable react/no-array-index-key */
2022-08-24 10:44:35 +03:00
import useSWR from "swr";
import Head from "next/head";
import dynamic from "next/dynamic";
import { useTranslation } from "react-i18next";
import { useEffect, useContext } from "react";
2022-09-18 16:41:01 +03:00
import { BiError } from "react-icons/bi";
2022-08-24 10:44:35 +03:00
import ServicesGroup from "components/services/group";
import BookmarksGroup from "components/bookmarks/group";
import Widget from "components/widget";
2022-09-09 06:45:43 +03:00
import Revalidate from "components/revalidate";
import createLogger from "utils/logger";
2022-09-09 06:45:43 +03:00
import { getSettings } from "utils/config";
import { ColorContext } from "utils/color-context";
import { ThemeContext } from "utils/theme-context";
import { SettingsContext } from "utils/settings-context";
2022-08-24 10:44:35 +03:00
const ThemeToggle = dynamic(() => import("components/theme-toggle"), {
ssr: false,
});
2022-08-25 11:14:17 +03:00
const ColorToggle = dynamic(() => import("components/color-toggle"), {
ssr: false,
});
2022-09-24 01:18:37 +03:00
const Version = dynamic(() => import("components/version"), {
ssr: false,
});
2022-09-16 10:53:12 +03:00
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"];
2022-09-18 16:41:01 +03:00
export function getStaticProps() {
let logger;
2022-09-18 16:41:01 +03:00
try {
2022-09-24 01:18:37 +03:00
logger = createLogger("index");
const { providers, ...settings } = getSettings();
2022-09-18 16:41:01 +03:00
return {
props: {
initialSettings: settings,
2022-09-18 16:41:01 +03:00
},
};
} catch (e) {
2022-09-24 01:18:37 +03:00
if (logger) {
logger.error(e);
}
2022-09-18 16:41:01 +03:00
return {
props: {
initialSettings: {},
2022-09-18 16:41:01 +03:00
},
};
}
}
export default function Index({ initialSettings }) {
2022-09-18 16:41:01 +03:00
const { data: errorsData } = useSWR("/api/validate");
if (errorsData && errorsData.length > 0) {
return (
<div className="w-full container m-auto justify-center p-10">
<div className="flex flex-col">
{errorsData.map((error, i) => (
<div
className="basis-1/2 bg-theme-500 dark:bg-theme-600 text-theme-600 dark:text-theme-300 m-2 rounded-md font-mono shadow-md border-4 border-transparent"
key={i}
>
<div className="bg-amber-200 text-amber-800 dark:text-amber-200 dark:bg-amber-800 p-2 rounded-md font-bold">
<BiError className="float-right w-6 h-6" />
{error.config}
</div>
<div className="p-2 text-theme-100 dark:text-theme-200">
<pre className="opacity-50 font-bold pb-2">{error.reason}</pre>
<pre className="text-sm">{error.mark.snippet}</pre>
</div>
</div>
))}
</div>
</div>
);
}
2022-09-09 06:45:43 +03:00
return <Home initialSettings={initialSettings} />;
2022-09-09 06:45:43 +03:00
}
function Home({ initialSettings }) {
const { i18n } = useTranslation();
const { theme, setTheme } = useContext(ThemeContext);
const { color, setColor } = useContext(ColorContext);
const { settings, setSettings } = useContext(SettingsContext);
2022-09-21 17:39:46 +03:00
useEffect(() => {
setSettings(initialSettings);
2022-09-21 17:39:46 +03:00
}, [initialSettings, setSettings]);
2022-09-07 16:53:24 +03:00
const { data: services } = useSWR("/api/services");
const { data: bookmarks } = useSWR("/api/bookmarks");
const { data: widgets } = useSWR("/api/widgets");
2022-08-24 10:44:35 +03:00
2022-09-09 06:45:43 +03:00
const wrappedStyle = {};
if (settings && settings.background) {
2022-09-09 06:45:43 +03:00
wrappedStyle.backgroundImage = `url(${settings.background})`;
wrappedStyle.backgroundSize = "cover";
2022-09-16 15:31:13 +03:00
wrappedStyle.opacity = settings.backgroundOpacity ?? 1;
2022-09-09 06:45:43 +03:00
}
useEffect(() => {
if (settings.language) {
i18n.changeLanguage(settings.language);
}
if (settings.theme && theme !== settings.theme) {
setTheme(settings.theme);
}
if (settings.color && color !== settings.color) {
setColor(settings.color);
}
}, [i18n, settings, color, setColor, theme, setTheme]);
2022-08-24 10:44:35 +03:00
return (
<>
<Head>
<title>{settings.title || "Homepage"}</title>
{settings.base && <base href={settings.base} />}
{settings.favicon && <link rel="icon" href={settings.favicon} />}
</Head>
<div className="fixed w-full h-full m-0 p-0" style={wrappedStyle} />
<div className="relative w-full container m-auto flex flex-col h-screen justify-between">
<div className="flex flex-row flex-wrap m-8 pb-4 mt-10 border-b-2 border-theme-800 dark:border-theme-200 justify-between">
{widgets && (
<>
{widgets
.filter((widget) => !rightAlignedWidgets.includes(widget.type))
.map((widget, i) => (
<Widget key={i} widget={widget} />
))}
<div className="ml-4 flex flex-wrap basis-full grow sm:basis-auto justify-between md:justify-end mt-2 md:mt-0">
2022-08-27 00:55:13 +03:00
{widgets
.filter((widget) => rightAlignedWidgets.includes(widget.type))
.map((widget, i) => (
<Widget key={i} widget={widget} />
2022-08-27 00:55:13 +03:00
))}
</div>
</>
2022-08-24 10:44:35 +03:00
)}
</div>
2022-08-24 10:44:35 +03:00
{services && (
<div className="flex flex-wrap p-8 items-start">
{services.map((group) => (
<ServicesGroup key={group.name} services={group} layout={settings.layout?.[group.name]} />
))}
</div>
)}
2022-08-24 10:44:35 +03:00
{bookmarks && (
<div className="grow flex flex-wrap pt-0 p-8">
{bookmarks.map((group) => (
<BookmarksGroup key={group.name} group={group} />
))}
2022-08-24 10:44:35 +03:00
</div>
)}
2022-09-24 01:18:37 +03:00
<div className="flex p-8 pb-0 w-full justify-end">
{!settings?.color && <ColorToggle />}
<Revalidate />
{!settings?.theme && <ThemeToggle />}
2022-08-24 10:44:35 +03:00
</div>
2022-09-24 01:18:37 +03:00
<div className="flex p-8 pt-4 w-full justify-end">
<Version />
</div>
</div>
</>
2022-08-24 10:44:35 +03:00
);
}