diff --git a/apps/web/package.json b/apps/web/package.json index 05d4174..ebba057 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -32,6 +32,7 @@ "geist": "^1.5.1", "lucide-react": "^0.546.0", "marked-react": "^3.0.2", + "motion": "^12.23.26", "next": "^16.0.10", "next-themes": "^0.4.6", "prism-react-renderer": "^2.4.1", diff --git a/apps/web/src/app/api/data/settings/route.ts b/apps/web/src/app/api/data/settings/route.ts index bfb1fc4..a7a0a43 100644 --- a/apps/web/src/app/api/data/settings/route.ts +++ b/apps/web/src/app/api/data/settings/route.ts @@ -50,7 +50,8 @@ export const POST = async (request: NextRequest) => { if ( body.action === "site_title_description" && body.title && - body.description + body.description && + body.server_owner ) { try { await db @@ -61,16 +62,15 @@ export const POST = async (request: NextRequest) => { .update(main_schema.kvData) .set({ value: body.description }) .where(dorm.eq(main_schema.kvData.key, "description")); - return Response.json( - { - success: true, - status: 200, - msg: "", - }, - { - status: 200, - }, - ); + await db + .update(main_schema.kvData) + .set({ value: body.server_owner }) + .where(dorm.eq(main_schema.kvData.key, "copyrightOwner")); + return Response.json({ + success: true, + status: 200, + msg: "", + }); } catch (e: any) { statusCode = 500; throw new Error(e.message || "ERR_GENERIC"); @@ -103,22 +103,24 @@ export const POST = async (request: NextRequest) => { .from(main_schema.kvData) .where(dorm.eq(main_schema.kvData.key, "searchStatus")) )[0].value; - return Response.json( - { - success: true, - status: 200, - msg: "", - data: { - homePage, - registration, - robotsTxt, - search, - }, - }, - { - status: 200, + const displayVersion = ( + await db + .select() + .from(main_schema.kvData) + .where(dorm.eq(main_schema.kvData.key, "exposeVersion")) + )[0].value; + return Response.json({ + success: true, + status: 200, + msg: "", + data: { + homePage, + registration, + robotsTxt, + search, + displayVersion, }, - ); + }); } catch (e: any) { statusCode = 500; throw new Error(e.message || "ERR_GENERIC"); @@ -134,12 +136,14 @@ export const POST = async (request: NextRequest) => { registration: boolean; robotsTxt: boolean; search: boolean; + displayVersion: boolean; }; if ( typeof data.homePage !== "boolean" || typeof data.registration !== "boolean" || typeof data.robotsTxt !== "boolean" || - typeof data.search !== "boolean" + typeof data.search !== "boolean" || + typeof data.displayVersion !== "boolean" ) { throw new Error("ERR_INVALID_BODY_TYPE"); } @@ -159,23 +163,20 @@ export const POST = async (request: NextRequest) => { .update(main_schema.kvData) .set({ value: body.data.search }) .where(dorm.eq(main_schema.kvData.key, "searchStatus")); - - return Response.json( - { - success: true, - status: 200, - msg: "", - }, - { - status: 200, - }, - ); + await db + .update(main_schema.kvData) + .set({ value: body.data.displayVersion }) + .where(dorm.eq(main_schema.kvData.key, "exposeVersion")); + return Response.json({ + success: true, + status: 200, + msg: "", + }); } catch (e: any) { statusCode = 500; throw new Error(e.message || "ERR_GENERIC"); } - } - if (body.action === "site_robots_txt_json") { + } else if (body.action === "site_robots_txt_json") { try { if (!body.data || typeof body.data !== "object") { throw new Error("ERR_INVALID_BODY_DATA_OBJ"); @@ -186,16 +187,11 @@ export const POST = async (request: NextRequest) => { .set({ value: body.data }) .where(dorm.eq(main_schema.kvData.key, "robotsTxtList")); - return Response.json( - { - success: true, - status: 200, - msg: "", - }, - { - status: 200, - }, - ); + return Response.json({ + success: true, + status: 200, + msg: "", + }); } catch (e: any) { statusCode = 500; throw new Error(e.message || "ERR_GENERIC"); @@ -208,17 +204,12 @@ export const POST = async (request: NextRequest) => { .from(main_schema.kvData) .where(dorm.eq(main_schema.kvData.key, "robotsTxtList")); - return Response.json( - { - success: true, - status: 200, - msg: "", - data: currentList[0].value, - }, - { - status: 200, - }, - ); + return Response.json({ + success: true, + status: 200, + msg: "", + data: currentList[0].value, + }); } catch (e: any) { statusCode = 500; throw new Error(e.message || "ERR_GENERIC"); @@ -270,12 +261,7 @@ export const POST = async (request: NextRequest) => { statusCode = 500; throw new Error("ERR_REMOVE_FAILED"); } - return Response.json( - { success: true, msg: "Deleted User" }, - { - status: 200, - }, - ); + return Response.json({ success: true, msg: "Deleted User" }); } catch (e: any) { console.log(e); statusCode = 403; @@ -305,12 +291,7 @@ export const POST = async (request: NextRequest) => { .update(main_schema.userPosts) .set({ status: "draft" }) // making every post a "draft" instaed of making it unlisted .where(dorm.eq(main_schema.userPosts.byUser, body.user)); - return Response.json( - { success: true, msg: "Banned User" }, - { - status: 200, - }, - ); + return Response.json({ success: true, msg: "Banned User" }); } catch (e: any) { console.log(e); statusCode = 500; @@ -331,12 +312,10 @@ export const POST = async (request: NextRequest) => { if (!data.success) { throw new Error("Failed to revoke the user's sessions"); } - return Response.json( - { success: true, msg: "Revoked the user's sessions" }, - { - status: 200, - }, - ); + return Response.json({ + success: true, + msg: "Revoked the user's sessions", + }); } catch (e: any) { console.log(e); statusCode = 500; diff --git a/apps/web/src/app/api/data/system_info/route.ts b/apps/web/src/app/api/data/system_info/route.ts index 8e6132e..34deca3 100644 --- a/apps/web/src/app/api/data/system_info/route.ts +++ b/apps/web/src/app/api/data/system_info/route.ts @@ -26,10 +26,10 @@ export const GET = async (request: NextRequest) => { return Response.json({ copyright_owner: getCopyrightOwner[0].value, feature_status: { - homePage: getHomePageStatus[0].value !== "false", - search: getSearchPageStatus[0].value !== "false", + homePage: getHomePageStatus[0].value, + search: getSearchPageStatus[0].value, }, - optionalExposeVersion: exposeVersion[0].value !== "false", + optionalExposeVersion: exposeVersion[0].value, version: exposeVersion[0].value !== "false" ? projectData.version : null, }); }; diff --git a/apps/web/src/app/dashboard/settings/clientComponents.tsx b/apps/web/src/app/dashboard/settings/clientComponents.tsx index 2f62503..bde6117 100644 --- a/apps/web/src/app/dashboard/settings/clientComponents.tsx +++ b/apps/web/src/app/dashboard/settings/clientComponents.tsx @@ -19,13 +19,16 @@ type RobotsParsedJson = Record; export function ChangeSiteSettings({ serverTitleData, serverDescriptionData, + serverOwnerData, }: { serverTitleData: string; serverDescriptionData: string; + serverOwnerData: string; }) { const [siteSettings, setSiteSettings] = useState({ title: serverTitleData || "", description: serverDescriptionData || "", + server_owner: serverOwnerData || "", }); const [statusSystemPull, setStatusSystemPull] = useState<{ @@ -34,12 +37,14 @@ export function ChangeSiteSettings({ robotsTxt: boolean; search: boolean; sysFailed: boolean; + displayVersion: boolean; }>({ homePage: false, registration: false, robotsTxt: false, search: true, sysFailed: true, + displayVersion: false, }); const getToggleData = useMutation({ @@ -64,6 +69,7 @@ export function ChangeSiteSettings({ robotsTxt: res.data.robotsTxt, search: res.data.search, sysFailed: false, + displayVersion: res.data.displayVersion, }); return; } catch (e: any) { @@ -73,6 +79,7 @@ export function ChangeSiteSettings({ robotsTxt: statusSystemPull.robotsTxt, search: statusSystemPull.search, sysFailed: true, + displayVersion: statusSystemPull.displayVersion, }); console.error(e); toast.error(`Fetch Failed: ${e.message}`); @@ -121,6 +128,7 @@ export function ChangeSiteSettings({ setSiteSettings({ title: e.target.value, description: siteSettings.description, + server_owner: siteSettings.server_owner, }); }} /> @@ -138,6 +146,25 @@ export function ChangeSiteSettings({ setSiteSettings({ title: siteSettings.title, description: e.target.value, + server_owner: siteSettings.server_owner, + }); + }} + /> + +
+ + Server Owner:{" "} + * + + { + setSiteSettings({ + title: siteSettings.title, + description: siteSettings.description, + server_owner: e.target.value, }); }} /> @@ -157,6 +184,7 @@ export function ChangeSiteSettings({ action: "site_title_description", title: siteSettings.title, description: siteSettings.description, + server_owner: siteSettings.server_owner, }) } > @@ -177,6 +205,7 @@ export function ChangeSiteSettings({ registration: statusSystemPull.registration, robotsTxt: statusSystemPull.robotsTxt, search: statusSystemPull.search, + displayVersion: statusSystemPull.displayVersion, sysFailed: statusSystemPull.sysFailed, }); sendData.mutate({ @@ -184,8 +213,9 @@ export function ChangeSiteSettings({ data: { homePage: checked, registration: statusSystemPull.registration, - robotsTxt: statusSystemPull.robotsTxt, + robotsTxt: statusSystemPull.homePage, search: statusSystemPull.search, + displayVersion: statusSystemPull.displayVersion, }, }); getToggleData.mutate(); @@ -206,6 +236,7 @@ export function ChangeSiteSettings({ robotsTxt: statusSystemPull.robotsTxt, search: statusSystemPull.search, sysFailed: statusSystemPull.sysFailed, + displayVersion: statusSystemPull.displayVersion, }); sendData.mutate({ action: "change_home_page_register_robotstxt_toggles", @@ -214,6 +245,7 @@ export function ChangeSiteSettings({ registration: checked, robotsTxt: statusSystemPull.robotsTxt, search: statusSystemPull.search, + displayVersion: statusSystemPull.displayVersion, }, }); getToggleData.mutate(); @@ -234,6 +266,7 @@ export function ChangeSiteSettings({ robotsTxt: checked, search: statusSystemPull.search, sysFailed: statusSystemPull.sysFailed, + displayVersion: statusSystemPull.displayVersion, }); sendData.mutate({ action: "change_home_page_register_robotstxt_toggles", @@ -242,6 +275,7 @@ export function ChangeSiteSettings({ registration: statusSystemPull.registration, robotsTxt: checked, search: statusSystemPull.search, + displayVersion: statusSystemPull.displayVersion, }, }); getToggleData.mutate(); @@ -262,14 +296,16 @@ export function ChangeSiteSettings({ robotsTxt: statusSystemPull.robotsTxt, search: checked, sysFailed: statusSystemPull.sysFailed, + displayVersion: statusSystemPull.displayVersion, }); sendData.mutate({ action: "change_home_page_register_robotstxt_toggles", data: { homePage: statusSystemPull.homePage, registration: statusSystemPull.registration, - robotsTxt: statusSystemPull.robotsTxt, - search: checked, + robotsTxt: checked, + search: statusSystemPull.search, + displayVersion: statusSystemPull.displayVersion, }, }); getToggleData.mutate(); @@ -278,6 +314,36 @@ export function ChangeSiteSettings({ />
+
+ { + console.log(`Home Page: ${checked}`); + setStatusSystemPull({ + homePage: checked, + registration: statusSystemPull.registration, + robotsTxt: statusSystemPull.robotsTxt, + search: statusSystemPull.search, + displayVersion: checked, + sysFailed: statusSystemPull.sysFailed, + }); + sendData.mutate({ + action: "change_home_page_register_robotstxt_toggles", + data: { + homePage: statusSystemPull.homePage, + registration: statusSystemPull.registration, + robotsTxt: checked, + search: statusSystemPull.search, + displayVersion: checked, + }, + }); + getToggleData.mutate(); + }} + disabled={statusSystemPull.sysFailed} + /> + +
); diff --git a/apps/web/src/app/dashboard/settings/page.tsx b/apps/web/src/app/dashboard/settings/page.tsx index 7fe5cfa..7e58e72 100644 --- a/apps/web/src/app/dashboard/settings/page.tsx +++ b/apps/web/src/app/dashboard/settings/page.tsx @@ -35,12 +35,17 @@ export default async function DashboardPage() { .select() .from(main_schema.kvData) .where(dorm.eq(main_schema.kvData.key, "robotsTxtList")); + const kvOwner = await db + .select() + .from(main_schema.kvData) + .where(dorm.eq(main_schema.kvData.key, "copyrightOwner")); return (
diff --git a/apps/web/src/components/imageView.tsx b/apps/web/src/components/imageView.tsx index a491350..13cce4e 100644 --- a/apps/web/src/components/imageView.tsx +++ b/apps/web/src/components/imageView.tsx @@ -1,6 +1,7 @@ "use client"; import { XIcon } from "lucide-react"; import Image from "next/image"; +import { motion } from "motion/react"; export default function ImageView({ imageSrc, @@ -11,20 +12,32 @@ export default function ImageView({ }) { return ( <> -
-
-
+
+
e.stopPropagation()} + > +
Image - +
- Preview Image
diff --git a/apps/web/src/components/navigation.tsx b/apps/web/src/components/navigation.tsx index ccf7ab3..05c474c 100644 --- a/apps/web/src/components/navigation.tsx +++ b/apps/web/src/components/navigation.tsx @@ -9,6 +9,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { toast } from "sonner"; import { authClient } from "@/lib/auth-client"; import { Button } from "./ui/button"; import { Skeleton } from "./ui/skeleton"; @@ -33,6 +34,9 @@ export default function Navigation() { queryFn: async () => { const req = await fetch("/api/data/system_info"); const res = await req.json(); + if (!req.ok) { + toast.error("Failed to fetch system info"); + } return res; }, queryKey: ["system_info"], @@ -47,6 +51,11 @@ export default function Navigation() { size="icon" className="cursor-pointer" aria-label="Home" + /** disabled={ + querySystemData.isLoading + ? false + : querySystemData.data?.feature_status.home !== true +} */ > @@ -57,6 +66,11 @@ export default function Navigation() { size="icon" className="cursor-pointer" aria-label="Search" + /** disabled={ + querySystemData.isLoading + ? false + : querySystemData.data?.feature_status.search !== true +} */ > diff --git a/apps/web/src/components/publicPostsAndVideos.tsx b/apps/web/src/components/publicPostsAndVideos.tsx index 974dae4..79009f1 100644 --- a/apps/web/src/components/publicPostsAndVideos.tsx +++ b/apps/web/src/components/publicPostsAndVideos.tsx @@ -8,6 +8,8 @@ import Link from "next/link"; import Image from "next/image"; import { Badge } from "./ui/badge"; import ImageView from "./imageView"; +import { motion, AnimatePresence } from "motion/react"; + import { CircleUserIcon, ExternalLink, @@ -165,14 +167,22 @@ export function PublicPostsAndVideos({ return (
- {imageViewSys.previewOn && ( - - setImageViewSys({ previewOn: false, previewImageUrl: "" }) - } - /> - )} + + {imageViewSys.previewOn ? ( + + + setImageViewSys({ previewOn: false, previewImageUrl: "" }) + } + /> + + ) : null} + {mode === "search" ? ( <>
diff --git a/bun.lock b/bun.lock index 1762e6a..e15e17f 100644 --- a/bun.lock +++ b/bun.lock @@ -7,6 +7,7 @@ "dependencies": { "dotenv": "^17.2.3", "geist": "^1.5.1", + "motion": "^12.23.26", "next": "^16.0.10", "pg": "^8.16.3", "zod": "^4.1.12", @@ -44,6 +45,7 @@ "geist": "^1.5.1", "lucide-react": "^0.546.0", "marked-react": "^3.0.2", + "motion": "^12.23.26", "next": "^16.0.10", "next-themes": "^0.4.6", "prism-react-renderer": "^2.4.1", @@ -806,6 +808,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "framer-motion": ["framer-motion@12.23.26", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA=="], + "geist": ["geist@1.5.1", "", { "peerDependencies": { "next": ">=13.2.0" } }, "sha512-mAHZxIsL2o3ZITFaBVFBnwyDOw+zNLYum6A6nIjpzCGIO8QtC3V76XF2RnZTyLx1wlDTmMDy8jg3Ib52MIjGvQ=="], "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], @@ -862,6 +866,12 @@ "marked-react": ["marked-react@3.0.2", "", { "dependencies": { "marked": "^16.0.0" }, "peerDependencies": { "react": "^16.8.0 || >=17.0.0" } }, "sha512-uLuH5P5i1H+igH+Y7toWX+sM2UGDdYMIPZ9JtBNajkyFiQBoAMJJY7gBlm3nHXHiPDZHkhZ9p/cb9XO0F1qnCA=="], + "motion": ["motion@12.23.26", "", { "dependencies": { "framer-motion": "^12.23.26", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Ll8XhVxY8LXMVYTCfme27WH2GjBrCIzY4+ndr5QKxsK+YwCtOi2B/oBi5jcIbik5doXuWT/4KKDOVAZJkeY5VQ=="], + + "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], + + "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -1078,8 +1088,6 @@ "web/@types/node": ["@types/node@20.19.25", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ=="], - "web/next": ["next@16.0.7", "", { "dependencies": { "@next/env": "16.0.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.7", "@next/swc-darwin-x64": "16.0.7", "@next/swc-linux-arm64-gnu": "16.0.7", "@next/swc-linux-arm64-musl": "16.0.7", "@next/swc-linux-x64-gnu": "16.0.7", "@next/swc-linux-x64-musl": "16.0.7", "@next/swc-win32-arm64-msvc": "16.0.7", "@next/swc-win32-x64-msvc": "16.0.7", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A=="], - "@aws-crypto/crc32/@aws-sdk/types/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="], "@aws-crypto/crc32c/@aws-sdk/types/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="], @@ -1142,24 +1150,6 @@ "@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="], - "web/next/@next/env": ["@next/env@16.0.7", "", {}, "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw=="], - - "web/next/@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg=="], - - "web/next/@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA=="], - - "web/next/@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww=="], - - "web/next/@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g=="], - - "web/next/@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA=="], - - "web/next/@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w=="], - - "web/next/@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q=="], - - "web/next/@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug=="], - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], diff --git a/package.json b/package.json index fb2b92c..e198ea2 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "dependencies": { "dotenv": "^17.2.3", "geist": "^1.5.1", + "motion": "^12.23.26", "next": "^16.0.10", "pg": "^8.16.3", "zod": "^4.1.12"