diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b0204e5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.git +.gitignore +.next +node_modules +README.md +.env.example +*.md diff --git a/CONFIGURATION.md b/CONFIGURATION.md new file mode 100644 index 0000000..c6b85dc --- /dev/null +++ b/CONFIGURATION.md @@ -0,0 +1,150 @@ +# Configuration de Sochboard + +## Structure générale + +```yaml +site: + # Informations du site +theme: + # Apparence +sections: + # Liste des sections et liens +``` + +## `site` + +| Champ | Requis | Type | Défaut | Description | +|---|---|---|---|---| +| `name` | Oui | chaîne | — | Nom du site (ex: "Soch Family") | +| `title` | Oui | chaîne | — | Sous-titre affiché sous le nom | +| `description` | Non | chaîne | — | Texte optionnel dans le header | +| `favicon` | Non | chaîne | — | URL ou chemin du favicon | +| `logoUrl` | Non | chaîne (URL) | — | URL d'une photo/image qui remplace le "S" | +| `showFooter` | Non | booléen | `true` | `false` pour masquer le footer | + +```yaml +site: + name: "Soch Family" + title: "Les applications de la famille" + description: "Accès rapide à nos services" + logoUrl: "https://example.com/photo.jpg" + showFooter: true +``` + +## `theme` + +| Champ | Requis | Type | Défaut | Description | +|---|---|---|---|---| +| `mode` | Non | `"dark"` ou `"light"` | `"dark"` | Mode de couleur | +| `accent` | Non | chaîne (hex) | `"#8b5cf6"` | Couleur d'accent (ex: `"#ff0000"`) | +| `background` | Non | `"gradient"` ou `"solid"` | `"gradient"` | Type d'arrière-plan | + +```yaml +theme: + mode: "dark" + accent: "#8b5cf6" + background: "gradient" +``` + +## `sections` + +Tableau de sections. Chaque section contient : + +| Champ | Requis | Type | Défaut | Description | +|---|---|---|---|---| +| `id` | Oui | chaîne | — | Identifiant unique | +| `title` | Oui | chaîne | — | Titre affiché | +| `description` | Non | chaîne | — | Texte sous le titre | +| `cardLayout` | Non | `"horizontal"` ou `"vertical"` | `"horizontal"` | Disposition des cartes dans la section | +| `links` | Non | tableau | `[]` | Liste des liens | + +```yaml +sections: + - id: "global" + title: "Global" + description: "Tous les services" + cardLayout: "horizontal" + links: [] +``` + +### `links` + +Tableau de liens. Chaque lien contient : + +| Champ | Requis | Type | Défaut | Description | +|---|---|---|---|---| +| `id` | Oui | chaîne | — | Identifiant unique | +| `name` | Oui | chaîne | — | Nom affiché | +| `description` | Non | chaîne | — | Description sous le nom | +| `url` | Oui | chaîne (URL) | — | Lien de l'application | +| `icon` | Oui | chaîne | — | Nom de l'icône Lucide | +| `iconUrl` | Non | chaîne (URL) | — | URL d'une image personnalisée (remplace `icon`) | +| `color` | Non | chaîne (hex) | — | Couleur d'accent (ex: `"#2daae1"`) | +| `openInNewTab` | Non | booléen | `true` | `false` pour ouvrir dans le même onglet | + +```yaml +links: + - id: "nextcloud" + name: "Nextcloud" + description: "Fichiers et documents" + url: "https://cloud.example.com" + icon: "Cloud" + iconUrl: "https://example.com/nextcloud-icon.svg" + color: "#2daae1" + openInNewTab: false +``` + +## Icônes Lucide disponibles + +``` +Cloud Film Music Gamepad2 Router +Server House BookOpen Calendar Mail +Shield Settings Globe ExternalLink +``` + +Si le nom de l'icône est inconnu, `ExternalLink` est utilisé par défaut. + +Si `iconUrl` est fourni, l'URL est prioritaire et `icon` sert uniquement de fallback. + +Des icônes pour les applications self-hostées sont disponibles sur [dashboardicons.com](https://dashboardicons.com/). + +Format CDN : `https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/.svg` + +## Exemple complet + +```yaml +site: + name: "Soch Family" + title: "Mes applis" + logoUrl: "https://example.com/logo.png" + showFooter: false + +theme: + mode: "dark" + accent: "#8b5cf6" + background: "gradient" + +sections: + - id: "services" + title: "Services" + cardLayout: "horizontal" + links: + - id: "nextcloud" + name: "Nextcloud" + url: "https://cloud.example.com" + icon: "Cloud" + iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/nextcloud.svg" + color: "#2daae1" + openInNewTab: true + + - id: "admin" + title: "Administration" + cardLayout: "vertical" + links: + - id: "mon-app" + name: "Mon App" + url: "https://app.example.com" + icon: "Globe" + iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/home-assistant.svg" + openInNewTab: false +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..00ab186 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +FROM node:20-alpine AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci --only=production + +FROM node:20-alpine AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci +COPY . . +RUN npm run build + +FROM node:20-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs && \ + adduser --system --uid 1001 nextjs + +COPY --from=build /app/public ./public +COPY --from=build /app/.next/standalone ./ +COPY --from=build /app/.next/static ./.next/static + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +USER nextjs + +CMD ["node", "server.js"] diff --git a/README.md b/README.md index e215bc4..cc8a171 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,71 @@ -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). +# Sochboard -## Getting Started +Dashboard familial pour les applications auto-hébergées. -First, run the development server: +## Démarrage rapide ```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev +docker compose up -d ``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +L'application est accessible sur http://localhost:3000. -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +## Configuration -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. +La configuration se fait via un fichier YAML monté dans le conteneur. -## Learn More +Par défaut : `config/dashboard.yml` -To learn more about Next.js, take a look at the following resources: +### Structure du fichier -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +```yaml +site: + name: "Soch Family" + title: "Les applications de la famille" + description: "Accès rapide à nos services" -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! +theme: + mode: "dark" + accent: "#8b5cf6" + background: "gradient" -## Deploy on Vercel +sections: + - id: "global" + title: "Global" + description: "Services accessibles à toute la famille" + links: + - id: "nextcloud" + name: "Nextcloud" + description: "Fichiers et documents" + url: "https://cloud.example.com" + icon: "Cloud" + color: "#2daae1" + openInNewTab: true +``` -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. +### Icônes disponibles -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. +Cloud, Film, Music, Gamepad2, Router, Server, House, BookOpen, Calendar, Mail, Shield, Settings, Globe, ExternalLink + +## Développement + +```bash +npm install +npm run dev +``` + +## Docker + +```bash +docker compose up -d +``` + +Modifiez `config/dashboard.yml` puis redémarrez le conteneur : + +```bash +docker compose restart +``` + +## Licence + +MIT diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..9ffa802 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,38 @@ +# Roadmap + +## iOS — Bouton thème non fonctionnel + +Le bouton de bascule thème clair/sombre ne répond pas au toucher sur Firefox iOS. + +**Pistes :** +- Contourner le système d'événements React (addEventListener natif) — essayé, sans effet +- Remplacer ` + + + {site.description && ( +

