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 ( -
- + <> + title - -
-          {`
-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 ( + <> + img 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} +
+

{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"