chore: format

This commit is contained in:
2025-10-10 16:43:21 +02:00
parent f0aabd63b6
commit 75c29e0ba4
551 changed files with 433948 additions and 94145 deletions

View File

@@ -1,13 +1,13 @@
import Script from "next/script"
import Script from "next/script";
export function Analytics() {
return (
<Script
id="plausible-script"
strategy="afterInteractive"
defer
data-domain="letterspace.app"
src="https://analytics.letterspace.app/js/script.js"
/>
)
return (
<Script
id="plausible-script"
strategy="afterInteractive"
defer
data-domain="letterspace.app"
src="https://analytics.letterspace.app/js/script.js"
/>
);
}

View File

@@ -1,115 +1,115 @@
"use client"
"use client";
import Link from "next/link"
import type { LucideIcon } from "lucide-react"
import Link from "next/link";
import type { LucideIcon } from "lucide-react";
import {
Zap,
Wifi,
Database,
MessageSquare,
FileCode,
Settings,
BugPlay,
ChevronDown,
} from "lucide-react"
import constants from "@/constants"
Zap,
Wifi,
Database,
MessageSquare,
FileCode,
Settings,
BugPlay,
ChevronDown,
} from "lucide-react";
import constants from "@/constants";
interface Feature {
icon: React.ReactElement<LucideIcon>
title: string
description: string
link?: {
text: string
url: string
}
icon: React.ReactElement<LucideIcon>;
title: string;
description: string;
link?: {
text: string;
url: string;
};
}
export const featuresData: Feature[] = [
{
icon: <Zap className="h-6 w-6 text-yellow-400" />,
title: "Zero-Config",
description: "Sensible built-in default configs for common use cases",
},
// {
// icon: <Code className="h-6 w-6 text-[#4ECDC4]" />,
// title: "Extensible",
// description:
// "Expose the full ability to customize the behavior of the platform",
// },
{
icon: <Wifi className="h-6 w-6 text-gray-300" />,
title: "SMTP Support",
description: "Connect any SMTP server to send emails to your subscribers",
},
{
icon: <Database className="h-6 w-6 text-[#4ECDC4]" />,
title: "Unlimited Lists",
description: "Create and manage as many newsletter lists as you need",
},
{
icon: <MessageSquare className="h-6 w-6 text-gray-300" />,
title: "Campaign Management",
description: "Built-in support for creating and scheduling email campaigns",
},
// {
// icon: <RefreshCw className="h-6 w-6 text-[#4ECDC4]" />,
// title: "Auto-scaling",
// description: "Automatically handle thousands of subscribers with ease",
// },
{
icon: <FileCode className="h-6 w-6 text-yellow-400" />,
title: "REST API",
description: "Comprehensive API for integrating with your applications",
link: {
text: "API Documentation",
url: constants.env.DOCS_URL + "/api",
},
},
{
icon: <Settings className="h-6 w-6 text-gray-300" />,
title: "Advanced Analytics",
description: "Track opens, clicks, and engagement for all your campaigns",
},
{
icon: <BugPlay className="h-6 w-6 text-[#4ECDC4]" />,
title: "Built by Developers",
description:
"For developers, by developers. Everything you need to build and test with ease.",
link: {
text: "Development Guide",
url: constants.env.DOCS_URL,
},
},
]
{
icon: <Zap className="h-6 w-6 text-yellow-400" />,
title: "Zero-Config",
description: "Sensible built-in default configs for common use cases",
},
// {
// icon: <Code className="h-6 w-6 text-[#4ECDC4]" />,
// title: "Extensible",
// description:
// "Expose the full ability to customize the behavior of the platform",
// },
{
icon: <Wifi className="h-6 w-6 text-gray-300" />,
title: "SMTP Support",
description: "Connect any SMTP server to send emails to your subscribers",
},
{
icon: <Database className="h-6 w-6 text-[#4ECDC4]" />,
title: "Unlimited Lists",
description: "Create and manage as many newsletter lists as you need",
},
{
icon: <MessageSquare className="h-6 w-6 text-gray-300" />,
title: "Campaign Management",
description: "Built-in support for creating and scheduling email campaigns",
},
// {
// icon: <RefreshCw className="h-6 w-6 text-[#4ECDC4]" />,
// title: "Auto-scaling",
// description: "Automatically handle thousands of subscribers with ease",
// },
{
icon: <FileCode className="h-6 w-6 text-yellow-400" />,
title: "REST API",
description: "Comprehensive API for integrating with your applications",
link: {
text: "API Documentation",
url: constants.env.DOCS_URL + "/api",
},
},
{
icon: <Settings className="h-6 w-6 text-gray-300" />,
title: "Advanced Analytics",
description: "Track opens, clicks, and engagement for all your campaigns",
},
{
icon: <BugPlay className="h-6 w-6 text-[#4ECDC4]" />,
title: "Built by Developers",
description:
"For developers, by developers. Everything you need to build and test with ease.",
link: {
text: "Development Guide",
url: constants.env.DOCS_URL,
},
},
];
export const Features = ({ features }: { features: Feature[] }) => (
<section className="container mx-auto px-4 py-16">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{features.map((feature, index) => (
<div
key={index}
className="relative group overflow-hidden bg-[#1a1a1a] p-6 rounded-lg border border-gray-800 transition-all duration-300 ease-in-out hover:shadow-lg hover:shadow-[#4ECDC4]/10
<section className="container mx-auto px-4 py-16">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{features.map((feature, index) => (
<div
key={index}
className="relative group overflow-hidden bg-[#1a1a1a] p-6 rounded-lg border border-gray-800 transition-all duration-300 ease-in-out hover:shadow-lg hover:shadow-[#4ECDC4]/10
before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_2s_infinite]
before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent"
>
<div className="relative z-10">
<div className="bg-[#252525] w-12 h-12 rounded-lg flex items-center justify-center mb-4">
{feature.icon}
</div>
<h3 className="text-xl font-bold mb-2">{feature.title}</h3>
<p className="text-gray-400">{feature.description}</p>
{feature.link && (
<Link
href={feature.link.url}
className="text-[#4ECDC4] hover:underline flex items-center gap-1 mt-4 text-sm"
>
{feature.link.text}{" "}
<ChevronDown className="h-4 w-4 rotate-270" />
</Link>
)}
</div>
</div>
))}
</div>
</section>
)
>
<div className="relative z-10">
<div className="bg-[#252525] w-12 h-12 rounded-lg flex items-center justify-center mb-4">
{feature.icon}
</div>
<h3 className="text-xl font-bold mb-2">{feature.title}</h3>
<p className="text-gray-400">{feature.description}</p>
{feature.link && (
<Link
href={feature.link.url}
className="text-[#4ECDC4] hover:underline flex items-center gap-1 mt-4 text-sm"
>
{feature.link.text}{" "}
<ChevronDown className="h-4 w-4 rotate-270" />
</Link>
)}
</div>
</div>
))}
</div>
</section>
);

