This commit is contained in:
ct
2025-07-15 04:28:51 +08:00
parent 66511e2b01
commit 369d5b22b4
5 changed files with 8 additions and 6 deletions

View File

@@ -0,0 +1,102 @@
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
import { ExternalLinkIcon } from '@radix-ui/react-icons';
const FAQDiscord = () => {
const faqData = [
{
q: 'How can I create a meme video?',
a: 'Use the video editor on top to start making your meme!<br><br>Edit your caption, background and meme. Once satisfied, press the Export button to download your video!',
},
{
q: 'Why is video export slow for me?',
a: "Video processing happens entirely in your browser using advanced web technology.<br><br> Export speed depends on your video content complexity and device performance. High-end devices export quickly, while older/slower devices may take longer or even crash. <br><br>If your phone is too slow, it's probably a potato. Try using a faster device like a desktop computer for better performance.",
},
{
q: 'What is a potato device?',
a: `Potato devices are old, dated computers, laptops, phones or tablets with little RAM and CPU power - typically devices from before ${new Date().getFullYear() - 6} (pre-${new Date().getFullYear() - 6}).<br><br>These devices are usually too weak for the modern web and may not work properly with our video editor, or may crash during video processing.`,
},
{
q: 'What video format do you export?',
a: 'We export high-quality MP4 videos optimized for all social media platforms in 9:16 format.<br><br>This is compatible for TikTok, Youtube Shorts, Instagram Reels, and more.',
},
{
q: 'Is there a mobile app?',
a: "Our web app is fully responsive and works perfectly on mobile devices.<br><br>Do you want a mobile app? We'll see what can be done. Let us know in our Discord group.",
},
{
q: 'How often do you add new content?',
a: 'We just started building this platform and will gradually add more meme templates and backgrounds over time, so everyone can continue using it for free with fresh content!<br><br>Want a certain content? Let us know in our Discord group.',
},
{
q: 'I found a bug!',
a: "Great, report it into the Discord group and we'll fix it as soon as possible!",
},
{
q: 'I have more questions!',
a: 'Great! Join our Discord group and ask away!',
},
];
return (
<section className="">
<div className="mx-auto max-w-6xl space-y-10 px-4 sm:px-6 lg:px-8">
<div className="text-center">
<h2 className="text-foreground mb-4 text-3xl font-bold sm:text-4xl lg:text-5xl">Want to know more?</h2>
</div>
<div className="grid gap-6 md:flex">
<div
id="faq"
className="max-w-4xl flex-3/5 rounded-2xl border bg-gradient-to-br from-transparent to-purple-500/5 p-6 sm:p-8 dark:to-purple-300/10"
>
<Accordion type="single" collapsible className="w-full" defaultValue="item-1">
{faqData.map((faq, index) => (
<AccordionItem key={index} value={`item-${index + 1}`} className="border-b last:border-b-0">
<AccordionTrigger className="py-4 text-left font-medium hover:no-underline">{faq.q}</AccordionTrigger>
<AccordionContent className="text-muted-foreground pb-4 leading-relaxed text-balance">
<div dangerouslySetInnerHTML={{ __html: faq.a }} />
</AccordionContent>
</AccordionItem>
))}
</Accordion>
</div>
<div id="discord" className="flex flex-2/5 flex-col justify-center space-y-6">
<div className="flex items-center gap-4">
<div
id="discord-logo"
className="flex h-16 w-16 flex-shrink-0 items-center justify-center rounded-full bg-[#5865F2] shadow-lg"
>
<svg className="h-8 w-8 text-white" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.211.375-.445.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z" />
</svg>
</div>
<div className="text-left">
<h3 className="text-foreground text-2xl font-bold">MEMEFAST Discord</h3>
<p className="text-muted-foreground text-sm leading-relaxed text-wrap">
Join our Discord community to connect with other creators, get help, stay up to date and help shape the future of
MEMEFAST.
</p>
</div>
</div>
{import.meta.env.VITE_DISCORD_LINK && (
<a
href={import.meta.env.VITE_DISCORD_LINK}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center gap-2 rounded-full bg-[#5865F2] px-8 py-3 text-lg font-semibold text-white shadow-lg transition-all hover:bg-[#4752C4] hover:shadow-xl focus:ring-2 focus:ring-[#5865F2] focus:ring-offset-2 focus:outline-none"
>
Join Discord
<ExternalLinkIcon className="h-5 w-5" />
</a>
)}
</div>
</div>
</div>
</section>
);
};
export default FAQDiscord;

View File

@@ -0,0 +1,75 @@
import { Download, Heart, Library, Smartphone, Video } from 'lucide-react';
const Features = () => {
const features = [
{
icon: Video,
title: 'No installation needed',
description: 'Easy video editor with editable text, background, memes, built into the web.',
gradient: 'bg-gradient-to-br from-transparent to-blue-500/5 dark:to-blue-400/10 hover:bg-gradient-to-tl',
order: 3,
},
{
icon: Heart,
title: 'Built-in over 200+ memes, for now',
description: 'Access meme and background with our editor without paying a cent.',
gradient: 'bg-gradient-to-br from-transparent to-pink-500/5 dark:to-pink-400/10 hover:bg-gradient-to-tl',
order: 1,
},
{
icon: Download,
title: 'Export in minutes',
description: 'Download high-quality 720p MP4 videos optimized for TikTok, Youtube Shorts, Instagram Reels, and more.',
gradient: 'bg-gradient-to-br from-transparent to-green-500/5 dark:to-green-400/10 hover:bg-gradient-to-tl',
order: 2,
},
{
icon: Smartphone,
title: 'Works Everywhere',
description: 'Create on desktop, tablet, or mobile! Potato devices not recommended though.',
gradient: 'bg-gradient-to-br from-transparent to-purple-500/5 dark:to-purple-400/10 hover:bg-gradient-to-tl',
order: 4,
},
{
icon: Library,
title: 'Meme Library Updates',
description: 'Soon we will be adding more memes and backgrounds to the library!',
comingSoon: true,
gradient: 'bg-gradient-to-br from-transparent to-orange-500/5 dark:to-orange-400/10 hover:bg-gradient-to-tl',
order: 5,
},
];
return (
<section className="">
<div className="mx-auto max-w-6xl space-y-10 px-4 sm:px-6 lg:px-8">
<div className="flex flex-wrap justify-center gap-3 md:grid-cols-2 lg:grid-cols-3 lg:gap-4">
{features
.sort((a, b) => a.order - b.order)
.map((feature, index) => (
<div
key={index}
className={`group hover:bg-muted/50 relative h-auto min-h-[275px] w-[275px] rounded-2xl border p-6 shadow-lg ${feature.gradient} transition-all duration-300 lg:p-8`}
>
{feature.comingSoon && (
<div className="bg-foreground text-background absolute -top-2 -right-2 rounded-full px-2 py-1 text-xs font-medium">
Coming Soon!
</div>
)}
<div className="mb-4">
<feature.icon className="text-foreground h-8 w-8" />
</div>
<h3 className="text-foreground mb-2 text-xl font-semibold">{feature.title}</h3>
<p className="text-muted-foreground leading-relaxed">{feature.description}</p>
</div>
))}
</div>
</div>
</section>
);
};
export default Features;

View File

@@ -0,0 +1,59 @@
import { Switch } from '@/components/ui/switch';
import { useTheme } from '@/hooks/useTheme';
import { Moon, Sun } from 'lucide-react';
const Footer = () => {
const currentYear = new Date().getFullYear();
const { isDark, toggleTheme } = useTheme();
return (
<section className="pt-10">
<div className="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
<div className="border-t pt-8">
<div className="flex flex-col items-center justify-between space-y-4 sm:flex-row sm:space-y-0">
<div className="text-muted-foreground text-sm">© {currentYear} MEMEFAST. All rights reserved.</div>
<div className="text-muted-foreground text-sm">
Made by{' '}
<a href="https://x.com/charlestehio" target="_blank" rel="noopener noreferrer">
@charlestehio
</a>
</div>
<div className="flex flex-col items-center space-y-4 sm:flex-row sm:space-y-0 sm:space-x-6">
{/* Theme Toggle */}
<div className="flex items-center space-x-2">
<Sun className="text-muted-foreground h-4 w-4" />
<Switch id="dark-mode" checked={isDark} onCheckedChange={toggleTheme} />
<Moon className="text-muted-foreground h-4 w-4" />
</div>
{/* Navigation Links */}
<div className="flex space-x-6">
<a href="/" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Home
</a>
<a href="/terms" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Terms
</a>
<a href="/privacy" className="text-muted-foreground hover:text-foreground text-sm transition-colors">
Privacy
</a>
{import.meta.env.VITE_DISCORD_LINK && (
<a
href={import.meta.env.VITE_DISCORD_LINK}
target="_blank"
rel="noopener noreferrer"
className="text-muted-foreground hover:text-foreground text-sm transition-colors"
>
Discord
</a>
)}
</div>
</div>
</div>
</div>
</div>
</section>
);
};
export default Footer;

View File

@@ -0,0 +1,65 @@
import CountUp from '@/components/reactbits/CountUp/CountUp';
import { usePage } from '@inertiajs/react';
const Hero = () => {
const { stats } = usePage().props;
return (
<section className="from-muted/50 relative bg-gradient-to-b to-transparent dark:from-neutral-900 dark:to-transparent">
<div className="relative mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
<div className="space-y-4 text-center">
{/* Badge */}
<div className="bg-background/50 inline-flex items-center gap-2 rounded-full border px-3 py-1 text-sm backdrop-blur-sm">
<div className="h-2 w-2 rounded-full bg-green-500"></div>
<span className="text-muted-foreground">Instant meme videos No signup required</span>
</div>
{/* Main heading */}
<div className="space-y-0">
<h1 className="font-display text-6xl font-black tracking-tight sm:text-7xl lg:text-8xl">
<span className="text-foreground">MEME</span>
<span className="text-muted-foreground">FAST</span>
</h1>
<h2 className="text-muted-foreground mx-auto max-w-4xl text-xl leading-relaxed font-light sm:text-2xl lg:text-3xl">
Fast and simple meme video editor
</h2>
</div>
{/* Stats */}
<div className="flex flex-wrap justify-center gap-8 sm:gap-12">
<div className="text-center">
<CountUp
from={0}
to={stats?.meme_count || 200}
separator=","
direction="up"
duration={1}
className="text-foreground text-3xl font-bold sm:text-4xl"
postFix=""
/>{' '}
<div className="text-muted-foreground text-sm">Meme Templates</div>
</div>
<div className="text-center">
<CountUp
from={0}
to={stats?.background_count || 200}
separator=","
direction="up"
duration={1}
className="text-foreground text-3xl font-bold sm:text-4xl"
postFix=""
/>
<div className="text-muted-foreground text-sm">Backgrounds</div>
</div>
<div className="text-center">
<div className="text-foreground text-3xl font-bold sm:text-4xl">720p</div>
<div className="text-muted-foreground text-sm">Export</div>
</div>
</div>
</div>
</div>
</section>
);
};
export default Hero;