From 8353ced08c2498263a67784cb100f340a5b483e2 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Fri, 10 Oct 2025 17:09:31 +0530 Subject: [PATCH] added Services.tsx with sample data --- app/components/Services.tsx | 271 ++++++++++++++++++++++++++++++++++++ app/routes/home.tsx | 4 +- 2 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 app/components/Services.tsx diff --git a/app/components/Services.tsx b/app/components/Services.tsx new file mode 100644 index 0000000..8385acf --- /dev/null +++ b/app/components/Services.tsx @@ -0,0 +1,271 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Card from '@mui/material/Card'; +import MuiChip from '@mui/material/Chip'; +import Container from '@mui/material/Container'; +import Typography from '@mui/material/Typography'; +import { styled } from '@mui/material/styles'; + +import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; +import EdgesensorHighRoundedIcon from '@mui/icons-material/EdgesensorHighRounded'; +import ViewQuiltRoundedIcon from '@mui/icons-material/ViewQuiltRounded'; + +const services = { + media: [ + { name: "Jellyseerr", url: "http://jellyseerr.aetoskia.com", desc: "Summon films and series from the digital void.", external: true }, + { name: "Sonarr", url: "http://sonarr.aetoskia.com", desc: "Keep the endless chronicles of TV under iron control.", external: true }, + { name: "Radarr", url: "http://radarr.aetoskia.com", desc: "Command the legions of cinema, enforce cinematic order.", external: true }, + { name: "qBit", url: "http://qbit.aetoskia.com", desc: "Torrent war engine, fetching data across the nether realms.", external: true }, + ], + codebase: [ + { name: "Gitea", url: "http://gitea.aetoskia.com", desc: "Forge and safeguard code like a sacred relic.", external: true }, + { name: "Registry", url: "http://registry.aetoskia.com", desc: "Monitor core constructs of the digital empire.", external: true }, + { name: "Drone", url: "http://drone.aetoskia.com", desc: "Automaton architect, building pipelines of perfection.", external: true }, + ], + monitoring: [ + { name: "Portainer", url: "http://portainer.aetoskia.com", desc: "Oversee the fleet of containers with unyielding vigilance.", external: true }, + ], +}; + +const items = [ + { + icon: , + title: 'Dashboard', + description: + 'This item could provide a snapshot of the most important metrics or data points related to the product.', + imageLight: "url('/extended_sigil.png')", + imageDark: "url('/extended_sigil.png')", + }, + { + icon: , + title: 'Mobile integration', + description: + 'This item could provide information about the mobile app version of the product.', + imageLight: "url('/extended_sigil.png')", + imageDark: "url('/extended_sigil.png')", + }, + { + icon: , + title: 'Available on all platforms', + description: + 'This item could let users know the product is available on all platforms, such as web, mobile, and desktop.', + imageLight: "url('/extended_sigil.png')", + imageDark: "url('/extended_sigil.png')", + }, +]; + +interface ChipProps { + selected?: boolean; +} + +const Chip = styled(MuiChip)(({ theme }) => ({ + variants: [ + { + props: ({ selected }) => !!selected, + style: { + background: + 'linear-gradient(to bottom right, hsl(210, 98%, 48%), hsl(210, 98%, 35%))', + color: 'hsl(0, 0%, 100%)', + borderColor: (theme.vars || theme).palette.primary.light, + '& .MuiChip-label': { + color: 'hsl(0, 0%, 100%)', + }, + ...theme.applyStyles('dark', { + borderColor: (theme.vars || theme).palette.primary.dark, + }), + }, + }, + ], +})); + +interface MobileLayoutProps { + selectedItemIndex: number; + handleItemClick: (index: number) => void; + selectedFeature: (typeof items)[0]; +} + +export function MobileLayout({ + selectedItemIndex, + handleItemClick, + selectedFeature, +}: MobileLayoutProps) { + if (!items[selectedItemIndex]) { + return null; + } + + return ( + + + {items.map(({ title }, index) => ( + handleItemClick(index)} + selected={selectedItemIndex === index} + /> + ))} + + + ({ + mb: 2, + backgroundSize: 'cover', + backgroundPosition: 'center', + minHeight: 280, + backgroundImage: 'var(--items-imageLight)', + ...theme.applyStyles('dark', { + backgroundImage: 'var(--items-imageDark)', + }), + })} + style={ + items[selectedItemIndex] + ? ({ + '--items-imageLight': items[selectedItemIndex].imageLight, + '--items-imageDark': items[selectedItemIndex].imageDark, + } as any) + : {} + } + /> + + + {selectedFeature.title} + + + {selectedFeature.description} + + + + + ); +} + +export default function Services() { + const [selectedItemIndex, setSelectedItemIndex] = React.useState(0); + + const handleItemClick = (index: number) => { + setSelectedItemIndex(index); + }; + + const selectedFeature = items[selectedItemIndex]; + + return ( + + +
+ + {items.map(({ icon, title, description }, index) => ( + handleItemClick(index)} + sx={[ + (theme) => ({ + p: 2, + height: '100%', + width: '100%', + '&:hover': { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + }), + selectedItemIndex === index && { + backgroundColor: 'action.selected', + }, + ]} + > + + {icon} + + {title} + {description} + + + ))} + + +
+ + + ({ + m: 'auto', + width: 420, + height: 500, + backgroundSize: 'contain', + backgroundImage: 'var(--items-imageLight)', + ...theme.applyStyles('dark', { + backgroundImage: 'var(--items-imageDark)', + }), + })} + style={ + items[selectedItemIndex] + ? ({ + '--items-imageLight': items[selectedItemIndex].imageLight, + '--items-imageDark': items[selectedItemIndex].imageDark, + } as any) + : {} + } + /> + + +
+
+ ); +} \ No newline at end of file diff --git a/app/routes/home.tsx b/app/routes/home.tsx index 764d501..99c87d6 100644 --- a/app/routes/home.tsx +++ b/app/routes/home.tsx @@ -5,6 +5,7 @@ import Box from "@mui/material/Box"; import Link from "@mui/material/Link"; import Grid from "@mui/material/Grid"; import Paper from "@mui/material/Paper"; +import Services from "~/components/Services"; export function meta() { return [ @@ -49,7 +50,8 @@ export default function Home() { > - + +