View File

@@ -1,57 +1,57 @@
"use client"
"use client";
import Link from "next/link"
import { constants } from "@/constants"
import Image from "next/image"
import Link from "next/link";
import { constants } from "@/constants";
import Image from "next/image";
export const Footer = () => (
<footer className="border-t border-gray-800 py-8 mt-12">
<div className="container mx-auto px-4">
<div className="flex flex-col items-center justify-center gap-6">
<div className="flex items-center">
<span className="text-white font-bold">Letter</span>
<span className="text-primary font-bold">Space</span>
<span className="text-gray-400 text-sm ml-4">
©{new Date().getFullYear()} LetterSpace
</span>
</div>
<div className="flex gap-6">
<Link
href={constants.env.DOCS_URL}
className="text-gray-400 hover:text-white"
>
Documentation
</Link>
<Link
href={constants.env.GITHUB_URL}
className="text-gray-400 hover:text-white"
target="_blank"
>
GitHub
</Link>
<Link
href={constants.env.DOCS_URL + "/api"}
className="text-gray-400 hover:text-white"
>
API
</Link>
<Link
href={constants.env.X_URL}
className="text-gray-400 hover:text-white flex items-center gap-1.5"
target="_blank"
rel="noopener noreferrer"
>
<Image
src="/x.svg"
alt="X"
width={20}
height={20}
style={{ filter: "invert(1)" }}
/>
Built by dcodes
</Link>
</div>
</div>
</div>
</footer>
)
<footer className="border-t border-gray-800 py-8 mt-12">
<div className="container mx-auto px-4">
<div className="flex flex-col items-center justify-center gap-6">
<div className="flex items-center">
<span className="text-white font-bold">Letter</span>
<span className="text-primary font-bold">Space</span>
<span className="text-gray-400 text-sm ml-4">
©{new Date().getFullYear()} LetterSpace
</span>
</div>
<div className="flex gap-6">
<Link
href={constants.env.DOCS_URL}
className="text-gray-400 hover:text-white"
>
Documentation
</Link>
<Link
href={constants.env.GITHUB_URL}
className="text-gray-400 hover:text-white"
target="_blank"
>
GitHub
</Link>
<Link
href={constants.env.DOCS_URL + "/api"}
className="text-gray-400 hover:text-white"
>
API
</Link>
<Link
href={constants.env.X_URL}
className="text-gray-400 hover:text-white flex items-center gap-1.5"
target="_blank"
rel="noopener noreferrer"
>
<Image
src="/x.svg"
alt="X"
width={20}
height={20}
style={{ filter: "invert(1)" }}
/>
Built by dcodes
</Link>
</div>
</div>
</div>
</footer>
);

