Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f394bacf1 | ||
|
|
d4bd7f4e1a | ||
|
|
1b6b442078 | ||
|
|
f9191708f4 | ||
|
|
10da7d0a16 | ||
|
|
c07c75f23b | ||
|
|
e9622234fe | ||
|
|
aedc2b5dfb | ||
|
|
5b1b700ccb | ||
|
|
0478d12ffc |
@@ -0,0 +1,66 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Button } from '@imphnen-frontend-service/shadcn-ui/atoms';
|
||||||
|
import { motion, useInView } from 'framer-motion';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
export function CallToAction() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, amount: 0.2 });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="w-full py-20 md:py-32 relative overflow-hidden">
|
||||||
|
{/* Background Elements */}
|
||||||
|
<div className="absolute inset-0 -z-10">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-background to-primary/20" />
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(59,130,246,0.2),transparent_70%)]" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="container px-4 md:px-6" ref={ref}>
|
||||||
|
<motion.div
|
||||||
|
className="max-w-4xl mx-auto rounded-2xl overflow-hidden border shadow-lg"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<div className="relative p-8 md:p-12 lg:p-16 bg-background">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-blue-400/5" />
|
||||||
|
|
||||||
|
<div className="relative z-10 text-center">
|
||||||
|
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-6">
|
||||||
|
Siap Menjadi{' '}
|
||||||
|
<span className="bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
Programmer Handal?
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<p className="text-lg text-muted-foreground mb-8 max-w-2xl mx-auto">
|
||||||
|
Bergabunglah dengan komunitas IMPHNEN sekarang dan mulai
|
||||||
|
perjalanan programming mu dengan cara yang menyenangkan!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
className="bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90"
|
||||||
|
>
|
||||||
|
Gabung Discord
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="lg"
|
||||||
|
variant="outline"
|
||||||
|
className="border-primary hover:bg-primary/10"
|
||||||
|
>
|
||||||
|
Join Facebook Group
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decorative Elements */}
|
||||||
|
<div className="absolute -top-12 -left-12 w-24 h-24 rounded-full bg-primary/10 blur-2xl" />
|
||||||
|
<div className="absolute -bottom-12 -right-12 w-24 h-24 rounded-full bg-blue-400/10 blur-2xl" />
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
FacebookIcon,
|
||||||
|
InstagramIcon,
|
||||||
|
MessageCircleIcon,
|
||||||
|
} from '@imphnen-frontend-service/shadcn-ui/atoms';
|
||||||
|
import { motion, useInView } from 'framer-motion';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
export function Community() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, amount: 0.2 });
|
||||||
|
|
||||||
|
const communities = [
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<FacebookIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||||
|
),
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Facebook Group',
|
||||||
|
description:
|
||||||
|
'Bergabunglah dengan grup Facebook kami untuk diskusi santai dan berbagi artikel menarik.',
|
||||||
|
buttonText: 'Gabung Sekarang',
|
||||||
|
buttonLink: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<InstagramIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||||
|
),
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Instagram',
|
||||||
|
description:
|
||||||
|
'Ikuti kami di Instagram untuk tips programming, konten inspiratif, dan info event terbaru.',
|
||||||
|
buttonText: 'Follow Kami',
|
||||||
|
buttonLink: '#',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<MessageCircleIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||||
|
),
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Discord Server',
|
||||||
|
description:
|
||||||
|
'Diskusikan langsung dengan sesama programmer dan dapatkan bantuan langsung dari para ahli.',
|
||||||
|
buttonText: 'Join Server',
|
||||||
|
buttonLink: '#',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const containerVariants = {
|
||||||
|
hidden: { opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
staggerChildren: 0.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { y: 20, opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: { duration: 0.5 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
id="komunitas"
|
||||||
|
className="w-full py-20 md:py-32 bg-muted relative overflow-hidden"
|
||||||
|
>
|
||||||
|
{/* Background Elements */}
|
||||||
|
<div className="absolute inset-0 -z-10">
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(59,130,246,0.1),transparent_70%)]" />
|
||||||
|
<div className="absolute inset-0 bg-[linear-gradient(to_right,rgba(59,130,246,0.01)_1px,transparent_1px),linear-gradient(to_bottom,rgba(59,130,246,0.01)_1px,transparent_1px)] bg-[size:14px_14px]" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="container px-4 md:px-6" ref={ref}>
|
||||||
|
<div className="flex flex-col items-center justify-center space-y-4 text-center mb-16">
|
||||||
|
<motion.div
|
||||||
|
className="space-y-2"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<h2 className="text-3xl font-bold tracking-tighter md:text-4xl/tight lg:text-5xl">
|
||||||
|
Komunitas{' '}
|
||||||
|
<span className="bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
Kami
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<p className="max-w-[800px] mx-auto text-muted-foreground md:text-lg">
|
||||||
|
Bergabunglah dengan ribuan programmer Indonesia yang saling
|
||||||
|
membantu dan berbagi pengalaman.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="grid gap-8 md:grid-cols-3"
|
||||||
|
variants={containerVariants}
|
||||||
|
initial="hidden"
|
||||||
|
animate={isInView ? 'visible' : 'hidden'}
|
||||||
|
>
|
||||||
|
{communities.map((community, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
className="group relative overflow-hidden rounded-xl border bg-background p-6 transition-all hover:shadow-xl"
|
||||||
|
variants={itemVariants}
|
||||||
|
>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-blue-400/5 opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div
|
||||||
|
className={`mb-4 inline-flex h-12 w-12 items-center justify-center rounded-full ${community.iconBg}`}
|
||||||
|
>
|
||||||
|
{community.icon}
|
||||||
|
</div>
|
||||||
|
<h3 className="mb-2 text-xl font-bold">{community.title}</h3>
|
||||||
|
<p className="mb-6 text-muted-foreground">
|
||||||
|
{community.description}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className="w-full group-hover:bg-primary group-hover:text-primary-foreground transition-colors duration-300"
|
||||||
|
>
|
||||||
|
{community.buttonText}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute -bottom-1 -right-1 w-20 h-20 bg-gradient-to-tl from-primary/20 to-transparent rounded-tl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Community Stats */}
|
||||||
|
<motion.div
|
||||||
|
className="mt-20 grid grid-cols-2 md:grid-cols-4 gap-8 text-center"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.3 }}
|
||||||
|
>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
10K+
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">Member Aktif</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
50+
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">Event Bulanan</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
100+
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Mentor Profesional
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
5K+
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Diskusi Mingguan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="w-full border-t bg-background py-12 md:py-16">
|
||||||
|
<div className="container px-4 md:px-6">
|
||||||
|
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-4">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
IMPHNEN
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Ingin Menjadi Programmer Handal merupakan komunitas Programmer
|
||||||
|
Indonesia.
|
||||||
|
</p>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z" />
|
||||||
|
</svg>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z" />
|
||||||
|
</svg>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
|
||||||
|
</svg>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z" />
|
||||||
|
</svg>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="text-lg font-bold">Tautan Cepat</h3>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#fitur"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Fitur
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#komunitas"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Komunitas
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#sumber-belajar"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Sumber Belajar
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#testimoni"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Testimoni
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="text-lg font-bold">Sumber Belajar</h3>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Video Tutorial
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Artikel
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Tantangan Koding
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
>
|
||||||
|
Sharing Session
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="text-lg font-bold">Bahasa Pemrograman</h3>
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/10 dark:bg-blue-900/30 dark:text-blue-400 dark:ring-blue-400/20">
|
||||||
|
PHP
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-inset ring-yellow-600/10 dark:bg-yellow-900/30 dark:text-yellow-400 dark:ring-yellow-400/20">
|
||||||
|
JavaScript
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/10 dark:bg-green-900/30 dark:text-green-400 dark:ring-green-400/20">
|
||||||
|
Python
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/10 dark:bg-blue-900/30 dark:text-blue-400 dark:ring-blue-400/20">
|
||||||
|
C#
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/10 dark:bg-red-900/30 dark:text-red-400 dark:ring-red-400/20">
|
||||||
|
Java
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-cyan-50 px-2 py-1 text-xs font-medium text-cyan-700 ring-1 ring-inset ring-cyan-600/10 dark:bg-cyan-900/30 dark:text-cyan-400 dark:ring-cyan-400/20">
|
||||||
|
Go
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-600/10 dark:bg-orange-900/30 dark:text-orange-400 dark:ring-orange-400/20">
|
||||||
|
Rust
|
||||||
|
</span>
|
||||||
|
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/10 dark:bg-blue-900/30 dark:text-blue-400 dark:ring-blue-400/20">
|
||||||
|
HTML
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-6">
|
||||||
|
<h3 className="text-lg font-bold mb-2">Newsletter</h3>
|
||||||
|
<p className="text-sm text-muted-foreground mb-2">
|
||||||
|
Dapatkan update terbaru dari kami
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Email Anda"
|
||||||
|
className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
|
/>
|
||||||
|
<button className="inline-flex items-center justify-center rounded-md bg-primary px-3 py-1 text-sm font-medium text-primary-foreground shadow hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50">
|
||||||
|
Daftar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-8 border-t pt-8 text-center">
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
© {new Date().getFullYear()} IMPHNEN - Ingin Menjadi Programmer
|
||||||
|
Handal, Namun Enggan Ngoding. All rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import { cn } from '@imphnen-frontend-service/utils';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { SimpleThemeToggle } from './simple-theme-toggle';
|
||||||
|
|
||||||
export function Header() {
|
export function Header() {
|
||||||
const [isScrolled, setIsScrolled] = useState(false);
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
@@ -80,6 +81,7 @@ export function Header() {
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
|
<SimpleThemeToggle />
|
||||||
<Button className="hidden md:flex bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90 transition-all duration-300">
|
<Button className="hidden md:flex bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90 transition-all duration-300">
|
||||||
Gabung Discord
|
Gabung Discord
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BookOpenIcon,
|
||||||
|
Button,
|
||||||
|
CodeIcon,
|
||||||
|
Share2Icon,
|
||||||
|
VideoIcon,
|
||||||
|
} from '@imphnen-frontend-service/shadcn-ui/atoms';
|
||||||
|
import { motion, useInView } from 'framer-motion';
|
||||||
|
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
export function LearningResources() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, amount: 0.2 });
|
||||||
|
|
||||||
|
const resources = [
|
||||||
|
{
|
||||||
|
icon: <VideoIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />,
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Video Tutorial',
|
||||||
|
description:
|
||||||
|
'Belajar melalui tutorial video dari langkah awal hingga mahir.',
|
||||||
|
buttonText: 'Lihat Semua Video',
|
||||||
|
buttonLink: '#',
|
||||||
|
color: 'from-blue-500 to-blue-700',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<BookOpenIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||||
|
),
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Artikel & Tutorial',
|
||||||
|
description:
|
||||||
|
'Pelajari konsep programming melalui artikel yang disusun secara terstruktur.',
|
||||||
|
buttonText: 'Baca Artikel',
|
||||||
|
buttonLink: '#',
|
||||||
|
color: 'from-blue-500 to-blue-700',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <CodeIcon className="h-6 w-6 text-blue-600 dark:text-blue-400" />,
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Tantangan Koding',
|
||||||
|
description:
|
||||||
|
'Uji kemampuan koding kamu dengan tantangan yang menyenangkan dan menantang.',
|
||||||
|
buttonText: 'Mulai Tantangan',
|
||||||
|
buttonLink: '#',
|
||||||
|
color: 'from-blue-500 to-blue-700',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Share2Icon className="h-6 w-6 text-blue-600 dark:text-blue-400" />,
|
||||||
|
iconBg: 'bg-blue-100 dark:bg-blue-900',
|
||||||
|
title: 'Sharing Session',
|
||||||
|
description:
|
||||||
|
'Ikuti sesi berbagi pengalaman dari programmer berpengalaman dan belajar dari pengalaman mereka.',
|
||||||
|
buttonText: 'Jadwal Session',
|
||||||
|
buttonLink: '#',
|
||||||
|
color: 'from-blue-500 to-blue-700',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const containerVariants = {
|
||||||
|
hidden: { opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
staggerChildren: 0.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { y: 20, opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: { duration: 0.5 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
id="sumber-belajar"
|
||||||
|
className="w-full py-20 md:py-32 relative overflow-hidden"
|
||||||
|
>
|
||||||
|
{/* Background Elements */}
|
||||||
|
<div className="absolute inset-0 -z-10">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-b from-background via-background to-background" />
|
||||||
|
<div className="absolute top-0 right-0 w-1/2 h-1/2 bg-gradient-to-bl from-primary/5 to-transparent blur-3xl" />
|
||||||
|
<div className="absolute bottom-0 left-0 w-1/2 h-1/2 bg-gradient-to-tr from-blue-400/5 to-transparent blur-3xl" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="container px-4 md:px-6" ref={ref}>
|
||||||
|
<div className="flex flex-col items-center justify-center space-y-4 text-center mb-16">
|
||||||
|
<motion.div
|
||||||
|
className="space-y-2"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<h2 className="text-3xl font-bold tracking-tighter md:text-4xl/tight lg:text-5xl">
|
||||||
|
Sumber{' '}
|
||||||
|
<span className="bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
Belajar
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<p className="max-w-[800px] mx-auto text-muted-foreground md:text-lg">
|
||||||
|
Akses berbagai materi belajar yang akan membantu kamu menguasai
|
||||||
|
konsep programming dengan cara yang menyenangkan.
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="grid gap-8 md:grid-cols-2 lg:grid-cols-4"
|
||||||
|
variants={containerVariants}
|
||||||
|
initial="hidden"
|
||||||
|
animate={isInView ? 'visible' : 'hidden'}
|
||||||
|
>
|
||||||
|
{resources.map((resource, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
className="group relative overflow-hidden rounded-xl border bg-background p-6 transition-all hover:shadow-lg"
|
||||||
|
variants={itemVariants}
|
||||||
|
>
|
||||||
|
<div className="absolute top-0 left-0 h-1 w-full bg-gradient-to-r from-primary/50 to-blue-400/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div
|
||||||
|
className={`mb-4 inline-flex h-12 w-12 items-center justify-center rounded-full ${resource.iconBg}`}
|
||||||
|
>
|
||||||
|
{resource.icon}
|
||||||
|
</div>
|
||||||
|
<h3 className="mb-2 text-xl font-bold">{resource.title}</h3>
|
||||||
|
<p className="mb-6 text-muted-foreground">
|
||||||
|
{resource.description}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
className="p-0 h-auto font-medium text-primary hover:text-primary/80"
|
||||||
|
>
|
||||||
|
{resource.buttonText} →
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute -bottom-32 -right-32 w-64 h-64 bg-gradient-to-tl from-primary/10 to-transparent rounded-full opacity-0 group-hover:opacity-100 transition-all duration-500 group-hover:-translate-y-10 group-hover:-translate-x-10" />
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Featured Resource */}
|
||||||
|
<motion.div
|
||||||
|
className="mt-20 rounded-xl overflow-hidden border bg-background/50 backdrop-blur-sm"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.3 }}
|
||||||
|
>
|
||||||
|
<div className="grid md:grid-cols-2 gap-0">
|
||||||
|
<div className="p-8 md:p-12 flex flex-col justify-center">
|
||||||
|
<div className="inline-block rounded-full bg-primary/10 px-4 py-1.5 text-sm font-medium text-primary mb-4">
|
||||||
|
Rekomendasi Terbaik
|
||||||
|
</div>
|
||||||
|
<h3 className="text-2xl md:text-3xl font-bold mb-4">
|
||||||
|
Kursus Lengkap Web Development
|
||||||
|
</h3>
|
||||||
|
<p className="text-muted-foreground mb-6">
|
||||||
|
Pelajari HTML, CSS, JavaScript, React, dan Node.js dalam satu
|
||||||
|
kursus komprehensif yang dirancang untuk pemula hingga tingkat
|
||||||
|
menengah.
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-wrap gap-4">
|
||||||
|
<Button className="bg-gradient-to-r from-primary to-blue-400 hover:from-primary/90 hover:to-blue-400/90">
|
||||||
|
Mulai Kursus
|
||||||
|
</Button>
|
||||||
|
<Button variant="outline">Lihat Silabus</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="relative h-64 md:h-auto">
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/20 to-blue-400/20" />
|
||||||
|
<div className="absolute inset-0 flex items-center justify-center">
|
||||||
|
<div className="w-16 h-16 rounded-full bg-background/80 backdrop-blur-sm flex items-center justify-center cursor-pointer hover:bg-background transition-colors">
|
||||||
|
<div className="w-0 h-0 border-t-8 border-t-transparent border-l-12 border-l-primary border-b-8 border-b-transparent ml-1" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
MoonIcon,
|
||||||
|
SunIcon,
|
||||||
|
} from '@imphnen-frontend-service/shadcn-ui/atoms';
|
||||||
|
import { useTheme } from 'next-themes';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export function SimpleThemeToggle() {
|
||||||
|
const { theme, setTheme } = useTheme();
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
setTheme(theme === 'dark' ? 'light' : 'dark');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={toggleTheme}
|
||||||
|
className="focus-visible:ring-0"
|
||||||
|
>
|
||||||
|
{theme === 'dark' ? (
|
||||||
|
<SunIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||||
|
) : (
|
||||||
|
<MoonIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||||
|
)}
|
||||||
|
<span className="sr-only">Toggle theme</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { QuoteIcon } from '@imphnen-frontend-service/shadcn-ui/atoms';
|
||||||
|
import { motion, useInView } from 'framer-motion';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
export function Testimonials() {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const isInView = useInView(ref, { once: true, amount: 0.2 });
|
||||||
|
|
||||||
|
const testimonials = [
|
||||||
|
{
|
||||||
|
quote:
|
||||||
|
'Saya yang tadinya tidak mengerti apa-apa tentang programming, sekarang bisa membuat website sendiri dengan mudah. Terima kasih IMPHNEN!',
|
||||||
|
name: 'Budi Santoso',
|
||||||
|
role: 'Web Developer Pemula',
|
||||||
|
avatar: '/placeholder.svg?height=64&width=64',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quote:
|
||||||
|
'Komunitas yang sangat supportif! Setiap pertanyaan selalu dijawab dengan cepat dan jelas. Diskusi programnya mudah dipahami.',
|
||||||
|
name: 'Anita Ratna',
|
||||||
|
role: 'Mobile App Developer',
|
||||||
|
avatar: '/placeholder.svg?height=64&width=64',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quote:
|
||||||
|
'Server Discord IMPHNEN adalah tempat belajar terbaik untuk programmer pemula seperti saya. Materinya lengkap dan komunitasnya sangat membantu!',
|
||||||
|
name: 'Dedi Permana',
|
||||||
|
role: 'Data Scientist',
|
||||||
|
avatar: '/placeholder.svg?height=64&width=64',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const containerVariants = {
|
||||||
|
hidden: { opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
staggerChildren: 0.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { y: 20, opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: { duration: 0.5 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
id="testimoni"
|
||||||
|
className="w-full py-20 md:py-32 bg-muted relative overflow-hidden"
|
||||||
|
>
|
||||||
|
{/* Background Elements */}
|
||||||
|
<div className="absolute inset-0 -z-10">
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,rgba(59,130,246,0.1),transparent_50%)]" />
|
||||||
|
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_bottom,rgba(96,165,250,0.1),transparent_50%)]" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="container px-4 md:px-6" ref={ref}>
|
||||||
|
<div className="flex flex-col items-center justify-center space-y-4 text-center mb-16">
|
||||||
|
<motion.div
|
||||||
|
className="space-y-2"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<h2 className="text-3xl font-bold tracking-tighter md:text-4xl/tight lg:text-5xl">
|
||||||
|
Testimoni{' '}
|
||||||
|
<span className="bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
Member
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
<p className="max-w-[800px] mx-auto text-muted-foreground md:text-lg">
|
||||||
|
Apa kata mereka yang telah bergabung dengan komunitas IMPHNEN?
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="grid gap-8 md:grid-cols-3"
|
||||||
|
variants={containerVariants}
|
||||||
|
initial="hidden"
|
||||||
|
animate={isInView ? 'visible' : 'hidden'}
|
||||||
|
>
|
||||||
|
{testimonials.map((testimonial, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
className="group relative overflow-hidden rounded-xl border bg-background p-6 transition-all hover:shadow-lg"
|
||||||
|
variants={itemVariants}
|
||||||
|
>
|
||||||
|
<div className="absolute top-6 right-6 text-primary/20 group-hover:text-primary/40 transition-colors">
|
||||||
|
<QuoteIcon className="h-8 w-8" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<p className="mb-6 text-muted-foreground italic">
|
||||||
|
"{testimonial.quote}"
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="relative h-12 w-12 overflow-hidden rounded-full border-2 border-primary/20">
|
||||||
|
<Image
|
||||||
|
src={testimonial.avatar || '/placeholder.svg'}
|
||||||
|
alt={testimonial.name}
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
className="object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 className="font-bold">{testimonial.name}</h4>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{testimonial.role}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="absolute -bottom-1 -left-1 w-20 h-20 bg-gradient-to-tr from-primary/10 to-transparent rounded-tr-full opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Testimonial Stats */}
|
||||||
|
<motion.div
|
||||||
|
className="mt-20 rounded-xl overflow-hidden border bg-background/50 backdrop-blur-sm p-8 md:p-12"
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
||||||
|
transition={{ duration: 0.5, delay: 0.3 }}
|
||||||
|
>
|
||||||
|
<div className="grid md:grid-cols-2 gap-8 items-center">
|
||||||
|
<div>
|
||||||
|
<h3 className="text-2xl md:text-3xl font-bold mb-4">
|
||||||
|
Bergabunglah dengan{' '}
|
||||||
|
<span className="bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
10,000+
|
||||||
|
</span>{' '}
|
||||||
|
programmer Indonesia lainnya
|
||||||
|
</h3>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Komunitas kami terus berkembang dengan programmer dari berbagai
|
||||||
|
latar belakang dan tingkat keahlian. Bersama-sama, kita belajar,
|
||||||
|
berbagi, dan tumbuh sebagai profesional.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="rounded-lg border p-4 text-center">
|
||||||
|
<div className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
98%
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Tingkat Kemalasan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-lg border p-4 text-center">
|
||||||
|
<div className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
4.9/5
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Rating Drama
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-lg border p-4 text-center">
|
||||||
|
<div className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
85%
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Mendapat Pekerjaan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-lg border p-4 text-center">
|
||||||
|
<div className="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-400">
|
||||||
|
24/7
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-muted-foreground">Yapping</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import type { ThemeProviderProps } from 'next-themes';
|
||||||
|
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
||||||
|
|
||||||
|
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||||
|
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { type Metadata } from 'next';
|
import { type Metadata } from 'next';
|
||||||
import { Inter } from 'next/font/google';
|
import { Inter } from 'next/font/google';
|
||||||
import '../styles/globals.css';
|
import '../styles/globals.css';
|
||||||
|
import { ThemeProvider } from './_components/theme-provider';
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] });
|
const inter = Inter({ subsets: ['latin'] });
|
||||||
|
|
||||||
@@ -16,7 +17,16 @@ export default function RootLayout({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="id" suppressHydrationWarning>
|
<html lang="id" suppressHydrationWarning>
|
||||||
<body className={inter.className}>{children}</body>
|
<body className={inter.className}>
|
||||||
|
<ThemeProvider
|
||||||
|
attribute="class"
|
||||||
|
defaultTheme="system"
|
||||||
|
enableSystem
|
||||||
|
disableTransitionOnChange
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
import { CallToAction } from './_components/call-to-action';
|
||||||
|
import { Community } from './_components/community';
|
||||||
import { Features } from './_components/features';
|
import { Features } from './_components/features';
|
||||||
|
import Footer from './_components/footer';
|
||||||
import { Header } from './_components/header';
|
import { Header } from './_components/header';
|
||||||
import { Hero } from './_components/hero';
|
import { Hero } from './_components/hero';
|
||||||
|
import { LearningResources } from './_components/learning-resources';
|
||||||
|
import { Testimonials } from './_components/testimonials';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
@@ -9,7 +14,12 @@ export default function Page() {
|
|||||||
<main className="flex-1">
|
<main className="flex-1">
|
||||||
<Hero />
|
<Hero />
|
||||||
<Features />
|
<Features />
|
||||||
|
<Community />
|
||||||
|
<LearningResources />
|
||||||
|
<Testimonials />
|
||||||
|
<CallToAction />
|
||||||
</main>
|
</main>
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,18 @@ import {
|
|||||||
LuArrowDown as ArrowDownIcon,
|
LuArrowDown as ArrowDownIcon,
|
||||||
LuBookOpen as BookOpenIcon,
|
LuBookOpen as BookOpenIcon,
|
||||||
LuCode as CodeIcon,
|
LuCode as CodeIcon,
|
||||||
|
LuFacebook as FacebookIcon,
|
||||||
|
LuInstagram as InstagramIcon,
|
||||||
LuLaptop as LaptopIcon,
|
LuLaptop as LaptopIcon,
|
||||||
LuMenu as MenuIcon,
|
LuMenu as MenuIcon,
|
||||||
|
LuMessageCircle as MessageCircleIcon,
|
||||||
|
LuMoon as MoonIcon,
|
||||||
|
LuQuote as QuoteIcon,
|
||||||
|
LuShare2 as Share2Icon,
|
||||||
LuSparkles as SparklesIcon,
|
LuSparkles as SparklesIcon,
|
||||||
|
LuSun as SunIcon,
|
||||||
LuUsers as UsersIcon,
|
LuUsers as UsersIcon,
|
||||||
|
LuVideo as VideoIcon,
|
||||||
LuX as XIcon,
|
LuX as XIcon,
|
||||||
} from 'react-icons/lu';
|
} from 'react-icons/lu';
|
||||||
|
|
||||||
@@ -13,9 +21,17 @@ export {
|
|||||||
ArrowDownIcon,
|
ArrowDownIcon,
|
||||||
BookOpenIcon,
|
BookOpenIcon,
|
||||||
CodeIcon,
|
CodeIcon,
|
||||||
|
FacebookIcon,
|
||||||
|
InstagramIcon,
|
||||||
LaptopIcon,
|
LaptopIcon,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
|
MessageCircleIcon,
|
||||||
|
MoonIcon,
|
||||||
|
QuoteIcon,
|
||||||
|
Share2Icon,
|
||||||
SparklesIcon,
|
SparklesIcon,
|
||||||
|
SunIcon,
|
||||||
UsersIcon,
|
UsersIcon,
|
||||||
|
VideoIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './atoms/index';
|
||||||
Generated
+81
-2
@@ -11,17 +11,21 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^6.0.0",
|
"@ant-design/icons": "^6.0.0",
|
||||||
"@hookform/resolvers": "^5.0.1",
|
"@hookform/resolvers": "^5.0.1",
|
||||||
|
"@radix-ui/react-slot": "^1.2.0",
|
||||||
"@tanstack/react-query": "^5.74.4",
|
"@tanstack/react-query": "^5.74.4",
|
||||||
"@tanstack/react-store": "^0.7.0",
|
"@tanstack/react-store": "^0.7.0",
|
||||||
"@tanstack/react-table": "^8.21.2",
|
"@tanstack/react-table": "^8.21.2",
|
||||||
"axios": "^1.8.3",
|
"axios": "^1.8.3",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"framer-motion": "^12.9.2",
|
"framer-motion": "^12.9.2",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "~15.2.4",
|
"next": "~15.2.4",
|
||||||
|
"next-themes": "^0.4.6",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-hook-form": "^7.55.0",
|
"react-hook-form": "^7.55.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^7.3.0",
|
"react-router-dom": "^7.3.0",
|
||||||
"sonner": "^2.0.3",
|
"sonner": "^2.0.3",
|
||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
@@ -89,6 +93,7 @@
|
|||||||
"tailwindcss": "^4.0.13",
|
"tailwindcss": "^4.0.13",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
|
"tw-animate-css": "^1.2.8",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"typescript-eslint": "^8.19.0",
|
"typescript-eslint": "^8.19.0",
|
||||||
"verdaccio": "^6.0.5",
|
"verdaccio": "^6.0.5",
|
||||||
@@ -7529,6 +7534,39 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-compose-refs": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-slot": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rc-component/util": {
|
"node_modules/@rc-component/util": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.2.1.tgz",
|
||||||
@@ -10716,7 +10754,7 @@
|
|||||||
"version": "19.1.2",
|
"version": "19.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz",
|
||||||
"integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==",
|
"integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
@@ -14794,6 +14832,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/class-variance-authority": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"clsx": "^2.1.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://polar.sh/cva"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/classnames": {
|
"node_modules/classnames": {
|
||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||||
@@ -16019,7 +16069,7 @@
|
|||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/cwd": {
|
"node_modules/cwd": {
|
||||||
@@ -24544,6 +24594,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/next-themes": {
|
||||||
|
"version": "0.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
|
||||||
|
"integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/next/node_modules/@swc/helpers": {
|
"node_modules/next/node_modules/@swc/helpers": {
|
||||||
"version": "0.5.15",
|
"version": "0.5.15",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
|
||||||
@@ -27494,6 +27554,15 @@
|
|||||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@@ -31253,6 +31322,16 @@
|
|||||||
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
|
"integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/tw-animate-css": {
|
||||||
|
"version": "1.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.2.8.tgz",
|
||||||
|
"integrity": "sha512-AxSnYRvyFnAiZCUndS3zQZhNfV/B77ZhJ+O7d3K6wfg/jKJY+yv6ahuyXwnyaYA9UdLqnpCwhTRv9pPTBnPR2g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/Wombosvideo"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tweetnacl": {
|
"node_modules/tweetnacl": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
|
|||||||
@@ -26,17 +26,21 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^6.0.0",
|
"@ant-design/icons": "^6.0.0",
|
||||||
"@hookform/resolvers": "^5.0.1",
|
"@hookform/resolvers": "^5.0.1",
|
||||||
|
"@radix-ui/react-slot": "^1.2.0",
|
||||||
"@tanstack/react-query": "^5.74.4",
|
"@tanstack/react-query": "^5.74.4",
|
||||||
"@tanstack/react-store": "^0.7.0",
|
"@tanstack/react-store": "^0.7.0",
|
||||||
"@tanstack/react-table": "^8.21.2",
|
"@tanstack/react-table": "^8.21.2",
|
||||||
"axios": "^1.8.3",
|
"axios": "^1.8.3",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"framer-motion": "^12.9.2",
|
"framer-motion": "^12.9.2",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"next": "~15.2.4",
|
"next": "~15.2.4",
|
||||||
|
"next-themes": "^0.4.6",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-hook-form": "^7.55.0",
|
"react-hook-form": "^7.55.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^7.3.0",
|
"react-router-dom": "^7.3.0",
|
||||||
"sonner": "^2.0.3",
|
"sonner": "^2.0.3",
|
||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
@@ -104,6 +108,7 @@
|
|||||||
"tailwindcss": "^4.0.13",
|
"tailwindcss": "^4.0.13",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
|
"tw-animate-css": "^1.2.8",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"typescript-eslint": "^8.19.0",
|
"typescript-eslint": "^8.19.0",
|
||||||
"verdaccio": "^6.0.5",
|
"verdaccio": "^6.0.5",
|
||||||
|
|||||||
Reference in New Issue
Block a user