diff --git a/dist-electron/main.js b/dist-electron/main.js
index c9c7726..728ec0d 100644
--- a/dist-electron/main.js
+++ b/dist-electron/main.js
@@ -38,7 +38,11 @@ function createWindow() {
icon: path.join(__dirname, "path-to-your-icon", "electron-vite.svg"),
webPreferences: {
preload: path.join(__dirname, "preload.mjs")
- }
+ },
+ width: 900,
+ height: 700,
+ minWidth: 900,
+ minHeight: 700
});
win.webContents.on("did-finish-load", () => {
win == null ? void 0 : win.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString());
diff --git a/electron/main.ts b/electron/main.ts
index c81eb41..47785f1 100644
--- a/electron/main.ts
+++ b/electron/main.ts
@@ -51,6 +51,10 @@ function createWindow() {
webPreferences: {
preload: path.join(__dirname, "preload.mjs"),
},
+ width: 900,
+ height: 700,
+ minWidth: 900,
+ minHeight: 700,
});
// Send a message to the Renderer process when the window has finished loading
diff --git a/package.json b/package.json
index b07cf14..697e577 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@floating-ui/react-dom": "^2.1.1",
"@headlessui/react": "^2.1.3",
+ "@tanstack/react-query": "^5.53.3",
"axios": "^1.7.5",
"class-variance-authority": "^0.7.0",
"framer-motion": "^11.3.30",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0c6b9ef..ee7914c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,6 +14,9 @@ importers:
'@headlessui/react':
specifier: ^2.1.3
version: 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@tanstack/react-query':
+ specifier: ^5.53.3
+ version: 5.53.3(react@18.3.1)
axios:
specifier: ^1.7.5
version: 1.7.5
@@ -602,6 +605,14 @@ packages:
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
engines: {node: '>=10'}
+ '@tanstack/query-core@5.53.3':
+ resolution: {integrity: sha512-ZfjAgd7NpqDx0e4aYBt7EmS2enbulPrJwowTy+mayRE93WUUH+sIYHun1TdRjpGwDPMNNZ5D6goh7n3CwoO+HA==}
+
+ '@tanstack/react-query@5.53.3':
+ resolution: {integrity: sha512-286mN/91CeM7vC6CZFLKYDHSw+WyMX6ekIvzoTbpM4xyPb99VSyCKPLyPgaOatKqYm6ooMBquSq9NGRdKgsJfg==}
+ peerDependencies:
+ react: ^18 || ^19
+
'@tanstack/react-virtual@3.10.4':
resolution: {integrity: sha512-Y2y1QJN3e5gNTG4wlZcoW2IAFrVCuho80oyeODKKFVSbAhJAXmkDNH3ZztM6EQij5ueqpqgz5FlsgKP9TGjImA==}
peerDependencies:
@@ -2871,6 +2882,13 @@ snapshots:
dependencies:
defer-to-connect: 2.0.1
+ '@tanstack/query-core@5.53.3': {}
+
+ '@tanstack/react-query@5.53.3(react@18.3.1)':
+ dependencies:
+ '@tanstack/query-core': 5.53.3
+ react: 18.3.1
+
'@tanstack/react-virtual@3.10.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@tanstack/virtual-core': 3.10.4
diff --git a/src/App.tsx b/src/App.tsx
index a5f1e94..9fd9bec 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,6 +4,7 @@ import router from "./router/MainRouter";
import "./i18n";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const App = () => {
const { i18n } = useTranslation();
@@ -11,9 +12,13 @@ const App = () => {
const lng = navigator.language;
i18n.changeLanguage(lng);
}, []);
+
+ const queryClient = new QueryClient();
return (
-
+
+
+
);
};
diff --git a/src/assets/Icons/CheckIcon.tsx b/src/assets/Icons/CheckIcon.tsx
new file mode 100644
index 0000000..af646aa
--- /dev/null
+++ b/src/assets/Icons/CheckIcon.tsx
@@ -0,0 +1,24 @@
+const CheckIcon = ({
+ stroke,
+ className,
+}: {
+ stroke?: number;
+ className?: string;
+}) => (
+
+);
+
+export default CheckIcon;
diff --git a/src/assets/Icons/DownIcon.tsx b/src/assets/Icons/DownIcon.tsx
new file mode 100644
index 0000000..dc780f9
--- /dev/null
+++ b/src/assets/Icons/DownIcon.tsx
@@ -0,0 +1,24 @@
+const DownIcon = ({
+ stroke,
+ className,
+}: {
+ stroke?: number;
+ className?: string;
+}) => (
+
+);
+
+export default DownIcon;
diff --git a/src/assets/Icons/FolderAddIcon.tsx b/src/assets/Icons/FolderAddIcon.tsx
new file mode 100644
index 0000000..f4001e3
--- /dev/null
+++ b/src/assets/Icons/FolderAddIcon.tsx
@@ -0,0 +1,40 @@
+const FolderAddIcon = ({
+ stroke,
+ className,
+ solid,
+}: {
+ stroke?: number;
+ className?: string;
+ solid?: boolean;
+}) =>
+ solid ? (
+
+ ) : (
+
+ );
+
+export default FolderAddIcon;
diff --git a/src/assets/Icons/LeftIcon.tsx b/src/assets/Icons/LeftIcon.tsx
new file mode 100644
index 0000000..892886b
--- /dev/null
+++ b/src/assets/Icons/LeftIcon.tsx
@@ -0,0 +1,24 @@
+const LeftIcon = ({
+ stroke,
+ className,
+}: {
+ stroke?: number;
+ className?: string;
+}) => (
+
+);
+
+export default LeftIcon;
diff --git a/src/assets/Icons/RightIcon.tsx b/src/assets/Icons/RightIcon.tsx
new file mode 100644
index 0000000..2cbd98b
--- /dev/null
+++ b/src/assets/Icons/RightIcon.tsx
@@ -0,0 +1,24 @@
+const RightIcon = ({
+ stroke,
+ className,
+}: {
+ stroke?: number;
+ className?: string;
+}) => (
+
+);
+
+export default RightIcon;
diff --git a/src/assets/Icons/UpIcon.tsx b/src/assets/Icons/UpIcon.tsx
new file mode 100644
index 0000000..104bf43
--- /dev/null
+++ b/src/assets/Icons/UpIcon.tsx
@@ -0,0 +1,24 @@
+const UpIcon = ({
+ stroke,
+ className,
+}: {
+ stroke?: number;
+ className?: string;
+}) => (
+
+);
+
+export default UpIcon;
diff --git a/src/components/Crax.tsx b/src/components/Crax.tsx
index 4378d9a..ae09183 100644
--- a/src/components/Crax.tsx
+++ b/src/components/Crax.tsx
@@ -21,7 +21,7 @@ const Crax = () => {
}, []);
return (
-
+
{eyeOpen ? "0_0" : ">_<"}
);
diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx
index 2a1a60d..4de8467 100644
--- a/src/components/Icon.tsx
+++ b/src/components/Icon.tsx
@@ -1,12 +1,18 @@
import BookmarkIcon from "../assets/Icons/BookmarkIcon";
+import CheckIcon from "../assets/Icons/CheckIcon";
import CloseIcon from "../assets/Icons/CloseIcon";
+import DownIcon from "../assets/Icons/DownIcon";
import FilmIcon from "../assets/Icons/FilmIcon";
+import FolderAddIcon from "../assets/Icons/FolderAddIcon";
import FolderOpenIcon from "../assets/Icons/FolderOpenIcon";
import GearIcon from "../assets/Icons/GearIcon";
+import LeftIcon from "../assets/Icons/LeftIcon";
import MoreHorizontalIcon from "../assets/Icons/MoreHorizontalIcon";
import PlayIcon from "../assets/Icons/PlayIcon";
+import RightIcon from "../assets/Icons/RightIcon";
import SearchIcon from "../assets/Icons/SearchIcon";
import TvIcon from "../assets/Icons/TvIcon";
+import UpIcon from "../assets/Icons/UpIcon";
import UploadIcon from "../assets/Icons/UploadIcon";
const iconMap = {
@@ -18,8 +24,14 @@ const iconMap = {
moreHorizontal: MoreHorizontalIcon,
upload: UploadIcon,
folderOpen: FolderOpenIcon,
+ folderAdd: FolderAddIcon,
gear: GearIcon,
- tv: TvIcon
+ tv: TvIcon,
+ left: LeftIcon,
+ right: RightIcon,
+ up: UpIcon,
+ down: DownIcon,
+ check: CheckIcon,
};
export type IconName = keyof typeof iconMap;
diff --git a/src/components/inputs/Button.tsx b/src/components/inputs/Button.tsx
index f210691..59625a6 100644
--- a/src/components/inputs/Button.tsx
+++ b/src/components/inputs/Button.tsx
@@ -2,25 +2,30 @@ import { VariantProps } from "class-variance-authority";
import buttonStyles from "../../styles/buttonStyles";
import Icon, { IconName } from "../Icon";
import { useNavigate } from "react-router-dom";
+import { ReactNode } from "react";
-export interface ButtonProps
- extends React.ButtonHTMLAttributes
,
- VariantProps {
+export type ButtonProps = VariantProps & {
icon?: IconName;
iconType?: "solid" | "outline";
to?: string;
rounded?: boolean;
-}
+ isIconLeft?: boolean;
+ fullWidth?: boolean;
+ className?: string;
+ children?: ReactNode;
+ onClick?: () => void;
+};
const Button: React.FC = ({
className,
variant,
- title,
size = "small",
icon,
iconType,
to = "",
rounded = false,
+ isIconLeft = false,
+ fullWidth,
children,
...props
}) => {
@@ -28,23 +33,35 @@ const Button: React.FC = ({
return (
);
};
diff --git a/src/components/inputs/Switch.tsx b/src/components/inputs/Switch.tsx
new file mode 100644
index 0000000..dc33dfa
--- /dev/null
+++ b/src/components/inputs/Switch.tsx
@@ -0,0 +1,29 @@
+import { Switch as HUISwitch } from "@headlessui/react";
+
+interface SwitchProps {
+ checked: boolean;
+ onChange: (checked: boolean) => void;
+ className?: string;
+ label?: string;
+}
+
+const Switch = ({ checked, onChange, className, label }: SwitchProps) => {
+ return (
+
+ {label &&
{label}
}
+
+
+
+
+ );
+};
+
+export default Switch;
diff --git a/src/components/setup/CollectionsTab.tsx b/src/components/setup/CollectionsTab.tsx
deleted file mode 100644
index 4bf93de..0000000
--- a/src/components/setup/CollectionsTab.tsx
+++ /dev/null
@@ -1,226 +0,0 @@
-import { useState } from "react";
-import { motion } from "framer-motion";
-import {
- Description,
- Dialog,
- DialogPanel,
- DialogTitle,
- Tab,
- TabGroup,
- TabList,
- TabPanel,
- TabPanels,
-} from "@headlessui/react";
-import Crax from "../Crax";
-import Icon from "../Icon";
-import Button from "../inputs/Button";
-import TextInput from "../inputs/TextInput";
-import IconButton from "../inputs/IconButton";
-
-const MediaTypeTabPanel = () => {
- const [isOpen, setIsOpen] = useState(false);
- const [folderPath, setFolderPath] = useState("");
-
- const mediaTypes = [
- { id: "movie", label: "Movie", icon: "film" },
- { id: "tv", label: "TV Show", icon: "tv" },
- ];
-
- const [selectedMediaType, setSelectedMediaType] = useState(mediaTypes[0]);
-
- const handleSelectFolderButton = async () => {
- const result = await window.ipcRenderer.selectFolder();
- if (!result.canceled && result.filePaths.length > 0) {
- setFolderPath(result.filePaths[0]); // Set the selected folder path
- }
- };
-
- const handleSelectFolderInput = (e: any) => {
- setFolderPath(e.target.value);
- };
-
- return (
-
- {mediaTypes.map((mediaType) => (
-
- ))}
-
-
-
- );
-};
-
-const FoldersTabPanel = () => {
- return (
-
-
-
-
My Awesome Collection
-
Path: /Users/Hello/Welcome/TO
-
-
-
-
-
-
-
-
My Awesome Collection
-
Path: /Users/Hello/Welcome/TO
-
-
-
-
-
-
-
-
My Awesome Collection
-
Path: /Users/Hello/Welcome/TO
-
-
-
-
-
-
- );
-};
-
-const AdvancedTabPanel = () => {
- return Hello 2;
-};
-
-const CollectionsTab = () => {
- return (
-
-
-
-
-
- {({ selected }) => (
-
-
- Media Type
-
- )}
-
-
- {({ selected }) => (
-
-
- Folders
-
- )}
-
-
- {({ selected }) => (
-
-
- Advanced
-
- )}
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default CollectionsTab;
diff --git a/src/components/setup/ExtrasTab.tsx b/src/components/setup/ExtrasTab.tsx
deleted file mode 100644
index 0ec7439..0000000
--- a/src/components/setup/ExtrasTab.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const ExtrasTab = () => {
- return Hello 3
;
-};
-
-export default ExtrasTab;
diff --git a/src/components/setup/ServerTab.tsx b/src/components/setup/ServerTab.tsx
deleted file mode 100644
index 83a87a3..0000000
--- a/src/components/setup/ServerTab.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import Crax from "../Crax";
-import Icon from "../Icon";
-import TextInput from "../inputs/TextInput";
-
-const ServerTab = () => {
- return (
-
-
-
-
OR
-
-
- );
-};
-
-export default ServerTab;
diff --git a/src/contexts/ConfigContext.tsx b/src/contexts/ConfigContext.tsx
index 57353cc..056f94b 100644
--- a/src/contexts/ConfigContext.tsx
+++ b/src/contexts/ConfigContext.tsx
@@ -1,7 +1,6 @@
import React, { createContext, useContext } from "react";
import { useTranslation } from "react-i18next";
-import config from "../config";
-import { Config } from "electron";
+import config, { Config } from "../config";
const ConfigContext = createContext(undefined);
diff --git a/src/index.css b/src/index.css
index 81ca5b5..f11b040 100644
--- a/src/index.css
+++ b/src/index.css
@@ -7,10 +7,10 @@
-webkit-app-region: drag;
}
-/* :root {
+:root {
--swiper-theme-color: #ffffff !important;
--swiper-navigation-color: #ffffff !important;
-} */
+}
@layer base {
body {
@@ -47,155 +47,3 @@
@apply opacity-50 pointer-events-none;
}
}
-
-:root {
- --color-bg1: rgb(0, 115, 255);
- --color-bg2: rgb(0, 255, 170);
- --color1: 18, 113, 255;
- --color2: 221, 74, 255;
- --color3: 100, 220, 255;
- --color4: 200, 50, 50;
- --color5: 180, 180, 50;
- --color-interactive: 140, 100, 255;
- --circle-size: 80%;
- --blending: hard-light;
-}
-
-@keyframes moveInCircle {
- 0% {
- transform: rotate(0deg);
- }
- 50% {
- transform: rotate(180deg);
- }
- 100% {
- transform: rotate(360deg);
- }
-}
-
-@keyframes moveVertical {
- 0% {
- transform: translateY(-50%);
- }
- 50% {
- transform: translateY(50%);
- }
- 100% {
- transform: translateY(-50%);
- }
-}
-
-@keyframes moveHorizontal {
- 0% {
- transform: translateX(-50%) translateY(-10%);
- }
- 50% {
- transform: translateX(50%) translateY(10%);
- }
- 100% {
- transform: translateX(-50%) translateY(-10%);
- }
-}
-
-.gradient-bg {
- width: 100vw;
- height: 100vh;
- position: relative;
- overflow: hidden;
- background: linear-gradient(40deg, var(--color-bg1), var(--color-bg2));
- top: 0;
- left: 0;
-}
-.gradient-bg svg {
- display: none;
-}
-.gradient-bg .gradients-container {
- filter: url(#goo) blur(40px);
- width: 100%;
- height: 100%;
-}
-.gradient-bg .g1 {
- position: absolute;
- background: radial-gradient(
- circle at center,
- rgba(var(--color1)) 0,
- rgba(var(--color1)) 50%
- )
- no-repeat;
- mix-blend-mode: var(--blending);
- width: var(--circle-size);
- height: var(--circle-size);
- top: calc(50% - var(--circle-size) / 2);
- left: calc(50% - var(--circle-size) / 2);
- transform-origin: center center;
- animation: moveVertical 30s ease infinite;
- opacity: 1;
-}
-.gradient-bg .g2 {
- position: absolute;
- background: radial-gradient(
- circle at center,
- rgba(var(--color2)) 0,
- rgba(var(--color2)) 50%
- )
- no-repeat;
- mix-blend-mode: var(--blending);
- width: var(--circle-size);
- height: var(--circle-size);
- top: calc(50% - var(--circle-size) / 2);
- left: calc(50% - var(--circle-size) / 2);
- transform-origin: calc(50% - 400px);
- animation: moveInCircle 20s reverse infinite;
- opacity: 1;
-}
-.gradient-bg .g3 {
- position: absolute;
- background: radial-gradient(
- circle at center,
- rgba(var(--color3)) 0,
- rgba(var(--color3)) 50%
- )
- no-repeat;
- mix-blend-mode: var(--blending);
- width: var(--circle-size);
- height: var(--circle-size);
- top: calc(50% - var(--circle-size) / 2 + 200px);
- left: calc(50% - var(--circle-size) / 2 - 500px);
- transform-origin: calc(50% + 400px);
- animation: moveInCircle 40s linear infinite;
- opacity: 1;
-}
-.gradient-bg .g4 {
- position: absolute;
- background: radial-gradient(
- circle at center,
- rgba(var(--color4)) 0,
- rgba(var(--color4)) 50%
- )
- no-repeat;
- mix-blend-mode: var(--blending);
- width: var(--circle-size);
- height: var(--circle-size);
- top: calc(50% - var(--circle-size) / 2);
- left: calc(50% - var(--circle-size) / 2);
- transform-origin: calc(50% - 200px);
- animation: moveHorizontal 40s ease infinite;
- opacity: 0.7;
-}
-.gradient-bg .g5 {
- position: absolute;
- background: radial-gradient(
- circle at center,
- rgba(var(--color5)) 0,
- rgba(var(--color5)) 50%
- )
- no-repeat;
- mix-blend-mode: var(--blending);
- width: calc(var(--circle-size) * 2);
- height: calc(var(--circle-size) * 2);
- top: calc(50% - var(--circle-size));
- left: calc(50% - var(--circle-size));
- transform-origin: calc(50% - 800px) calc(50% + 200px);
- animation: moveInCircle 20s ease infinite;
- opacity: 1;
-}
diff --git a/src/pages/setup/SetupTabs/CollectionsTab.tsx b/src/pages/setup/SetupTabs/CollectionsTab.tsx
new file mode 100644
index 0000000..449ea79
--- /dev/null
+++ b/src/pages/setup/SetupTabs/CollectionsTab.tsx
@@ -0,0 +1,160 @@
+import { motion } from "framer-motion";
+import {
+ Listbox,
+ ListboxButton,
+ ListboxOption,
+ ListboxOptions,
+ Tab,
+ TabGroup,
+ TabList,
+ TabPanel,
+ TabPanels,
+} from "@headlessui/react";
+import { useState } from "react";
+import Icon from "../../../components/Icon";
+import TextInput from "../../../components/inputs/TextInput";
+import Button from "../../../components/inputs/Button";
+import axios from "axios";
+
+const NewCollectionSubTab = () => {
+ const mediaTypes = [
+ { mediaType: "movie", label: "Movie", icon: "film" },
+ { mediaType: "tv", label: "TV Show", icon: "tv" },
+ ];
+
+ const [selected, setSelected] = useState(mediaTypes[0]);
+
+ const postNewCollectionConfig = async (collectionsConfig: {
+ name: string;
+ path: string;
+ mediaType: "movie" | "tv";
+ isAdult: boolean;
+ }) => {
+ const { data } = await axios.patch(
+ "http://localhost:8803/api/v1/config/collections",
+ collectionsConfig
+ );
+ return data;
+ };
+
+ const [currentCollectionName, setCurrentCollectionName] = useState("");
+ const [currentCollectionImage, setCurrentCollectionImage] = useState("");
+ const [currentMediaType, setCurrentMediaType] = useState("");
+
+ return (
+
+
+
+
+
+
+
+
+
+
Media Type
+
+
+
+
+
+
+ {mediaTypes.map((mediaType) => (
+
+ {mediaType.label}
+
+ ))}
+
+
+
+
+
+ );
+};
+
+const CollectionsSubTab = () => {
+ return Hello 2
;
+};
+
+const collectionTabsContent = [
+ {
+ id: "newcollection",
+ title: "New Collection",
+ icon: "folderAdd",
+ tab: ,
+ },
+ {
+ id: "collections",
+ title: "Collections",
+ icon: "folderOpen",
+ tab: ,
+ },
+];
+
+const CollectionsTab = ({ config, handleBack, handleNext }: any) => {
+ const [selectedIndex, setSelectedIndex] = useState(0);
+ return (
+
+
+
+ {collectionTabsContent.map(({ id, title, icon }, index) => (
+
+
+ {title}
+
+ ))}
+
+
+ {collectionTabsContent.map(({ id, tab }) => (
+
+ {tab}
+
+ ))}
+
+
+
+
+
+
+
+ );
+};
+
+export default CollectionsTab;
diff --git a/src/pages/setup/SetupTabs/ExtrasTab.tsx b/src/pages/setup/SetupTabs/ExtrasTab.tsx
new file mode 100644
index 0000000..b35ce3f
--- /dev/null
+++ b/src/pages/setup/SetupTabs/ExtrasTab.tsx
@@ -0,0 +1,35 @@
+import Icon from "../../../components/Icon";
+import Switch from "../../../components/inputs/Switch";
+
+const ExtrasTab = ({ config, handleBack, handleNext }: any) => {
+ return (
+
+
+ Homepage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ExtrasTab;
diff --git a/src/pages/setup/SetupTabs/ServerTab.tsx b/src/pages/setup/SetupTabs/ServerTab.tsx
new file mode 100644
index 0000000..85bb803
--- /dev/null
+++ b/src/pages/setup/SetupTabs/ServerTab.tsx
@@ -0,0 +1,75 @@
+import { useEffect, useState } from "react";
+import Icon from "../../../components/Icon";
+import TextInput from "../../../components/inputs/TextInput";
+import Button from "../../../components/inputs/Button";
+import axios from "axios";
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+
+const ServerTab = ({ handleBack, handleNext }: any) => {
+ const getServerConfig = async () => {
+ const { data } = await axios.get(
+ "http://localhost:8803/api/v1/config/server"
+ );
+ return data;
+ };
+
+ const patchServerConfig = async (serverConfig: { name: string }) => {
+ const { data } = await axios.patch(
+ "http://localhost:8803/api/v1/config/server",
+ serverConfig
+ );
+ return data;
+ };
+
+ const queryClient = useQueryClient();
+
+ const { data: server } = useQuery({
+ queryKey: ["server"],
+ queryFn: getServerConfig,
+ });
+
+ const mutation = useMutation({
+ mutationFn: patchServerConfig,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ["server"] });
+ },
+ });
+
+ const [serverName, setServerName] = useState(server?.name || "");
+
+ useEffect(() => {
+ if (server) {
+ setServerName(server.name);
+ }
+ }, [server]);
+
+ const handleNextWithFn = async () => {
+ mutation.mutate({ name: serverName });
+ handleNext();
+ };
+
+ return (
+
+
+
setServerName(e.target.value)}
+ />
+ OR
+
+
+
+
+
+
+ );
+};
+
+export default ServerTab;
diff --git a/src/pages/setup/SetupTabs/UsersTab.tsx b/src/pages/setup/SetupTabs/UsersTab.tsx
new file mode 100644
index 0000000..7e0d8c9
--- /dev/null
+++ b/src/pages/setup/SetupTabs/UsersTab.tsx
@@ -0,0 +1,73 @@
+import { useState } from "react";
+import Switch from "../../../components/inputs/Switch";
+import TextInput from "../../../components/inputs/TextInput";
+import Button from "../../../components/inputs/Button";
+import Icon from "../../../components/Icon";
+
+const UsersTab = ({ config, handleBack, handleNext }: any) => {
+ const [profileImage, setProfileImage] = useState("");
+ const [childAccount, setChildAccount] = useState(false);
+ const [passwordProtected, setPasswordProtected] = useState(false);
+ return (
+
+
+
+ {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((item) => (
+
+ ))}
+
+
+
+ {profileImage !== "" && (
+
+ )}
+
+
+ Upload
+
+
+
+
+
+
+
setPasswordProtected(checked)}
+ />
+ {passwordProtected && (
+
+
+
+
+ )}
+ setChildAccount(checked)}
+ />
+
+ Confirm
+
+
+
+ );
+};
+
+export default UsersTab;
diff --git a/src/components/setup/SetupTabs.tsx b/src/pages/setup/SetupTabs/index.tsx
similarity index 50%
rename from src/components/setup/SetupTabs.tsx
rename to src/pages/setup/SetupTabs/index.tsx
index 2dbef48..b4515c0 100644
--- a/src/components/setup/SetupTabs.tsx
+++ b/src/pages/setup/SetupTabs/index.tsx
@@ -1,31 +1,63 @@
-import { useState } from "react";
+import { ReactNode, useState } from "react";
import { motion } from "framer-motion";
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@headlessui/react";
import CollectionsTab from "./CollectionsTab";
-import ExtrasTab from "./ExtrasTab";
import ServerTab from "./ServerTab";
-import Icon from "../Icon";
+import SetupTab from "./ExtrasTab";
+import Icon from "../../../components/Icon";
+import UsersTab from "./UsersTab";
-const setupTabsContent = [
+
+interface SetupTabContent {
+ id: string;
+ title: string;
+ tab: (handleBack?: () => void, handleNext?: () => void) => ReactNode;
+}
+
+const setupTabsContent: SetupTabContent[] = [
{
id: "server",
title: "Server",
- tab: ,
+ tab: (handleBack, handleNext) => (
+
+ ),
},
{
id: "collections",
title: "Collections",
- tab: ,
+ tab: (handleBack, handleNext) => (
+
+ ),
+ },
+ {
+ id: "users",
+ title: "Users",
+ tab: (handleBack, handleNext) => (
+
+ ),
},
{
id: "extras",
title: "Extras",
- tab: ,
+ tab: (handleBack, handleNext) => ,
},
];
const SetupTabs = ({ setIsOpen }: any) => {
const [selectedIndex, setSelectedIndex] = useState(0);
+
+ const handleNext = () => {
+ if (selectedIndex < setupTabsContent.length - 1) {
+ setSelectedIndex(selectedIndex + 1);
+ }
+ };
+
+ const handleBack = () => {
+ if (selectedIndex > 0) {
+ setSelectedIndex(selectedIndex - 1);
+ }
+ };
+
return (
{
onChange={setSelectedIndex}
>
-
+
{setupTabsContent.map(({ id, title }, index) => (
{selectedIndex === index && (
)}
@@ -52,20 +86,22 @@ const SetupTabs = ({ setIsOpen }: any) => {
))}
{
e.stopPropagation();
setIsOpen(false);
}}
>
-
-
+
{setupTabsContent.map(({ id, tab }) => (
- {tab}
+
+ {tab(handleBack, handleNext)}
+
))}
diff --git a/src/pages/setup/WelcomePage.tsx b/src/pages/setup/WelcomePage.tsx
index 0d58061..bc99dc1 100644
--- a/src/pages/setup/WelcomePage.tsx
+++ b/src/pages/setup/WelcomePage.tsx
@@ -1,7 +1,8 @@
import { AnimatePresence, motion } from "framer-motion";
import { useState } from "react";
import Logo from "../../components/Logo";
-import SetupTabs from "../../components/setup/SetupTabs";
+import SetupTabs from "./SetupTabs";
+import Icon from "../../components/Icon";
const WelcomePage = () => {
const [isOpen, setIsOpen] = useState(false);
@@ -79,7 +80,7 @@ const WelcomePage = () => {
},
},
close: {
- width: "130px",
+ width: "160px",
height: "40px",
transition: {
type: "spring",
@@ -95,10 +96,10 @@ const WelcomePage = () => {
}
: undefined
}
- className={`relative transition-colors text-black flex items-center justify-center ${
+ className={`relative transition-colors group/wrapper text-black flex items-center justify-center bg-white ${
!isOpen
- ? "mt-10 rounded-xl cursor-pointer bg-white"
- : "cursor-default rounded-[20px] border bg-white/60"
+ ? "mt-10 rounded-xl cursor-pointer"
+ : "cursor-default rounded-3xl border"
}`}
onClick={!isOpen ? toggleOpen : undefined}
>
@@ -120,8 +121,11 @@ const WelcomePage = () => {
) : (
-
- Setup Dester
+
)}
diff --git a/src/styles/buttonStyles.ts b/src/styles/buttonStyles.ts
index b6d11dd..a50c8a9 100644
--- a/src/styles/buttonStyles.ts
+++ b/src/styles/buttonStyles.ts
@@ -5,29 +5,23 @@ const buttonStyles = cva(
"font-semibold",
"flex",
"items-center",
+ "justify-center",
"transition-colors",
- "w-fit",
"whitespace-nowrap",
],
{
variants: {
variant: {
- primary: [
- "bg-white",
- "hover:bg-zinc-200",
- "active:bg-zinc-400",
- "text-black",
- ],
+ primary: ["bg-white", "hover:bg-zinc-200", "text-black"],
secondary: [
"bg-neutral-600/20",
"hover:bg-neutral-600/40",
- "active:bg-neutral-600/60",
"text-white",
"backdrop-blur-lg",
"shadow-[inset_0_1px_0_0_#ffffff1a]",
],
black: ["bg-black", "text-white"],
- accent: ["bg-emerald-400", "text-white", "hover:bg-emerald-500"],
+ accent: ["bg-emerald-400", "hover:bg-emerald-500"],
},
size: {
small: ["text-sm", "px-1", "h-10"],
@@ -36,6 +30,10 @@ const buttonStyles = cva(
rounded: {
true: "rounded-full",
},
+ fullWidth: {
+ true: "w-full",
+ flase: "w-fit",
+ },
},
compoundVariants: [
{
@@ -52,6 +50,7 @@ const buttonStyles = cva(
defaultVariants: {
variant: "primary",
size: "small",
+ fullWidth: false,
},
}
);
diff --git a/src/wrappers/SetupWrapper.tsx b/src/wrappers/SetupWrapper.tsx
index 0752c96..6c26f75 100644
--- a/src/wrappers/SetupWrapper.tsx
+++ b/src/wrappers/SetupWrapper.tsx
@@ -5,33 +5,6 @@ const SetupWrapper = () => {
return (