View File

@@ -1,47 +1,47 @@
"use client"
"use client";
import Link from "next/link"
import { Menu } from "lucide-react"
import { Button } from "@repo/ui"
import { constants } from "@/constants"
import Image from "next/image"
import Link from "next/link";
import { Menu } from "lucide-react";
import { Button } from "@repo/ui";
import { constants } from "@/constants";
import Image from "next/image";
export const Header = () => (
<header className="border-b border-gray-800">
<div className="container mx-auto px-4 py-3 flex items-center justify-between">
<div className="flex items-center gap-4">
<Link href="/" className="flex items-center font-bold text-xl">
<span className="text-white">Letter</span>
<span className="text-primary">Space</span>
</Link>
</div>
<header className="border-b border-gray-800">
<div className="container mx-auto px-4 py-3 flex items-center justify-between">
<div className="flex items-center gap-4">
<Link href="/" className="flex items-center font-bold text-xl">
<span className="text-white">Letter</span>
<span className="text-primary">Space</span>
</Link>
</div>
<nav className="hidden md:flex items-center gap-6">
<Link
href="#"
className="text-gray-300 hover:text-white flex items-center gap-1"
>
v{constants.version}
</Link>
<Link
href={constants.env.GITHUB_URL}
className="text-gray-300 hover:text-white"
target="_blank"
>
<Image
src="/github.svg"
alt="GitHub"
width={30}
height={30}
style={{ filter: "invert(1)" }}
/>
</Link>
</nav>
<nav className="hidden md:flex items-center gap-6">
<Link
href="#"
className="text-gray-300 hover:text-white flex items-center gap-1"
>
v{constants.version}
</Link>
<Link
href={constants.env.GITHUB_URL}
className="text-gray-300 hover:text-white"
target="_blank"
>
<Image
src="/github.svg"
alt="GitHub"
width={30}
height={30}
style={{ filter: "invert(1)" }}
/>
</Link>
</nav>
<Button variant="ghost" size="icon" className="md:hidden">
<span className="sr-only">Open menu</span>
<Menu className="h-6 w-6" />
</Button>
</div>
</header>
)
<Button variant="ghost" size="icon" className="md:hidden">
<span className="sr-only">Open menu</span>
<Menu className="h-6 w-6" />
</Button>
</div>
</header>
);

View File

