From 1a9bf7853e45f9893292b5d64992d0d57b9779ad Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Fri, 4 Apr 2025 21:59:56 +0200 Subject: [PATCH 1/3] feat: improve design (i guess) --- .vscode/settings.json | 3 +- package.json | 5 +- pnpm-lock.yaml | 80 +++++++++ postcss.config.mjs | 8 + .../home/container/section-container.tsx | 2 +- .../pages/home/dataflow/dataflow.tsx | 161 +++++++++++------- .../drag-and-drop/drag-and-drop-showcase.tsx | 34 ++-- .../pages/home/features/features.tsx | 20 +-- src/components/pages/home/hero/hero-cards.tsx | 9 +- src/components/pages/home/hero/hero-text.tsx | 44 +++++ src/components/pages/home/hero/hero.tsx | 51 +++--- .../pages/home/hero/widgets/stock-widget.tsx | 2 +- .../pages/home/review-list/review-list.tsx | 55 +++--- src/css/custom.css | 4 +- src/lib/utils.ts | 9 + src/pages/index.tsx | 7 +- tailwind.config.js | 33 +++- 17 files changed, 392 insertions(+), 135 deletions(-) create mode 100644 postcss.config.mjs create mode 100644 src/components/pages/home/hero/hero-text.tsx create mode 100644 src/lib/utils.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index c5a1b289..046e77f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,6 @@ "Radarr", "Readarr", "Sonarr" - ] + ], + "typescript.tsdk": "node_modules/typescript/lib" } \ No newline at end of file diff --git a/package.json b/package.json index c85af302..3f799af7 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "dayjs": "^1.11.13", "docusaurus-plugin-image-zoom": "^3.0.1", "leader-line-new": "^1.1.9", + "motion": "^12.6.2", "postcss": "^8.4.32", "prism-react-renderer": "^2.4.1", "random-word-slugs": "^0.1.7", @@ -40,6 +41,7 @@ "react-dom": "^19.0.0", "swagger-ui-react": "^5.19.0", "swiper": "^11.2.6", + "tailwind-merge": "^3.0.2", "tailwindcss": "^3.4.17" }, "devDependencies": { @@ -50,9 +52,9 @@ "@docusaurus/types": "^3.7.0", "@fec/remark-a11y-emoji": "^3.1.0", "@playwright/test": "^1.51.1", + "@tsconfig/docusaurus": "^2.0.3", "@types/react": "19.0.12", "@types/react-dom": "19.0.4", - "@tsconfig/docusaurus": "^2.0.3", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "cheerio": "1.0.0", @@ -60,6 +62,7 @@ "eslint-plugin-markdown": "^5.1.0", "eslint-plugin-unused-imports": "^4.1.4", "prettier": "^3.2.4", + "tailwindcss-motion": "^1.1.0", "typescript": "^5.8.2", "zod": "^3.24.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 926cb4c0..4c83b314 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ importers: leader-line-new: specifier: ^1.1.9 version: 1.1.9 + motion: + specifier: ^12.6.2 + version: 12.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) postcss: specifier: ^8.4.32 version: 8.4.32 @@ -71,6 +74,9 @@ importers: swiper: specifier: ^11.2.6 version: 11.2.6 + tailwind-merge: + specifier: ^3.0.2 + version: 3.0.2 tailwindcss: specifier: ^3.4.17 version: 3.4.17 @@ -126,6 +132,9 @@ importers: prettier: specifier: ^3.2.4 version: 3.2.4 + tailwindcss-motion: + specifier: ^1.1.0 + version: 1.1.0(tailwindcss@3.4.17) typescript: specifier: ^5.8.2 version: 5.8.2 @@ -4429,6 +4438,20 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + framer-motion@12.6.2: + resolution: {integrity: sha512-7LgPRlPs5aG8UxeZiMCMZz8firC53+2+9TnWV22tuSi38D3IFRxHRUqOREKckAkt6ztX+Dn6weLcatQilJTMcg==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -5584,6 +5607,26 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + motion-dom@12.6.1: + resolution: {integrity: sha512-8XVsriTUEVOepoIDgE/LDGdg7qaKXWdt+wQA/8z0p8YzJDLYL8gbimZ3YkCLlj7bB2i/4UBD/g+VO7y9ZY0zHQ==} + + motion-utils@12.5.0: + resolution: {integrity: sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==} + + motion@12.6.2: + resolution: {integrity: sha512-8OBjjuC59WuWHKmPzVWT5M0t5kDxtkfMfHF1M7Iey6F/nvd0AI15YlPnpGlcagW/eOfkdWDO90U/K5LF/k55Yw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -7379,6 +7422,14 @@ packages: resolution: {integrity: sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==} engines: {node: '>= 4.7.0'} + tailwind-merge@3.0.2: + resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} + + tailwindcss-motion@1.1.0: + resolution: {integrity: sha512-0lK6rA4+367ffJdi1TtB72GlMCxJi2TP/xRiHc6An5pZSlU6WfIHhSvLxpcGilGZfBrOqc2q4woH1DEP/lCNbQ==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -14226,6 +14277,15 @@ snapshots: fraction.js@4.3.7: {} + framer-motion@12.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + motion-dom: 12.6.1 + motion-utils: 12.5.0 + tslib: 2.6.3 + optionalDependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + fresh@0.5.2: {} fs-extra@11.2.0: @@ -15786,6 +15846,20 @@ snapshots: minipass@7.1.2: {} + motion-dom@12.6.1: + dependencies: + motion-utils: 12.5.0 + + motion-utils@12.5.0: {} + + motion@12.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + framer-motion: 12.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + tslib: 2.6.3 + optionalDependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + mri@1.2.0: {} mrmime@2.0.0: {} @@ -17981,6 +18055,12 @@ snapshots: swiper@11.2.6: {} + tailwind-merge@3.0.2: {} + + tailwindcss-motion@1.1.0(tailwindcss@3.4.17): + dependencies: + tailwindcss: 3.4.17 + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 00000000..0dc456ad --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +} + +export default config diff --git a/src/components/pages/home/container/section-container.tsx b/src/components/pages/home/container/section-container.tsx index c59eafb4..d10bd1ff 100644 --- a/src/components/pages/home/container/section-container.tsx +++ b/src/components/pages/home/container/section-container.tsx @@ -7,5 +7,5 @@ interface SectionContainerProps { export const SectionContainer = ({ children, className }: SectionContainerProps) => { return
{children}
; + className={`container mx-auto px-4 sm:px-6 md:px-8 lg:px-12 max-w-[90rem] w-full py-8 ${className || ''}`}>{children}; }; \ No newline at end of file diff --git a/src/components/pages/home/dataflow/dataflow.tsx b/src/components/pages/home/dataflow/dataflow.tsx index 7189da68..21cae587 100644 --- a/src/components/pages/home/dataflow/dataflow.tsx +++ b/src/components/pages/home/dataflow/dataflow.tsx @@ -3,71 +3,117 @@ import React, { useRef } from 'react'; import LeaderLine, { SocketType } from 'leader-line-new'; export const DataflowVisualizationComponent = () => { - const homarrRef = useRef(); - const sonarrRef = useRef(); - const lidarrRef = useRef(); - const radarrRef = useRef(); - const jellyfinRef = useRef(); - const plexRef = useRef(); - const sabnzbdRef = useRef(); + const homarrRef = useRef(null); + const sonarrRef = useRef(null); + const lidarrRef = useRef(null); + const radarrRef = useRef(null); + const jellyfinRef = useRef(null); + const plexRef = useRef(null); + const sabnzbdRef = useRef(null); + + const items = [ + { + ref: radarrRef, + className: 'absolute left-0 top-0', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/radarr.png?raw=true', + alt: 'Radarr', + socket: 'right', + x: 0, + }, + { + ref: sonarrRef, + className: 'absolute left-0 top-1/2 -translate-y-1/2', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/sonarr.png?raw=true', + alt: 'Sonarr', + socket: 'right', + x: 0, + }, + { + ref: lidarrRef, + className: 'absolute left-0 bottom-0', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/lidarr.png?raw=true', + alt: 'Lidarr', + socket: 'right', + x: 0, + }, + { + ref: jellyfinRef, + className: 'absolute right-0 top-1/2 -translate-y-1/2', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/jellyfin.png?raw=true', + alt: 'Jellyfin', + socket: 'left', + x: 100, + }, + { + ref: plexRef, + className: 'absolute right-0 bottom-0', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/plex.png?raw=true', + alt: 'Plex', + socket: 'left', + x: 100, + }, + { + ref: sabnzbdRef, + className: 'absolute right-0 top-0', + src: 'https://github.com/walkxcode/dashboard-icons/blob/main/png/sabnzbd.png?raw=true', + alt: 'Sabnzbd', + socket: 'left', + x: 100, + }, + ]; return (
-

No YAML configurations.
Easy and - quick to manage integrations.

- +

+ No YAML configurations. +
+ Easy and quick to manage integrations. +

- {'Homarr - - {'Radarr'} - {'Sonarr'} - {'Lidarr'} - - {'Jellyfin'} + {'Homarr - {'Plex'} - - {'Sabnzbd'} - - - - - - - + {items.map((item) => ( + + {item.alt} + + + ))}
); }; -export const LineTree = ({ start, end, startSocket, endSocket, x = 0 }: { - start: any, - end: any, - startSocket: SocketType, - endSocket: SocketType, - x?: number +export const LineTree = ({ + start, + end, + startSocket, + endSocket, + x = 0, +}: { + start: any; + end: any; + startSocket: SocketType; + endSocket: SocketType; + x?: number; }) => { const line = useRef(); let leaderLine: LeaderLine; @@ -85,7 +131,8 @@ export const LineTree = ({ start, end, startSocket, endSocket, x = 0 }: { dash: { animation: true, }, - }); + } + ); }; const timer = setInterval(() => { if (start.current) { @@ -111,4 +158,4 @@ export const LineTree = ({ start, end, startSocket, endSocket, x = 0 }: { }); return null; -}; \ No newline at end of file +}; diff --git a/src/components/pages/home/drag-and-drop/drag-and-drop-showcase.tsx b/src/components/pages/home/drag-and-drop/drag-and-drop-showcase.tsx index b534c343..cecdafac 100644 --- a/src/components/pages/home/drag-and-drop/drag-and-drop-showcase.tsx +++ b/src/components/pages/home/drag-and-drop/drag-and-drop-showcase.tsx @@ -1,21 +1,33 @@ -import videoLight from './showcase-light.mp4'; -import videoDark from './showcase-dark.mp4'; -import { IconClick } from '@tabler/icons-react'; -import { SectionContainer } from '@site/src/components/pages/home/container/section-container'; import { useColorMode } from '@docusaurus/theme-common'; +import { SectionContainer } from '@site/src/components/pages/home/container/section-container'; +import { IconClick } from '@tabler/icons-react'; +import videoDark from './showcase-dark.mp4'; +import videoLight from './showcase-light.mp4'; export const DragAndDropShowcase = () => { const { colorMode } = useColorMode(); const video = colorMode === 'dark' ? videoDark : videoLight; return ( -
- -

Easy setup using drag and drop

-