diff --git a/app/layout.tsx b/app/layout.tsx
index 756fcce..2cc502f 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,9 +1,11 @@
import type { Metadata } from "next";
+import Sidebar from "../components/Sidebar";
+import styles from "../styles/Layout.module.css";
import "./globals.css";
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: "Hex: Unlocked",
+ description: "",
};
export default function RootLayout({
@@ -13,7 +15,14 @@ export default function RootLayout({
}>) {
return (
-
{children}
+
+
+
+
+ {children}
+
+
+
);
-}
+}
\ No newline at end of file
diff --git a/app/page.tsx b/app/page.tsx
index c5d1e04..1549a16 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,9 +1,132 @@
-import Sidebar from "./components/Sidebar"
+'use client';
+
+import { useState, useEffect, useMemo } from 'react';
+import { useInventoryStore } from '@/store/useInventoryStore';
+import styles from '../styles/Home.module.css';
export default function Home() {
- return (
-
-
-
- );
+ const store = useInventoryStore();
+
+ const [charCount, setCharCount] = useState(0);
+ const [custCount, setCustCount] = useState(0);
+ const [itemsCount, setItemsCount] = useState(0);
+ const [offeringsCount, setOfferingsCount] = useState(0);
+ const [dlcsCount, setDlcsCount] = useState(0);
+
+ const [importText, setImportText] = useState('');
+
+ useEffect(() => {
+ Promise.all([
+ fetch('/data/characters.json').then(r => r.json()).catch(() => []),
+ fetch('/data/items.json').then(r => r.json()).catch(() => []),
+ fetch('/data/offerings.json').then(r => r.json()).catch(() => []),
+ fetch('/data/customization_items.json').then(r => r.json()).catch(() => []),
+ fetch('/data/dlcs.json').then(r => r.json()).catch(() => [])
+ ]).then(([chars, items, offerings, customizations, dlcs]) => {
+ setCharCount(chars.length);
+ setItemsCount(items.length);
+ setOfferingsCount(offerings.length);
+ setCustCount(customizations.length);
+ setDlcsCount(dlcs.length);
+ });
+ }, []);
+
+ /*
+ profile handling
+ */
+ const handleDownload = () => {
+ const blob = new Blob([importText], { type: 'application/json' });
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = 'profile.json';
+ link.click();
+ URL.revokeObjectURL(url);
+ };
+
+ const handleCopy = () => {
+ navigator.clipboard.writeText(importText);
+ };
+
+ const getExportText = () => {
+ return JSON.stringify({
+ unlockedCharacters: store.unlockedCharacters,
+ unlockedCustomizations: store.unlockedCustomizations,
+ unlockedDLCs: store.unlockedDLCs,
+ items: store.items,
+ offerings: store.offerings
+ }, null, 2);
+ };
+
+ const handleImport = async () => {
+ const parsed = JSON.parse(importText);
+ store.importProfile(parsed);
+ };
+
+ useEffect(() => {
+ setImportText(getExportText());
+ }, [store.unlockedCharacters, store.unlockedCustomizations, store.unlockedDLCs, store.items, store.offerings]);
+
+ /*
+ stats
+ */
+ const unlockedItems = useMemo(() => Object.values(store.items).filter(qty => qty > 0).length, [store.items]);
+ const unlockedOfferings = useMemo(() => Object.values(store.offerings).filter(qty => qty > 0).length, [store.offerings]);
+
+ return (
+
+
+ {/* stats cards */}
+
+
+
Characters
+
{store.unlockedCharacters.length} / {charCount || '-'}
+
+
+
Customizations
+
{store.unlockedCustomizations.length} / {custCount || '-'}
+
+
+
DLCs
+
{store.unlockedDLCs.length} / {dlcsCount || '-'}
+
+
+
Items
+
{unlockedItems} / {itemsCount || '-'}
+
+
+
Offerings
+
{unlockedOfferings} / {offeringsCount || '-'}
+
+
+
+ {/* profile import export stuff */}
+
+
+
Profile Import / Export
+
+
+
+
)
}