@@ -1,118 +1,118 @@
"use client"
"use client";
import constants from "@/constants"
import { Button } from "@repo/ui"
import { Mail, Star, Zap } from "lucide-react"
import Link from "next/link"
import constants from "@/constants";
import { Button } from "@repo/ui";
import { Mail, Star, Zap } from "lucide-react";
import Link from "next/link";
export const Hero = () => (
<section className="container mx-auto px-4 py-16 md:py-24 flex flex-col md:flex-row items-center justify-between">
<div className="md:w-1/2 space-y-4">
<h2 className="text-3xl font-bold">
Letter<span className="text-primary">Space</span>
</h2>
<h1 className="text-5xl md:text-6xl font-bold text-white">
Open Source Email Platform
</h1>
<div className="space-y-2 max-w-xl">
<p className="text-gray-400 text-xl">
Connect any SMTP server and manage unlimited newsletters
</p>
<p className="text-gray-400 text-xl">
Zero-config and developer-friendly
</p>
<p className="text-gray-400 text-xl">LetterSpace for everyone</p>
</div>
<section className="container mx-auto px-4 py-16 md:py-24 flex flex-col md:flex-row items-center justify-between">
<div className="md:w-1/2 space-y-4">
<h2 className="text-3xl font-bold">
Letter<span className="text-primary">Space</span>
</h2>
<h1 className="text-5xl md:text-6xl font-bold text-white">
Open Source Email Platform
</h1>
<div className="space-y-2 max-w-xl">
<p className="text-gray-400 text-xl">
Connect any SMTP server and manage unlimited newsletters
</p>
<p className="text-gray-400 text-xl">
Zero-config and developer-friendly
</p>
<p className="text-gray-400 text-xl">LetterSpace for everyone</p>
</div>
<div className="flex gap-4 pt-4">
<Link href={constants.env.DOCS_URL}>
<Button className="bg-[#4ECDC4] hover:bg-[#3DBDB5] text-black font-medium px-6">
Get Started
</Button>
</Link>
<Link href={constants.env.GITHUB_URL}>
<Button
variant="outline"
className="border-gray-700 text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900"
>
View on GitHub
</Button>
</Link>
</div>
</div>
<div className="flex gap-4 pt-4">
<Link href={constants.env.DOCS_URL}>
<Button className="bg-[#4ECDC4] hover:bg-[#3DBDB5] text-black font-medium px-6">
Get Started
</Button>
</Link>
<Link href={constants.env.GITHUB_URL}>
<Button
variant="outline"
className="border-gray-700 text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900"
>
View on GitHub
</Button>
</Link>
</div>
</div>
<div className="md:w-1/2 flex justify-center mt-12 md:mt-0">
<div className="relative w-80 h-80">
{/* Space background with stars */}
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-[#1a1a1a] to-[#121212] overflow-hidden">
{/* Stars */}
<div className="absolute inset-0">
<div className="star star-1"></div>
<div className="star star-2"></div>
<div className="star star-3"></div>
<div className="star star-4"></div>
<div className="star star-5"></div>
<div className="star star-6"></div>
<div className="star star-7"></div>
<div className="star star-8"></div>
<div className="star star-9"></div>
<div className="star star-10"></div>
<div className="star star-11"></div>
<div className="star star-12"></div>
</div>
<div className="md:w-1/2 flex justify-center mt-12 md:mt-0">
<div className="relative w-80 h-80">
{/* Space background with stars */}
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-[#1a1a1a] to-[#121212] overflow-hidden">
{/* Stars */}
<div className="absolute inset-0">
<div className="star star-1"></div>
<div className="star star-2"></div>
<div className="star star-3"></div>
<div className="star star-4"></div>
<div className="star star-5"></div>
<div className="star star-6"></div>
<div className="star star-7"></div>
<div className="star star-8"></div>
<div className="star star-9"></div>
<div className="star star-10"></div>
<div className="star star-11"></div>
<div className="star star-12"></div>
</div>
{/* Animated nebula/galaxy effect */}
<div className="absolute inset-0 bg-gradient-to-br from-[#4ECDC4]/10 to-transparent blur-2xl animate-pulse"></div>
<div className="absolute inset-0 bg-gradient-to-tr from-yellow-400/5 to-transparent blur-3xl animate-pulse animation-delay-700"></div>
</div>
{/* Animated nebula/galaxy effect */}
<div className="absolute inset-0 bg-gradient-to-br from-[#4ECDC4]/10 to-transparent blur-2xl animate-pulse"></div>
<div className="absolute inset-0 bg-gradient-to-tr from-yellow-400/5 to-transparent blur-3xl animate-pulse animation-delay-700"></div>
</div>
{/* Floating envelope in space */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
{/* Envelope with 3D perspective */}
<div className="relative w-48 h-36 bg-gradient-to-br from-[#4ECDC4] to-[#2A9D94] rounded-lg shadow-lg transform rotate-6 animate-float-space perspective">
{/* Envelope flap */}
<div className="absolute top-0 left-0 w-full h-1/3 bg-gradient-to-b from-[#5DDED6] to-[#4ECDC4] rounded-t-lg envelope-flap"></div>
{/* Floating envelope in space */}
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
{/* Envelope with 3D perspective */}
<div className="relative w-48 h-36 bg-gradient-to-br from-[#4ECDC4] to-[#2A9D94] rounded-lg shadow-lg transform rotate-6 animate-float-space perspective">
{/* Envelope flap */}
<div className="absolute top-0 left-0 w-full h-1/3 bg-gradient-to-b from-[#5DDED6] to-[#4ECDC4] rounded-t-lg envelope-flap"></div>
{/* Envelope body */}
<div className="absolute bottom-0 left-0 w-full h-2/3 bg-[#4ECDC4] rounded-b-lg border-t border-white/20"></div>
{/* Envelope body */}
<div className="absolute bottom-0 left-0 w-full h-2/3 bg-[#4ECDC4] rounded-b-lg border-t border-white/20"></div>
{/* Letter peeking out */}
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 w-5/6 h-3/4 bg-white rounded-sm shadow-inner transform -translate-y-2 letter">
<div className="w-full h-full p-2 flex flex-col justify-center">
<div className="w-full h-2 bg-gray-300 rounded-full mb-2"></div>
<div className="w-3/4 h-2 bg-gray-300 rounded-full mb-2"></div>
<div className="w-5/6 h-2 bg-gray-300 rounded-full"></div>
</div>
</div>
</div>
{/* Letter peeking out */}
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 w-5/6 h-3/4 bg-white rounded-sm shadow-inner transform -translate-y-2 letter">
<div className="w-full h-full p-2 flex flex-col justify-center">
<div className="w-full h-2 bg-gray-300 rounded-full mb-2"></div>
<div className="w-3/4 h-2 bg-gray-300 rounded-full mb-2"></div>
<div className="w-5/6 h-2 bg-gray-300 rounded-full"></div>
</div>
</div>
</div>
{/* Orbiting elements */}
<div className="absolute w-full h-full animate-orbit">
<div className="absolute -right-4 -top-8">
<Star className="h-6 w-6 text-yellow-400 animate-twinkle" />
</div>
</div>
{/* Orbiting elements */}
<div className="absolute w-full h-full animate-orbit">
<div className="absolute -right-4 -top-8">
<Star className="h-6 w-6 text-yellow-400 animate-twinkle" />
</div>
</div>
<div className="absolute w-full h-full animate-orbit-reverse">
<div className="absolute -left-8 top-0">
<Mail className="h-8 w-8 text-[#4ECDC4] animate-pulse" />
</div>
</div>
<div className="absolute w-full h-full animate-orbit-reverse">
<div className="absolute -left-8 top-0">
<Mail className="h-8 w-8 text-[#4ECDC4] animate-pulse" />
</div>
</div>
<div className="absolute w-full h-full animate-orbit-slow">
<div className="absolute right-0 bottom-0">
<Zap className="h-10 w-10 text-yellow-400 filter drop-shadow-lg" />
</div>
</div>
</div>
<div className="absolute w-full h-full animate-orbit-slow">
<div className="absolute right-0 bottom-0">
<Zap className="h-10 w-10 text-yellow-400 filter drop-shadow-lg" />
</div>
</div>
</div>
{/* Floating particles */}
<div className="particle particle-1"></div>
<div className="particle particle-2"></div>
<div className="particle particle-3"></div>
<div className="particle particle-4"></div>
<div className="particle particle-5"></div>
</div>
</div>
</section>
)
{/* Floating particles */}
<div className="particle particle-1"></div>
<div className="particle particle-2"></div>
<div className="particle particle-3"></div>
<div className="particle particle-4"></div>
<div className="particle particle-5"></div>
</div>
</div>
</section>
);