diff --git a/components/AppShelf/AddAppShelfItem.tsx b/components/AppShelf/AddAppShelfItem.tsx
new file mode 100644
index 000000000..d916b2e3f
--- /dev/null
+++ b/components/AppShelf/AddAppShelfItem.tsx
@@ -0,0 +1,127 @@
+import {
+ useMantineTheme,
+ Modal,
+ Paper,
+ Center,
+ Group,
+ TextInput,
+ Image,
+ Button,
+ Select,
+ AspectRatio,
+ Box,
+ Text,
+ Grid,
+} from '@mantine/core';
+import { useForm } from '@mantine/hooks';
+import { motion } from 'framer-motion';
+import { useState } from 'react';
+import { Apps } from 'tabler-icons-react';
+import { ServiceTypes } from './AppShelf.d';
+
+export default function AddItemShelfItem(props: any) {
+ const { additem: addItem } = props;
+ const [opened, setOpened] = useState(false);
+ const theme = useMantineTheme();
+ const form = useForm({
+ initialValues: {
+ type: 'Other',
+ name: '',
+ icon: '',
+ url: '',
+ },
+
+ validationRules: {},
+ });
+ return (
+ <>
+ setOpened(false)} title="Add a service">
+
+
+
+
+
+
+
+
+
+
+
+
+ setOpened(true)} size={60} />
+
+ Add Service
+
+
+
+
+ >
+ );
+}
diff --git a/components/AppShelf/AppShelf.d.ts b/components/AppShelf/AppShelf.d.ts
new file mode 100644
index 000000000..2fd16cff3
--- /dev/null
+++ b/components/AppShelf/AppShelf.d.ts
@@ -0,0 +1,15 @@
+export const ServiceTypes = [
+ 'Other',
+ 'Sonarr',
+ 'Radarr',
+ 'Lidarr',
+ 'Plex',
+ 'Emby',
+]
+
+export interface serviceItem {
+ name: string;
+ type: ServiceTypes;
+ url: string;
+ icon: string;
+}
\ No newline at end of file
diff --git a/components/AppShelf/AppShelf.tsx b/components/AppShelf/AppShelf.tsx
index 4375ca367..b3fd253be 100644
--- a/components/AppShelf/AppShelf.tsx
+++ b/components/AppShelf/AppShelf.tsx
@@ -1,32 +1,49 @@
-import React, { useState } from 'react';
-import { motion, AnimatePresence } from 'framer-motion';
-import {
- ActionIcon,
- createStyles,
- Grid,
- Group,
- Text,
- Title,
- Paper,
- Tooltip,
- Image,
- ThemeIcon,
- useMantineTheme,
- Anchor,
- Box,
- Menu,
- AspectRatio,
-} from '@mantine/core';
-import { ArrowBack, Trash } from 'tabler-icons-react';
+import React, { useEffect, useState } from 'react';
+import { motion } from 'framer-motion';
+import { Grid, Group, Text, Image, Anchor, Box, AspectRatio, createStyles } from '@mantine/core';
+import { serviceItem } from './AppShelf.d';
+import AppShelfMenu from './AppShelfMenu';
+import AddItemShelfItem from './AddAppShelfItem';
+
+const useStyles = createStyles((theme) => ({
+ main: {
+ backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],
+ textAlign: 'center',
+ padding: theme.spacing.xl,
+ borderRadius: theme.radius.md,
+
+ '&:hover': {
+ backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1],
+ },
+ },
+}));
const AppShelf = () => {
- const Services = loadServices();
+ const [services, setServices] = useState([]);
+ const { classes } = useStyles();
const [hovering, setHovering] = useState('none');
- const theme = useMantineTheme();
+
+ useEffect(() => {
+ const localServices: serviceItem[] = JSON.parse(localStorage.getItem('services') || '[]');
+ if (localServices) {
+ setServices(localServices);
+ }
+ }, []);
+
+ function addItem(item: serviceItem) {
+ setServices([...services, item]);
+ localStorage.setItem('services', JSON.stringify([...services, item]));
+ }
+
+ function removeItem(item: serviceItem) {
+ setServices(services.filter((s) => s.url !== item.url));
+ localStorage.setItem('services', JSON.stringify(services.filter((s) => s.url !== item.url)));
+ }
+
return (
- {Services.map((service, i) => (
-
+ {services.map((service, i) => (
+
{
setHovering(service.name);
@@ -36,34 +53,14 @@ const AppShelf = () => {
}}
>
- ({
- backgroundColor:
- theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],
- textAlign: 'center',
- padding: theme.spacing.xl,
- borderRadius: theme.radius.md,
-
- '&:hover': {
- backgroundColor:
- theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[1],
- },
- })}
- >
-
-
+
+
+
-
+
-
+
{service.name}
@@ -73,62 +70,75 @@ const AppShelf = () => {
))}
+
);
};
export default AppShelf;
-function loadServices() {
+
+const MockServices = [
+ {
+ name: 'Radarr',
+ type: 'Radarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Radarr/icon.png',
+ url: 'http://server:7878/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+ {
+ name: 'Sonarr',
+ type: 'Sonarr',
+ icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
+ url: 'http://server:8989/',
+ },
+];
+
+function saveLocal(arg0: any) {
+ // localStorage.setItem('services', JSON.stringify(arg0));
+ console.log(`saving ${arg0}`);
+}
+
+function loadLocal(arg0: string) {
+ const local = localStorage.getItem(arg0);
+ if (local) {
+ return JSON.parse(local);
+ }
return [
+ ...MockServices,
{
name: 'Radarr',
+ type: 'Radarr',
icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Radarr/icon.png',
url: 'http://server:7878/',
},
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
- {
- name: 'Sonarr',
- icon: 'https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/Sonarr/icon.png',
- url: 'http://server:8989/',
- },
];
}
diff --git a/components/AppShelf/AppShelfMenu.tsx b/components/AppShelf/AppShelfMenu.tsx
new file mode 100644
index 000000000..67deb3537
--- /dev/null
+++ b/components/AppShelf/AppShelfMenu.tsx
@@ -0,0 +1,34 @@
+import { Menu, Text } from '@mantine/core';
+import { showNotification } from '@mantine/notifications';
+import { Check, Trash } from 'tabler-icons-react';
+
+export default function AppShelfMenu(props: any) {
+ const { name, removeitem: removeItem } = props;
+ return (
+
+ );
+}