+ {site.description} +

+ )} + + ) +} diff --git a/src/components/dashboard/DashboardSection.tsx b/src/components/dashboard/DashboardSection.tsx new file mode 100644 index 0000000..f2d2678 --- /dev/null +++ b/src/components/dashboard/DashboardSection.tsx @@ -0,0 +1,43 @@ +import { ServiceCard } from "./ServiceCard" +import type { SectionConfig } from "@/types/config" + +interface DashboardSectionProps { + section: SectionConfig + sectionIndex?: number +} + +export function DashboardSection({ section, sectionIndex = 0 }: DashboardSectionProps) { + if (section.links.length === 0) { + return null + } + + return ( +
+
+

+ {section.title} +

+ {section.description && ( +

{section.description}

+ )} +
+
+ {section.links.map((link, index) => ( + + ))} +
+
+ ) +} diff --git a/src/components/dashboard/IconRenderer.tsx b/src/components/dashboard/IconRenderer.tsx new file mode 100644 index 0000000..0d5d08e --- /dev/null +++ b/src/components/dashboard/IconRenderer.tsx @@ -0,0 +1,45 @@ +import { + Cloud, + Film, + Music, + Gamepad2, + Router, + Server, + House, + BookOpen, + Calendar, + Mail, + Shield, + Settings, + Globe, + ExternalLink, + type LucideIcon, +} from "lucide-react" + +const iconMap: Record = { + Cloud, + Film, + Music, + Gamepad2, + Router, + Server, + House, + BookOpen, + Calendar, + Mail, + Shield, + Settings, + Globe, + ExternalLink, +} + +interface IconRendererProps { + name: string + className?: string + size?: number +} + +export function IconRenderer({ name, className, size = 24 }: IconRendererProps) { + const Icon = iconMap[name] || ExternalLink + return