From c146b15dd1be30757daf8eb57867f20d08c9af7f Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 17:14:52 +0330 Subject: [PATCH 1/7] feat: install the lanuch UI component library --- components.json | 21 ++++ package.json | 7 +- pnpm-lock.yaml | 55 +++++++++- src/app/globals.css | 131 ++++++++++++++++++++++-- src/components/ui/section.tsx | 20 ++++ src/lib/utils.ts | 6 ++ tailwind.config.ts | 187 ++++++++++++++++++++++++++++++++-- 7 files changed, 405 insertions(+), 22 deletions(-) create mode 100644 components.json create mode 100644 src/components/ui/section.tsx create mode 100644 src/lib/utils.ts diff --git a/components.json b/components.json new file mode 100644 index 0000000..a577707 --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/package.json b/package.json index d30ae75..196634a 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,14 @@ "lint": "next lint" }, "dependencies": { + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.474.0", "next": "15.1.6", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "tailwind-merge": "^2.6.0", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9086de3..dd74261 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,15 @@ importers: .: dependencies: + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + lucide-react: + specifier: ^0.474.0 + version: 0.474.0(react@19.0.0) next: specifier: 15.1.6 version: 15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -17,6 +26,12 @@ importers: react-dom: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) + tailwind-merge: + specifier: ^2.6.0 + version: 2.6.0 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) devDependencies: '@eslint/eslintrc': specifier: ^3 @@ -593,9 +608,16 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1205,6 +1227,11 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lucide-react@0.474.0: + resolution: {integrity: sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1687,6 +1714,14 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tailwind-merge@2.6.0: + resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -2349,8 +2384,14 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + client-only@0.0.1: {} + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2597,7 +2638,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.19.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: @@ -2619,7 +2660,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.19.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.19.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -3117,6 +3158,10 @@ snapshots: lru-cache@10.4.3: {} + lucide-react@0.474.0(react@19.0.0): + dependencies: + react: 19.0.0 + math-intrinsics@1.1.0: {} merge2@1.4.1: {} @@ -3608,6 +3653,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + tailwind-merge@2.6.0: {} + + tailwindcss-animate@1.0.7(tailwindcss@3.4.17): + dependencies: + tailwindcss: 3.4.17 + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 diff --git a/src/app/globals.css b/src/app/globals.css index 6b717ad..8975b27 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,20 +2,129 @@ @tailwind components; @tailwind utilities; -:root { - --background: #ffffff; - --foreground: #171717; +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 10% 3.9%; + --accent: 240 5% 64.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 72.22% 50.59%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.2% 33.9%; + --input: 240 5.9% 90%; + --ring: 240 5% 64.9%; + --radius: 0.5rem; + + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + + --brand: 27 96% 61%; + --brand-foreground: 31 97% 72%; + } + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 3.7% 15.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 0 0% 98%; + --accent: 0 0% 98%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + --border: 0 0% 98%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + + --brand: 31 97% 72%; + --brand-foreground: 27 96% 61%; + } } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; } } -body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; +@layer utilities { + .fade-x { + mask-image: linear-gradient( + to right, + transparent 0%, + black 25%, + black 75%, + transparent 100% + ); + } + + .fade-y { + mask-image: linear-gradient( + to top, + transparent 0%, + black 25%, + black 75%, + transparent 100% + ); + } + + .fade-top { + mask-image: linear-gradient(to bottom, transparent 0%, black 35%); + } + + .fade-bottom { + mask-image: linear-gradient(to top, transparent 0%, black 35%); + } + + .fade-top-lg { + mask-image: linear-gradient(to bottom, transparent 15%, black 100%); + } + + .fade-bottom-lg { + mask-image: linear-gradient(to top, transparent 15%, black 100%); + } + + .fade-left { + mask-image: linear-gradient(to right, transparent 0%, black 35%); + } + + .fade-right { + mask-image: linear-gradient(to left, transparent 0%, black 35%); + } + + .fade-left-lg { + mask-image: linear-gradient(to right, transparent 15%, black 100%); + } + + .fade-right-lg { + mask-image: linear-gradient(to left, transparent 15%, black 100%); + } } diff --git a/src/components/ui/section.tsx b/src/components/ui/section.tsx new file mode 100644 index 0000000..205dc51 --- /dev/null +++ b/src/components/ui/section.tsx @@ -0,0 +1,20 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Section = React.forwardRef< + HTMLElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +Section.displayName = "Section"; + +export { Section }; diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 109807b..c4f5f24 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,18 +1,189 @@ import type { Config } from "tailwindcss"; export default { - content: [ + darkMode: ["class"], + content: [ "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, + extend: { + colors: { + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + card: { + DEFAULT: 'hsl(var(--card) / 0.2)', + foreground: 'hsl(var(--card-foreground))' + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))' + }, + primary: { + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))' + }, + secondary: { + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))' + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground) / 0.6)' + }, + accent: { + DEFAULT: 'hsl(var(--accent) / 0.15)', + foreground: 'hsl(var(--accent-foreground))' + }, + destructive: { + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))' + }, + border: 'hsl(var(--border) / 0.1)', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + chart: { + '1': 'hsl(var(--chart-1))', + '2': 'hsl(var(--chart-2))', + '3': 'hsl(var(--chart-3))', + '4': 'hsl(var(--chart-4))', + '5': 'hsl(var(--chart-5))' + }, + brand: { + DEFAULT: 'hsl(var(--brand))', + foreground: 'hsl(var(--brand-foreground))' + } + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', + '2xl': 'calc(var(--radius) + 4px)', + xl: 'calc(var(--radius) + 2px)' + }, + fontFamily: { + code: [ + 'var(--font-mono)' + ], + regular: [ + 'var(--font-body)' + ] + }, + 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' + } + }, + marquee: { + from: { + transform: 'translateX(0)' + }, + to: { + transform: 'translateX(calc(-100% - var(--gap)))' + } + }, + appear: { + '0%': { + opacity: '0', + transform: 'translateY(1rem)', + filter: 'blur(.5rem)' + }, + '50%': { + filter: 'blur(0)' + }, + '100%': { + opacity: '1', + transform: 'translateY(0)', + filter: 'blur(0)' + } + }, + 'appear-zoom': { + '0%': { + opacity: '0', + transform: 'scale(.5)' + }, + '100%': { + opacity: '1', + transform: 'scale(1)' + } + }, + 'pulse-hover': { + '0%': { + opacity: '1', + transform: 'translateY(0)' + }, + '50%': { + opacity: '0.5', + transform: 'translateY(-1rem)' + }, + '100%': { + opacity: '1', + transform: 'translateY(0)' + } + }, + hover: { + '0%': { + transform: 'translateY(0) translateX(0)' + }, + '50%': { + transform: 'translateY(-1rem) translateX(1rem)' + }, + '100%': { + transform: 'translateY(0) translateX(0)' + } + }, + 'hover-reverse': { + '0%': { + transform: 'translateY(0) translateX(0)' + }, + '50%': { + transform: 'translateY(1rem) translateX(1rem)' + }, + '100%': { + transform: 'translateY(0) translateX(0)' + } + }, + 'pulse-fade': { + '0%': { + opacity: '1' + }, + '50%': { + opacity: '0.3' + }, + '100%': { + opacity: '1' + } + } + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out', + appear: 'appear 0.6s forwards ease-out', + 'appear-zoom': 'appear-zoom 0.6s forwards ease-out', + 'pulse-hover': 'pulse-hover 6s cubic-bezier(0.4, 0, 0.6, 1) infinite' + }, + spacing: { + container: '1280px' + }, + boxShadow: { + 'glow-sm': '0 0 16px 0 hsla(var(--foreground) / 0.08) inset', + 'glow-md': '0 0 32px 0 hsla(var(--foreground) / 0.08) inset', + 'glow-lg': '0 0 64px 0 hsla(var(--foreground) / 0.06) inset' + } + } }, - plugins: [], + plugins: [require("tailwindcss-animate")], } satisfies Config; From d10d59de403c62cdb9305ca9edc39f510c350b1b Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 17:17:45 +0330 Subject: [PATCH 2/7] feat: install the FAQ component from launch UI --- package.json | 2 + pnpm-lock.yaml | 272 ++++++++++++++++++++++++ src/components/sections/faq/default.tsx | 148 +++++++++++++ src/components/ui/accordion.tsx | 57 +++++ 4 files changed, 479 insertions(+) create mode 100644 src/components/sections/faq/default.tsx create mode 100644 src/components/ui/accordion.tsx diff --git a/package.json b/package.json index 196634a..8a440aa 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "lint": "next lint" }, "dependencies": { + "@radix-ui/react-accordion": "^1.2.2", + "@radix-ui/react-icons": "^1.3.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.474.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd74261..880ab03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@radix-ui/react-accordion': + specifier: ^1.2.2 + version: 1.2.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-icons': + specifier: ^1.3.2 + version: 1.3.2(react@19.0.0) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -364,6 +370,151 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@radix-ui/primitive@1.1.1': + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + + '@radix-ui/react-accordion@1.2.2': + resolution: {integrity: sha512-b1oh54x4DMCdGsB4/7ahiSrViXxaBwRPotiZNnYXjLha9vfuURSAZErki6qjDoSIV0eXx5v57XnTGVtGwnfp2g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.2': + resolution: {integrity: sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.1': + resolution: {integrity: sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.1': + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-icons@1.3.2': + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-presence@1.1.2': + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.1': + resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.1': + resolution: {integrity: sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -2094,6 +2245,127 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@radix-ui/primitive@1.1.1': {} + + '@radix-ui/react-accordion@1.2.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collapsible': 1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-collection': 1.1.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.8 + '@types/react-dom': 19.0.3(@types/react@19.0.8) + + '@radix-ui/react-collapsible@1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.8 + '@types/react-dom': 19.0.3(@types/react@19.0.8) + + '@radix-ui/react-collection@1.1.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@radix-ui/react-slot': 1.1.1(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.8 + '@types/react-dom': 19.0.3(@types/react@19.0.8) + + '@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.8)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-context@1.1.1(@types/react@19.0.8)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-direction@1.1.0(@types/react@19.0.8)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-icons@1.3.2(react@19.0.0)': + dependencies: + react: 19.0.0 + + '@radix-ui/react-id@1.1.0(@types/react@19.0.8)(react@19.0.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.8 + '@types/react-dom': 19.0.3(@types/react@19.0.8) + + '@radix-ui/react-primitive@2.0.1(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@radix-ui/react-slot': 1.1.1(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.8 + '@types/react-dom': 19.0.3(@types/react@19.0.8) + + '@radix-ui/react-slot@1.1.1(@types/react@19.0.8)(react@19.0.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.8)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.8)(react@19.0.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.8)(react@19.0.0) + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.8)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.8 + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.10.5': {} diff --git a/src/components/sections/faq/default.tsx b/src/components/sections/faq/default.tsx new file mode 100644 index 0000000..ed7082e --- /dev/null +++ b/src/components/sections/faq/default.tsx @@ -0,0 +1,148 @@ +import { Section } from "../../ui/section"; +import { + Accordion, + AccordionItem, + AccordionTrigger, + AccordionContent, +} from "../../ui/accordion"; +import Link from "next/link"; + +export default function FAQ() { + return ( +
+
+

+ Questions and Answers +

+ + + + Why building a great landing page is critical for your business? + + +

+ In today's AI-driven world, standing out is harder than + ever. While anyone can build a product, a professional landing + page makes the difference between success and failure. +

+

+ Launch UI helps you ship faster without compromising on quality. +

+
+
+ + + + Why use Launch UI instead of a no-code tool? + + +

+ No-code tools lock you into their ecosystem with recurring fees + and limited control. They often come with performance issues and + make it difficult to integrate with your product. +

+

+ You can't even change your hosting provider and basic + things like web analytics come as extra costs and paid add-ons. +

+

+ What might seem like a convenient solution today could paint you + into a corner tomorrow, limiting your ability to scale and + adapt. Launch UI gives you full control of your code while + maintaining professional quality. +

+
+
+ + + + How Launch UI is different from other components libraries and + templates? + + +

+ Launch UI stands out with premium design quality and delightful + touches of custom animations and illustrations. +

+

+ All components are carefully crafted to help position your + product as a professional tool, avoiding the generic template + look. +

+

+ Unlike many libraries that rely on outdated CSS practices and + old dependencies, Launch UI is built with modern technologies + and best practices in mind. +

+
+
+ + + + Why exactly does it mean that "The code is yours"? + + +

+ The basic version of Launch UI is open-source and free forever, + under a do-whatever-you-want license. +

+

+ The pro version that contains more components and options is a + one-time purchase that gives you lifetime access to all current + and future content. Use it for unlimited personal and commercial + projects - no recurring fees or restrictions. +

+

+ For complete details about licensing and usage rights, check out{" "} + + the pricing page + + . +

+
+
+ + + Are Figma files included? + +

+ Yes! The complete Launch UI template is available for free on + the{" "} + + Figma community + + . +

+
+
+ + + Can I get a discount? + +

+ Actually, yes! I'm looking for beta testers and great + examples of Launch UI in action to feature on the website. + Here's the deal: you provide feedback to help me improve + the product, and in return, you get a huge discount plus a solid + backlink for your product. +

+

+ If this interests you, don't hesitate to{" "} + + reach out by email + + . +

+
+
+
+
+
+ ); +} diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx new file mode 100644 index 0000000..c5efdca --- /dev/null +++ b/src/components/ui/accordion.tsx @@ -0,0 +1,57 @@ +"use client"; + +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDownIcon } from "@radix-ui/react-icons"; + +import { cn } from "@/lib/utils"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; From 11d0030b3a47d1c8579539713635fc737119862b Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 18:50:08 +0330 Subject: [PATCH 3/7] feat: Add theme provider and use it in main layout The themeProvider was used from the launch UI library template. I've also changed the lang of html to fa-IR and set the colorScheme to dark and className to dark --- src/app/layout.tsx | 7 +++--- src/components/contexts/theme-provider.tsx | 26 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 src/components/contexts/theme-provider.tsx diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f7fa87e..84db5fe 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ +import "./globals.css"; +import { ThemeProvider } from "@/components/contexts/theme-provider"; import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; -import "./globals.css"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -23,11 +24,11 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - {children} + {children} ); diff --git a/src/components/contexts/theme-provider.tsx b/src/components/contexts/theme-provider.tsx new file mode 100644 index 0000000..6e91ed1 --- /dev/null +++ b/src/components/contexts/theme-provider.tsx @@ -0,0 +1,26 @@ +"use client"; + +import { ThemeProvider as NextThemeProvider } from "next-themes"; +import { useEffect, useState } from "react"; + +export function ThemeProvider({ children }: { children: React.ReactNode }) { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) { + return <>{children}; + } + + return ( + + {children} + + ); +} From 59bbf8a5b591386612e6298e8069a8a6fe9bb493 Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 18:52:03 +0330 Subject: [PATCH 4/7] build: install next-themes --- package.json | 1 + pnpm-lock.yaml | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/package.json b/package.json index 8a440aa..3aaa110 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "clsx": "^2.1.1", "lucide-react": "^0.474.0", "next": "15.1.6", + "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", "tailwind-merge": "^2.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 880ab03..9aedf81 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: next: specifier: 15.1.6 version: 15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + next-themes: + specifier: ^0.4.4 + version: 0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react: specifier: ^19.0.0 version: 19.0.0 @@ -1423,6 +1426,12 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + next-themes@0.4.4: + resolution: {integrity: sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + next@15.1.6: resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} @@ -3467,6 +3476,11 @@ snapshots: natural-compare@1.4.0: {} + next-themes@0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + next@15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@next/env': 15.1.6 From 56e0555af7c3cbd0f3a533ddebde975cc1ac5a3d Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 18:52:59 +0330 Subject: [PATCH 5/7] feat: add a data.ts file for faq datas --- src/components/sections/faq/data.ts | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/components/sections/faq/data.ts diff --git a/src/components/sections/faq/data.ts b/src/components/sections/faq/data.ts new file mode 100644 index 0000000..f640008 --- /dev/null +++ b/src/components/sections/faq/data.ts @@ -0,0 +1,55 @@ + +export const accordionData = [ + { + id: "item-1", + trigger: "Why building a great landing page is critical for your business?", + content: [ + "In today\'s AI-driven world, standing out is harder than ever. While anyone can build a product, a professional landing page makes the difference between success and failure.", + "Launch UI helps you ship faster without compromising on quality." + ] + }, + { + id: "item-2", + trigger: "Why use Launch UI instead of a no-code tool?", + content: [ + "No-code tools lock you into their ecosystem with recurring fees and limited control. They often come with performance issues and make it difficult to integrate with your product.", + "You can\'t even change your hosting provider and basic things like web analytics come as extra costs and paid add-ons.", + "What might seem like a convenient solution today could paint you into a corner tomorrow, limiting your ability to scale and adapt. Launch UI gives you full control of your code while maintaining professional quality." + ] + }, + { + id: "item-3", + trigger: "How Launch UI is different from other components libraries and templates?", + content: [ + "Launch UI stands out with premium design quality and delightful touches of custom animations and illustrations.", + "All components are carefully crafted to help position your product as a professional tool, avoiding the generic template look.", + "Unlike many libraries that rely on outdated CSS practices and old dependencies, Launch UI is built with modern technologies and best practices in mind." + ] + }, + { + id: "item-4", + trigger: "Why exactly does it mean that \"The code is yours\"?", + content: [ + "The basic version of Launch UI is open-source and free forever, under a do-whatever-you-want license.", + "The pro version that contains more components and options is a one-time purchase that gives you lifetime access to all current and future content. Use it for unlimited personal and commercial projects - no recurring fees or restrictions.", + "For complete details about licensing and usage rights, check out the pricing page." + ] + }, + { + id: "item-5", + trigger: "Are Figma files included?", + content: [ + "Yes! The complete Launch UI template is available for free on the Figma community." + ] + }, + { + id: "item-6", + trigger: "Can I get a discount?", + content: [ + "Actually, yes! I\'m looking for beta testers and great examples of Launch UI in action to feature on the website. Here\'s the deal: you provide feedback to help me improve the product, and in return, you get a huge discount plus a solid backlink for your product.", + "If this interests you, don\'t hesitate to reach out by email." + ] + } +]; + +export default accordionData; From dda9d45430ed76c5c96bea6fcbdccd7eb1df3561 Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 18:53:35 +0330 Subject: [PATCH 6/7] refactor: change landing page related page.tsx I've changed the page.tsx and added the FAQ component --- src/app/page.tsx | 100 ++--------------------------------------------- 1 file changed, 4 insertions(+), 96 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 3eee014..555d969 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,101 +1,9 @@ -import Image from "next/image"; +import FAQ from "@/components/sections/faq/default"; export default function Home() { return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
- - -
- -
+ <> + + ); } From e4444ca87871e2c9ece19396fc4d449683072748 Mon Sep 17 00:00:00 2001 From: Majid Kargar Date: Mon, 27 Jan 2025 18:54:27 +0330 Subject: [PATCH 7/7] refactor: change the FAQ section to use the data.ts The data.ts file needs to be changed with real data --- src/components/sections/faq/default.tsx | 147 +++--------------------- 1 file changed, 18 insertions(+), 129 deletions(-) diff --git a/src/components/sections/faq/default.tsx b/src/components/sections/faq/default.tsx index ed7082e..5807762 100644 --- a/src/components/sections/faq/default.tsx +++ b/src/components/sections/faq/default.tsx @@ -1,146 +1,35 @@ -import { Section } from "../../ui/section"; import { Accordion, AccordionItem, AccordionTrigger, AccordionContent, } from "../../ui/accordion"; -import Link from "next/link"; +import { Section } from "../../ui/section"; +import accordionData from "./data"; export default function FAQ() { return (

- Questions and Answers + سوالات متداول

- - - Why building a great landing page is critical for your business? - - -

- In today's AI-driven world, standing out is harder than - ever. While anyone can build a product, a professional landing - page makes the difference between success and failure. -

-

- Launch UI helps you ship faster without compromising on quality. -

-
-
- - - - Why use Launch UI instead of a no-code tool? - - -

- No-code tools lock you into their ecosystem with recurring fees - and limited control. They often come with performance issues and - make it difficult to integrate with your product. -

-

- You can't even change your hosting provider and basic - things like web analytics come as extra costs and paid add-ons. -

-

- What might seem like a convenient solution today could paint you - into a corner tomorrow, limiting your ability to scale and - adapt. Launch UI gives you full control of your code while - maintaining professional quality. -

-
-
- - - - How Launch UI is different from other components libraries and - templates? - - -

- Launch UI stands out with premium design quality and delightful - touches of custom animations and illustrations. -

-

- All components are carefully crafted to help position your - product as a professional tool, avoiding the generic template - look. -

-

- Unlike many libraries that rely on outdated CSS practices and - old dependencies, Launch UI is built with modern technologies - and best practices in mind. -

-
-
- - - - Why exactly does it mean that "The code is yours"? - - -

- The basic version of Launch UI is open-source and free forever, - under a do-whatever-you-want license. -

-

- The pro version that contains more components and options is a - one-time purchase that gives you lifetime access to all current - and future content. Use it for unlimited personal and commercial - projects - no recurring fees or restrictions. -

-

- For complete details about licensing and usage rights, check out{" "} - - the pricing page - - . -

-
-
- - - Are Figma files included? - -

- Yes! The complete Launch UI template is available for free on - the{" "} - - Figma community - - . -

-
-
- - - Can I get a discount? - -

- Actually, yes! I'm looking for beta testers and great - examples of Launch UI in action to feature on the website. - Here's the deal: you provide feedback to help me improve - the product, and in return, you get a huge discount plus a solid - backlink for your product. -

-

- If this interests you, don't hesitate to{" "} - - reach out by email - - . -

-
-
+ {accordionData.map(({ id, trigger, content }) => ( + + {trigger} + + {content.map((paragraph, index) => ( +

+ {paragraph} +

+ ))} +
+
+ ))}