diff --git a/backend/pb_migrations/1705455990_created_wallpapers.js b/backend/pb_migrations/1705455990_created_wallpapers.js
new file mode 100644
index 0000000..c375b70
--- /dev/null
+++ b/backend/pb_migrations/1705455990_created_wallpapers.js
@@ -0,0 +1,43 @@
+///
+migrate((db) => {
+ const collection = new Collection({
+ "id": "ogs3cfy8l3jo32k",
+ "created": "2024-01-17 01:46:30.155Z",
+ "updated": "2024-01-17 01:46:30.155Z",
+ "name": "wallpapers",
+ "type": "base",
+ "system": false,
+ "schema": [
+ {
+ "system": false,
+ "id": "kxurmv6q",
+ "name": "artwork",
+ "type": "relation",
+ "required": false,
+ "presentable": false,
+ "unique": false,
+ "options": {
+ "collectionId": "eo6iaxf4pkeqynf",
+ "cascadeDelete": false,
+ "minSelect": null,
+ "maxSelect": 1,
+ "displayFields": null
+ }
+ }
+ ],
+ "indexes": [],
+ "listRule": null,
+ "viewRule": null,
+ "createRule": null,
+ "updateRule": null,
+ "deleteRule": null,
+ "options": {}
+ });
+
+ return Dao(db).saveCollection(collection);
+}, (db) => {
+ const dao = new Dao(db);
+ const collection = dao.findCollectionByNameOrId("ogs3cfy8l3jo32k");
+
+ return dao.deleteCollection(collection);
+})
diff --git a/backend/pb_migrations/1705456227_updated_wallpapers.js b/backend/pb_migrations/1705456227_updated_wallpapers.js
new file mode 100644
index 0000000..23dc19a
--- /dev/null
+++ b/backend/pb_migrations/1705456227_updated_wallpapers.js
@@ -0,0 +1,18 @@
+///
+migrate((db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("ogs3cfy8l3jo32k")
+
+ collection.listRule = ""
+ collection.viewRule = ""
+
+ return dao.saveCollection(collection)
+}, (db) => {
+ const dao = new Dao(db)
+ const collection = dao.findCollectionByNameOrId("ogs3cfy8l3jo32k")
+
+ collection.listRule = null
+ collection.viewRule = null
+
+ return dao.saveCollection(collection)
+})
diff --git a/package.json b/package.json
index ea149f4..1763608 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
+ "dayjs": "^1.11.10",
"howler": "^2.2.4",
"lucide-react": "^0.306.0",
"pixi.js": "^7.3.3",
diff --git a/src/Router.tsx b/src/Router.tsx
index 559b309..115068f 100644
--- a/src/Router.tsx
+++ b/src/Router.tsx
@@ -4,29 +4,35 @@ import MainLayout from "./components/layouts/MainLayout";
import ErrorBoundaryPage from "./pages/errors/error-boundary/page";
const HomePage = lazy(() => import("./pages/home/page"));
+const PatPatPage = lazy(() => import("./pages/pat-pat/page"));
const MyFurinaPage = lazy(() => import("./pages/my-furina/page"));
const ArtworksPage = lazy(() => import("./pages/artworks/page"));
const router = createBrowserRouter([
{
- Component: MainLayout,
children: [
{ index: true, Component: HomePage },
- { path: "/toodle", Component: MyFurinaPage },
{
- path: "/treasures",
- Component: ArtworksPage,
- },
- {
- path: "/treasures/:id",
- Component: ArtworksPage,
+ Component: MainLayout,
+ children: [
+ { path: "/pat-pat", Component: PatPatPage },
+ { path: "/toodle", Component: MyFurinaPage },
+ {
+ path: "/treasures",
+ Component: ArtworksPage,
+ },
+ {
+ path: "/treasures/:id",
+ Component: ArtworksPage,
+ },
+ ],
+ ErrorBoundary: () => (
+
+
+
+ ),
},
],
- ErrorBoundary: () => (
-
-
-
- ),
},
]);
diff --git a/src/components/containers/AppBar.tsx b/src/components/containers/AppBar.tsx
index e419b92..9568eeb 100644
--- a/src/components/containers/AppBar.tsx
+++ b/src/components/containers/AppBar.tsx
@@ -23,7 +23,8 @@ const AppBar = () => {
-
+
+
@@ -53,7 +54,7 @@ const NavbarItem = ({ path, title, isExact = true }: NavbarItemProps) => {
return (
{
diff --git a/src/components/containers/PageMetadata.tsx b/src/components/containers/PageMetadata.tsx
index 19dc9eb..30597d0 100644
--- a/src/components/containers/PageMetadata.tsx
+++ b/src/components/containers/PageMetadata.tsx
@@ -10,7 +10,11 @@ type PageMetadataProps = {
const PageMetadata = (props: PageMetadataProps) => {
return (
- {[props.title, "Furina.id"].filter((i) => !!i).join(" - ")}
+
+ {props.title
+ ? [props.title, "Furina.id"].join(" - ")
+ : "Welcome to Furina.id"}
+
\ No newline at end of file
diff --git a/src/pages/home/icons/furinamains.webp b/src/pages/home/icons/furinamains.webp
new file mode 100644
index 0000000..055ec14
Binary files /dev/null and b/src/pages/home/icons/furinamains.webp differ
diff --git a/src/pages/home/icons/index.ts b/src/pages/home/icons/index.ts
new file mode 100644
index 0000000..61a3447
--- /dev/null
+++ b/src/pages/home/icons/index.ts
@@ -0,0 +1,13 @@
+import patFurina from "./pat-furina.webp";
+import treasures from "./treasures.webp";
+import facebook from "./facebook.svg";
+import twitter from "./twitter.jpg";
+import furinamains from "./furinamains.webp";
+
+export const icons = {
+ patFurina,
+ treasures,
+ facebook,
+ twitter,
+ furinamains,
+};
diff --git a/src/pages/home/icons/pat-furina.webp b/src/pages/home/icons/pat-furina.webp
new file mode 100644
index 0000000..aad4ec6
Binary files /dev/null and b/src/pages/home/icons/pat-furina.webp differ
diff --git a/src/pages/home/icons/treasures.webp b/src/pages/home/icons/treasures.webp
new file mode 100644
index 0000000..1eff67c
Binary files /dev/null and b/src/pages/home/icons/treasures.webp differ
diff --git a/src/pages/home/icons/twitter.jpg b/src/pages/home/icons/twitter.jpg
new file mode 100644
index 0000000..4ab659e
Binary files /dev/null and b/src/pages/home/icons/twitter.jpg differ
diff --git a/src/pages/home/page.tsx b/src/pages/home/page.tsx
index b54139f..f647f61 100644
--- a/src/pages/home/page.tsx
+++ b/src/pages/home/page.tsx
@@ -1,92 +1,182 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { useEffect, useRef, useState } from "react";
-import styles from "./style.module.css";
-import { cn } from "@/utility/utils";
-import LoadingPage from "../misc/loading-page";
+import titleImg from "@/assets/images/title-img.svg";
import PageMetadata from "@/components/containers/PageMetadata";
-import Modal from "@/components/ui/Modal";
-import useModal from "@/hooks/useModal";
-import Button from "@/components/ui/Button";
+import { cn } from "@/utility/utils";
+import dayjs from "dayjs";
+import { ComponentProps, useEffect, useMemo, useState } from "react";
+import { Link } from "react-router-dom";
+import { icons } from "./icons";
+import { useQuery } from "react-query";
+import pb from "@/utility/api";
const HomePage = () => {
- const appRef = useRef();
- const cleanRef = useRef();
- const targetRef = useRef(null);
- const [isReady, setReady] = useState(false);
-
- useEffect(() => {
- if (!appRef.current) {
- appRef.current = true;
-
- const init = async () => {
- const { default: game } = await import("./game");
- const { app, clean } = await game();
- targetRef.current?.appendChild(app.view as never);
-
- appRef.current = app;
- cleanRef.current = clean;
- setReady(true);
- };
-
- init();
- }
-
- return () => {
- if (cleanRef.current) {
- cleanRef.current();
- }
- };
- }, [setReady]);
-
return (
-
-
+
+
+
- {!isReady ?
: null}
-
-
-
-
+
);
};
-const Credits = () => {
- const modal = useModal();
+const BackgroundSlideshow = () => {
+ const { data: wallpapers } = useQuery({
+ queryKey: ["wallpapers"],
+ queryFn: async () => {
+ const items = await pb.collection("wallpapers").getFullList({
+ sort: "@random",
+ expand: "artwork",
+ });
+
+ return items.map((item) => {
+ const artwork = item.expand?.artwork;
+ return pb.files.getUrl(artwork, artwork?.image);
+ });
+ },
+ });
return (
-
-
+ <>
+

-
-
- {`
-Furina Stickers:
-Guido_ (https://risibank.fr/media/297778-genshin-archon-hydro-c6-r5-soutine)
-Coll5 (https://risibank.fr/media/317061-furina-focalor-genshin)
+ {wallpapers && wallpapers?.length > 0 ? (
+
+ ) : null}
+ >
+ );
+};
-Music:
-Kururin Furina Cover by Ariyutta (https://facebook.com/arbi.yudatama)
-pet the peepo by NitroiF (https://www.youtube.com/shorts/ll2Au3CdV2k)
+type BackgroundImageProps = {
+ src: string;
+};
-Hand Sprite:
-@soapmangraylace2752 (https://www.youtube.com/shorts/HEguW7Gmu2w)
-Fijiwaterhelp (https://jailbreak.fandom.com/wiki/User_blog:Fijiwaterhelp/hand_petting)
- `.trim()}
-
-
+const BackgroundImage = ({ src }: BackgroundImageProps) => {
+ const [isLoaded, setLoaded] = useState(false);
+ return (
+ <>
+

setTimeout(() => setLoaded(true), 100)}
+ />
+
+
+ >
+ );
+};
+
+const DateTime = () => {
+ const [time, setTime] = useState(new Date());
+
+ useEffect(() => {
+ const intv = setInterval(() => {
+ setTime(new Date());
+ }, 1000);
+ return () => {
+ clearInterval(intv);
+ };
+ }, [setTime]);
+
+ const message = useMemo(() => {
+ const hours = time.getHours();
+ let msg = "Day";
+
+ if (hours >= 18 && hours <= 2) {
+ msg = "Night";
+ } else if (hours > 2 && hours <= 9) {
+ msg = "Morning";
+ } else if (hours > 9 && hours <= 15) {
+ msg = "Day";
+ } else if (hours > 15 && hours < 18) {
+ msg = "Evening";
+ }
+
+ return `Good ${msg}~ 💧✨`;
+ }, [time]);
+
+ return (
+
+
{message}
+
+ {dayjs(time).format("HH:mm")}
+
+
+ {dayjs(time).format("dddd, DD MMM YYYY")}
+
+
+
);
};
+const AppNav = ({ className }: ComponentProps<"div">) => {
+ return (
+
+ );
+};
+
+type AppNavItemProps = {
+ title: string;
+ icon: string;
+ path?: string;
+ iconClassName?: string;
+};
+
+const AppNavItem = ({ title, icon, path, iconClassName }: AppNavItemProps) => {
+ return (
+
+
+

+
+
{title}
+
+ );
+};
+
export default HomePage;
diff --git a/src/pages/home/game.ts b/src/pages/pat-pat/game.ts
similarity index 100%
rename from src/pages/home/game.ts
rename to src/pages/pat-pat/game.ts
diff --git a/src/pages/pat-pat/page.tsx b/src/pages/pat-pat/page.tsx
new file mode 100644
index 0000000..c006cb9
--- /dev/null
+++ b/src/pages/pat-pat/page.tsx
@@ -0,0 +1,91 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { useEffect, useRef, useState } from "react";
+import styles from "./style.module.css";
+import { cn } from "@/utility/utils";
+import LoadingPage from "../misc/loading-page";
+import PageMetadata from "@/components/containers/PageMetadata";
+import Modal from "@/components/ui/Modal";
+import useModal from "@/hooks/useModal";
+import Button from "@/components/ui/Button";
+
+const PatPatPage = () => {
+ const appRef = useRef
();
+ const cleanRef = useRef();
+ const targetRef = useRef(null);
+ const [isReady, setReady] = useState(false);
+
+ useEffect(() => {
+ if (!appRef.current) {
+ appRef.current = true;
+
+ const init = async () => {
+ const { default: game } = await import("./game");
+ const { app, clean } = await game();
+ targetRef.current?.appendChild(app.view as never);
+
+ appRef.current = app;
+ cleanRef.current = clean;
+ setReady(true);
+ };
+
+ init();
+ }
+
+ return () => {
+ if (cleanRef.current) {
+ cleanRef.current();
+ }
+ };
+ }, [setReady]);
+
+ return (
+
+
+
+ {!isReady ?
: null}
+
+
+
+
+
+ );
+};
+
+const Credits = () => {
+ const modal = useModal();
+
+ return (
+
+
+
+
+
+ {`
+Furina Stickers:
+Guido_ (https://risibank.fr/media/297778-genshin-archon-hydro-c6-r5-soutine)
+Coll5 (https://risibank.fr/media/317061-furina-focalor-genshin)
+
+Music:
+Kururin Furina Cover by Ariyutta (https://facebook.com/arbi.yudatama)
+
+Hand Sprite:
+@soapmangraylace2752 (https://www.youtube.com/shorts/HEguW7Gmu2w)
+Fijiwaterhelp (https://jailbreak.fandom.com/wiki/User_blog:Fijiwaterhelp/hand_petting)
+ `.trim()}
+
+
+
+ );
+};
+
+export default PatPatPage;
diff --git a/src/pages/home/stateMachine.ts b/src/pages/pat-pat/stateMachine.ts
similarity index 100%
rename from src/pages/home/stateMachine.ts
rename to src/pages/pat-pat/stateMachine.ts
diff --git a/src/pages/home/store.ts b/src/pages/pat-pat/store.ts
similarity index 100%
rename from src/pages/home/store.ts
rename to src/pages/pat-pat/store.ts
diff --git a/src/pages/home/style.module.css b/src/pages/pat-pat/style.module.css
similarity index 100%
rename from src/pages/home/style.module.css
rename to src/pages/pat-pat/style.module.css
diff --git a/yarn.lock b/yarn.lock
index b593cf0..2e532be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1408,6 +1408,11 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+dayjs@^1.11.10:
+ version "1.11.10"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
+ integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
+
debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"