diff --git a/commit/commit/doctype/commit_docs/commit_docs.json b/commit/commit/doctype/commit_docs/commit_docs.json index 8a3bdd8..4bb7f43 100644 --- a/commit/commit/doctype/commit_docs/commit_docs.json +++ b/commit/commit/doctype/commit_docs/commit_docs.json @@ -10,6 +10,7 @@ "route", "published", "company_name", + "description", "section_break_camv", "sidebar", "logo_section", @@ -160,11 +161,16 @@ "fieldname": "company_name", "fieldtype": "Data", "label": "Company Name" + }, + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-11-09 12:53:12.416589", + "modified": "2024-12-07 22:34:40.239467", "modified_by": "Administrator", "module": "commit", "name": "Commit Docs", diff --git a/dashboard/package.json b/dashboard/package.json index 956e378..4897ebf 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -42,6 +42,7 @@ "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-tooltip": "^1.0.6", + "@tailwindcss/typography": "^0.5.15", "@tanstack/react-table": "^8.9.3", "@uiw/react-md-editor": "^4.0.4", "cal-sans": "^1.0.1", diff --git a/dashboard/public/man_doodle.png b/dashboard/public/man_doodle.png new file mode 100644 index 0000000..058d74b Binary files /dev/null and b/dashboard/public/man_doodle.png differ diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index 56702d0..a48a712 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -2,6 +2,7 @@ import { FrappeProvider } from 'frappe-react-sdk' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { lazy, Suspense } from 'react' import { FullPageLoader } from './components/common/FullPageLoader/FullPageLoader' +import DocsLandingPage from './pages/features/docs/LandingPage/DocsLandingPage' const ERDViewer = lazy(async () => import('./pages/features/erd/ERDViewer')) const Overview = lazy(async () => import('./pages/overview/Overview')) @@ -43,6 +44,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/dashboard/src/components/features/api_viewer/APIDetails.tsx b/dashboard/src/components/features/api_viewer/APIDetails.tsx index 49825b1..617c424 100644 --- a/dashboard/src/components/features/api_viewer/APIDetails.tsx +++ b/dashboard/src/components/features/api_viewer/APIDetails.tsx @@ -84,7 +84,7 @@ const APIDetails = ({ project_branch, endpointData, selectedEndpoint, setSelecte
Endpoint :
-
{data?.api_path}
+
{data?.api_path}
{viewerType === 'app' && diff --git a/dashboard/src/index.css b/dashboard/src/index.css index ad472c1..51e370a 100644 --- a/dashboard/src/index.css +++ b/dashboard/src/index.css @@ -1,3 +1,5 @@ +@import url('https://fonts.googleapis.com/css2?family=Parkinsans:wght@300..800&display=swap'); + @tailwind base; @tailwind components; @tailwind utilities; diff --git a/dashboard/src/pages/features/docs/LandingPage/DocsLandingPage.tsx b/dashboard/src/pages/features/docs/LandingPage/DocsLandingPage.tsx new file mode 100644 index 0000000..6f88c38 --- /dev/null +++ b/dashboard/src/pages/features/docs/LandingPage/DocsLandingPage.tsx @@ -0,0 +1,56 @@ +import { ErrorBanner } from "@/components/common/ErrorBanner/ErrorBanner"; +import { CommitDocs } from "@/types/commit/CommitDocs"; +import { useFrappeGetDocList } from "frappe-react-sdk"; +import { FullPageLoader } from "@/components/common/FullPageLoader/FullPageLoader"; +import { ShootingStars } from "./ShootingStars"; +import HeroSection from "./HeroSection"; +import DocsList from "./DocsList"; + +const DocsLandingPage = () => { + const { data, error, isLoading } = useFrappeGetDocList( + "Commit Docs", + { + fields: ["header", "light_mode_logo", "route", "published", "description"], + } + ); + + if (error) { + return ; + } + + if (isLoading) { + return ; + } + if (data) { + return ( +
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ ); + } + + return null; +}; + +export default DocsLandingPage; diff --git a/dashboard/src/pages/features/docs/LandingPage/DocsList.tsx b/dashboard/src/pages/features/docs/LandingPage/DocsList.tsx new file mode 100644 index 0000000..f43ea73 --- /dev/null +++ b/dashboard/src/pages/features/docs/LandingPage/DocsList.tsx @@ -0,0 +1,59 @@ +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" +import { Button } from "@/components/ui/button"; +import { CommitDocs } from "@/types/commit/CommitDocs" +import { useMemo } from "react" +import { MdArrowOutward } from "react-icons/md"; +import { useNavigate } from "react-router-dom"; + +const DocsList = ({ data }: { data: CommitDocs[] }) => { + return ( +
+ {data.map((item, idx) => ( + + ))} +
+ ) +} + +export default DocsList + +const DocCard = ({ data }: { data: CommitDocs }) => { + + const appNameInitials = useMemo(() => { + return data.header[0].toUpperCase() + }, [data]) + + const navigate = useNavigate() + + return ( +
+
+
+ + + + {appNameInitials} + + +
+ {data.header} +
+ + + +
+ {data.published == 1 &&
+
+
} +
+
+ {data.description} +
+ +
+ ) +} \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/LandingPage/HeroSection.tsx b/dashboard/src/pages/features/docs/LandingPage/HeroSection.tsx new file mode 100644 index 0000000..db1d566 --- /dev/null +++ b/dashboard/src/pages/features/docs/LandingPage/HeroSection.tsx @@ -0,0 +1,34 @@ + +import ManDoodle from "../../../../../public/man_doodle.png" +import { Button } from "@/components/ui/button"; + +const HeroSection = () => { + return ( +
+
+
+
+ Documentation is now Lemon Sqeezy +
+
+ Meet Commit Docs, built with Frappe Framework, it is the modern standard for public-facing documentation. Beautiful out of the box, easy to maintain, and Open Source ✨. +
+
+ +
+
+
+ ManDoodle. +
+
+
+ ) +} + +export default HeroSection \ No newline at end of file diff --git a/dashboard/src/pages/features/docs/LandingPage/ShootingStars.tsx b/dashboard/src/pages/features/docs/LandingPage/ShootingStars.tsx new file mode 100644 index 0000000..18a6c8e --- /dev/null +++ b/dashboard/src/pages/features/docs/LandingPage/ShootingStars.tsx @@ -0,0 +1,154 @@ +import { cn } from "@/lib/utils"; +import React, { useEffect, useState, useRef } from "react"; + +interface ShootingStar { + id: number; + x: number; + y: number; + angle: number; + scale: number; + speed: number; + distance: number; +} + +interface ShootingStarsProps { + minSpeed?: number; + maxSpeed?: number; + minDelay?: number; + maxDelay?: number; + starColor?: string; + trailColor?: string; + starWidth?: number; + starHeight?: number; + className?: string; + maxStars?: number; +} + +const getRandomStartPoint = () => { + const side = Math.floor(Math.random() * 4); + const offset = Math.random() * window.innerWidth; + + switch (side) { + case 0: + return { x: offset, y: 0, angle: 45 }; + case 1: + return { x: window.innerWidth, y: offset, angle: 135 }; + case 2: + return { x: offset, y: window.innerHeight, angle: 225 }; + case 3: + return { x: 0, y: offset, angle: 315 }; + default: + return { x: 0, y: 0, angle: 45 }; + } +}; + +export const ShootingStars: React.FC = ({ + minSpeed = 10, + maxSpeed = 30, + minDelay = 1200, + maxDelay = 4200, + starColor = "#9E00FF", + trailColor = "#2EB9DF", + starWidth = 10, + starHeight = 1, + className, + maxStars = 5, // Maximum stars on the screen +}) => { + const [stars, setStars] = useState([]); + const svgRef = useRef(null); + + useEffect(() => { + const createStar = () => { + if (stars.length >= maxStars) return; // Ensure we don't exceed maxStars + + const { x, y, angle } = getRandomStartPoint(); + const newStar: ShootingStar = { + id: Date.now() + Math.random(), // Unique ID + x, + y, + angle, + scale: 1, + speed: Math.random() * (maxSpeed - minSpeed) + minSpeed, + distance: 0, + }; + + setStars((prevStars) => [...prevStars, newStar]); + + const randomDelay = Math.random() * (maxDelay - minDelay) + minDelay; + setTimeout(createStar, randomDelay); + }; + + const timeoutId = setTimeout(createStar, minDelay); + + return () => clearTimeout(timeoutId); + }, [stars.length, minSpeed, maxSpeed, minDelay, maxDelay, maxStars]); + + useEffect(() => { + const moveStars = () => { + setStars((prevStars) => + prevStars + .map((star) => { + const newX = + star.x + star.speed * Math.cos((star.angle * Math.PI) / 180); + const newY = + star.y + star.speed * Math.sin((star.angle * Math.PI) / 180); + const newDistance = star.distance + star.speed; + const newScale = 1 + newDistance / 100; + + // Remove stars that go out of bounds + if ( + newX < -50 || + newX > window.innerWidth + 50 || + newY < -50 || + newY > window.innerHeight + 50 + ) { + return null; + } + + return { + ...star, + x: newX, + y: newY, + distance: newDistance, + scale: newScale, + }; + }) + .filter((star) => star !== null) as ShootingStar[] // Remove null values + ); + + requestAnimationFrame(moveStars); + }; + + const animationFrame = requestAnimationFrame(moveStars); + return () => cancelAnimationFrame(animationFrame); + }, []); + + return ( + + {stars.map((star) => ( + + ))} + + + + + + + + ); +}; diff --git a/dashboard/src/types/commit/CommitDocs.ts b/dashboard/src/types/commit/CommitDocs.ts index cbc2466..a1bbd40 100644 --- a/dashboard/src/types/commit/CommitDocs.ts +++ b/dashboard/src/types/commit/CommitDocs.ts @@ -45,4 +45,5 @@ export interface CommitDocs{ telegram?: string /** Footer : Table - Commit Docs Footer Item */ footer?: CommitDocsFooterItem[] + description?: string } \ No newline at end of file diff --git a/dashboard/tailwind.config.js b/dashboard/tailwind.config.js index 0122a7d..9bdc4be 100644 --- a/dashboard/tailwind.config.js +++ b/dashboard/tailwind.config.js @@ -1,76 +1,82 @@ +import { keyframes } from "framer-motion"; + /** @type {import('tailwindcss').Config} */ -module.exports = { - darkMode: ["class"], - content: [ - './pages/**/*.{ts,tsx}', - './components/**/*.{ts,tsx}', - './app/**/*.{ts,tsx}', - './src/**/*.{ts,tsx}', - ], - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, +export const darkMode = ["class"]; +export const content = [ + "./pages/**/*.{ts,tsx}", + "./components/**/*.{ts,tsx}", + "./app/**/*.{ts,tsx}", + "./src/**/*.{ts,tsx}", +]; +export const theme = { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + fontFamily: { + title_font: ["Parkinsans", "sans-serif"], }, - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", }, - keyframes: { - "accordion-down": { - from: { height: 0 }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: 0 }, - }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", }, }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: 0 }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, }, - plugins: [require("tailwindcss-animate")], -} \ No newline at end of file +}; +export const plugins = [ + import("tailwindcss-animate"), + import("@tailwindcss/typography"), +]; diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock index f0041ad..a040d79 100644 --- a/dashboard/yarn.lock +++ b/dashboard/yarn.lock @@ -2659,6 +2659,16 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== +"@tailwindcss/typography@^0.5.15": + version "0.5.15" + resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.15.tgz#007ab9870c86082a1c76e5b3feda9392c7c8d648" + integrity sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA== + dependencies: + lodash.castarray "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + postcss-selector-parser "6.0.10" + "@tanstack/react-table@^8.9.3": version "8.20.5" resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.20.5.tgz#19987d101e1ea25ef5406dce4352cab3932449d8" @@ -4863,11 +4873,17 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" + integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -5946,10 +5962,18 @@ postcss-nested@^6.2.0: dependencies: postcss-selector-parser "^6.1.1" -postcss-selector-parser@^6.1.1, postcss-selector-parser@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" - integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== +postcss-selector-parser@6.0.10: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.11: + version "6.0.16" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz#3b88b9f5c5abd989ef4e2fc9ec8eedd34b20fb04" + integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -6814,8 +6838,16 @@ stdin-discarder@^0.1.0: dependencies: bl "^5.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6848,7 +6880,14 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==