diff --git a/README.md b/README.md index ddabd09..57918bf 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# LPK NihonBuzz Academy Ecosystem Blueprint 🇯🇵 +# LPK Nihonbuzz Academy Ecosystem Blueprint 🇯🇵 -Dokumen ini merupakan cetak biru (blueprint) teknis mutakhir untuk seluruh ekosistem digital **LPK NihonBuzz**, yang dirancang sebagai platform pelatihan kerja terintegrasi, manajemen administrasi kantor (Buku Kantor), dan validasi sertifikasi kompetensi Bahasa Jepang. +Dokumen ini merupakan cetak biru (blueprint) teknis mutakhir untuk seluruh ekosistem digital **LPK Nihonbuzz**, yang dirancang sebagai platform pelatihan kerja terintegrasi, manajemen administrasi kantor (Buku Kantor), dan validasi sertifikasi kompetensi Bahasa Jepang. --- ## 1. High-Level Architecture -Eksosistem LPK NihonBuzz terbagi menjadi dua entitas utama yang saling terintegrasi namun berjalan di infrastruktur yang dioptimalkan untuk kebutuhan masing-masing. +Eksosistem LPK Nihonbuzz terbagi menjadi dua entitas utama yang saling terintegrasi namun berjalan di infrastruktur yang dioptimalkan untuk kebutuhan masing-masing. ```mermaid graph TD diff --git a/public/brand/wave-pattern-global.jpg b/public/brand/wave-pattern-global.jpg new file mode 100644 index 0000000..f2b26fc Binary files /dev/null and b/public/brand/wave-pattern-global.jpg differ diff --git a/public/brand/wave-pattern-global.svg b/public/brand/wave-pattern-global.svg new file mode 100644 index 0000000..db05da1 --- /dev/null +++ b/public/brand/wave-pattern-global.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/css/app.css b/resources/css/app.css index 4f354fb..6325b0c 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -60,6 +60,49 @@ } } +@layer components { + .btn { + @apply inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 h-11 px-6 shadow-sm; + } + .btn-sm { + @apply h-9 rounded-md px-3 text-xs shadow-sm; + } + .btn-lg { + @apply h-12 rounded-xl px-8 shadow-sm; + } + .btn-icon { + @apply h-11 w-11 px-0 shadow-sm; + } + + .btn-primary { + @apply bg-primary text-primary-foreground shadow hover:bg-primary/90 dark:hover:bg-primary/80; + } + .btn-secondary { + @apply bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 dark:hover:bg-secondary/70; + } + .btn-outline { + @apply border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground; + } + .btn-ghost { + @apply shadow-none hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 dark:hover:text-foreground; + } + .btn-destructive { + @apply bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 dark:hover:bg-destructive/80; + } + .btn-link { + @apply text-primary underline-offset-4 hover:underline shadow-none bg-transparent hover:bg-transparent; + } + + /* Glassmorphism Utilities */ + .card-glass { + @apply bg-white/50 dark:bg-black/30 backdrop-blur-xl border border-white/40 dark:border-white/10 shadow-sm; + } + + .btn-glass { + @apply border border-white/40 dark:border-white/10 bg-white/40 dark:bg-white/5 hover:bg-white/60 dark:hover:bg-white/10 backdrop-blur-md text-foreground shadow-sm; + } +} + @layer utilities { .bg-grid { background-size: 40px 40px; @@ -76,6 +119,13 @@ mask-image: linear-gradient(180deg, white, rgba(255, 255, 255, 0)); -webkit-mask-image: linear-gradient(180deg, white, rgba(255, 255, 255, 0)); } + + .bg-wave-global { + background-color: transparent; + background-image: url('/brand/wave-pattern-global.svg'); + background-repeat: repeat; + background-size: 400px auto; /* Adjust scale as needed, 400px seems a good starting point for visibility */ + } } @layer base { @@ -96,4 +146,3 @@ .plyr--video { @apply rounded-2xl overflow-hidden shadow-2xl; } - diff --git a/resources/js/Components/CourseCard.tsx b/resources/js/Components/CourseCard.tsx index 29d5812..d29bdf4 100644 --- a/resources/js/Components/CourseCard.tsx +++ b/resources/js/Components/CourseCard.tsx @@ -28,7 +28,7 @@ export default function CourseCard({ {/* Hover Glow Effect */}
- +
+
{/* Background Gradients - Boosted for Light Mode using CSS variables */}
@@ -45,7 +45,7 @@ export function Hero() { variants={containerVariants} initial="hidden" animate="visible" - className="relative z-10 container px-4 mx-auto flex flex-col items-center text-center gap-8" + className="relative z-10 container px-4 mx-auto flex flex-col items-center text-center gap-8 pt-24 lg:pt-32" >
diff --git a/resources/js/Components/Landing/Hero.tsx.bak b/resources/js/Components/Landing/Hero.tsx.bak new file mode 100644 index 0000000..a295b6c --- /dev/null +++ b/resources/js/Components/Landing/Hero.tsx.bak @@ -0,0 +1,91 @@ +"use client"; + +import { motion, Variants } from "framer-motion"; +import { ArrowRight, Sparkles } from "lucide-react"; +import { Button } from "@/Components/ui/button"; +import { Link } from "@inertiajs/react"; + +const containerVariants: Variants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.3, + }, + }, +}; + +const itemVariants: Variants = { + hidden: { y: 20, opacity: 0 }, + visible: { + y: 0, + opacity: 1, + transition: { + duration: 0.8, + ease: [0.215, 0.610, 0.355, 1.000], + }, + }, +}; + +export function Hero() { + return ( +
+ {/* Background Gradients - Boosted for Light Mode using CSS variables */} +
+
+ + {/* Grid Pattern Overlay */} +
+ + {/* Japanese Wave Pattern - Adjusted Opacity */} +
+ + + +
+ + Pendaftaran Batch 2026 Dibuka! +
+
+ + + Hubungkan Impianmu
+ + Ke Negeri Sakura + +
+ + + Platform edukasi terdepan untuk penguasaan Bahasa Jepang & karir profesional. + Belajar JLPT N5 hingga N2 dengan kurikulum modern dan Spaced Repetition System. + + + + + + +
+
+ ); +} diff --git a/resources/js/Components/Landing/Navbar.tsx b/resources/js/Components/Landing/Navbar.tsx index e605f43..447a1b4 100644 --- a/resources/js/Components/Landing/Navbar.tsx +++ b/resources/js/Components/Landing/Navbar.tsx @@ -39,7 +39,7 @@ export function Navbar() { className={cn( "flex items-center justify-between transition-all duration-300 ease-in-out pointer-events-auto", scrolled - ? "bg-background/80 backdrop-blur-xl border border-white/10 shadow-2xl w-full max-w-5xl px-10 py-3 rounded-full gap-8" + ? "bg-background/80 backdrop-blur-xl border border-white/10 shadow-none w-full max-w-5xl px-10 py-3 rounded-full gap-8" : "bg-transparent border-transparent w-full max-w-6xl px-6 py-3 rounded-full" )} > diff --git a/resources/js/Components/ui/card.tsx b/resources/js/Components/ui/card.tsx index cabfbfc..6c60172 100644 --- a/resources/js/Components/ui/card.tsx +++ b/resources/js/Components/ui/card.tsx @@ -9,7 +9,7 @@ const Card = React.forwardRef<
+
{/* Background Decorations - Pure CSS */}
diff --git a/resources/js/Layouts/GuestLayout.tsx b/resources/js/Layouts/GuestLayout.tsx index 1a8f3e4..da195b2 100644 --- a/resources/js/Layouts/GuestLayout.tsx +++ b/resources/js/Layouts/GuestLayout.tsx @@ -2,12 +2,29 @@ import { ThemeProvider } from "@/Components/ThemeProvider"; import { Navbar } from "@/Components/Landing/Navbar"; import { Footer } from "@/Components/Landing/Footer"; -export default function GuestLayout({ children }: { children: React.ReactNode }) { +import { cn } from "@/lib/utils"; + +export default function GuestLayout({ + children, + variant = 'default' +}: { + children: React.ReactNode, + variant?: 'default' | 'landing' +}) { return ( - -
+ +
+ {/* Global Background Pattern */} + {/* SVG is white by default. In light mode, we invert it to black to be visible on white bg. */} +
+ -
{children}
+
+ {children} +
diff --git a/resources/js/Pages/Auth/ConfirmPassword.tsx b/resources/js/Pages/Auth/ConfirmPassword.tsx index f71476f..0c438fe 100644 --- a/resources/js/Pages/Auth/ConfirmPassword.tsx +++ b/resources/js/Pages/Auth/ConfirmPassword.tsx @@ -24,33 +24,34 @@ export default function ConfirmPassword() {
-
-
- This is a secure area of the application. Please confirm your - password before continuing. +
+
+
+ This is a secure area of the application. Please confirm your + password before continuing. +
+ +
+
+ + setData('password', e.target.value)} + /> + +
+ +
+ +
+
- -
-
- - setData('password', e.target.value)} - /> - -
- -
- -
-
diff --git a/resources/js/Pages/Auth/ForgotPassword.tsx b/resources/js/Pages/Auth/ForgotPassword.tsx index 3862acb..ae9678c 100644 --- a/resources/js/Pages/Auth/ForgotPassword.tsx +++ b/resources/js/Pages/Auth/ForgotPassword.tsx @@ -5,6 +5,7 @@ import { FormEventHandler } from 'react'; import { Button } from '@/Components/ui/button'; import { Input } from '@/Components/ui/input'; import { Label } from '@/Components/ui/label'; +import { Card } from '@/Components/ui/card'; export default function ForgotPassword({ status }: { status?: string }) { const { data, setData, post, processing, errors } = useForm({ @@ -22,7 +23,7 @@ export default function ForgotPassword({ status }: { status?: string }) {
-
+
Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will @@ -51,12 +52,12 @@ export default function ForgotPassword({ status }: { status?: string }) {
- +
-
+
); diff --git a/resources/js/Pages/Auth/Login.tsx b/resources/js/Pages/Auth/Login.tsx index f6cdc13..9f41744 100644 --- a/resources/js/Pages/Auth/Login.tsx +++ b/resources/js/Pages/Auth/Login.tsx @@ -34,7 +34,7 @@ export default function Login({
- + Selamat Datang Kembali @@ -101,9 +101,9 @@ export default function Login({
- +
@@ -119,7 +119,7 @@ export default function Login({ +
diff --git a/resources/js/Pages/Auth/ResetPassword.tsx b/resources/js/Pages/Auth/ResetPassword.tsx index 337d0aa..d19f7f1 100644 --- a/resources/js/Pages/Auth/ResetPassword.tsx +++ b/resources/js/Pages/Auth/ResetPassword.tsx @@ -33,58 +33,59 @@ export default function ResetPassword({
-
-

Reset Password

- -
-
- - setData('email', e.target.value)} - /> - -
+
+
+

Reset Password

+ + +
+ + setData('email', e.target.value)} + /> + +
-
- - + + setData('password', e.target.value)} + /> + +
- onChange={(e) => setData('password', e.target.value)} - /> - -
+
+ + setData('password_confirmation', e.target.value)} + /> + +
-
- - setData('password_confirmation', e.target.value)} - /> - -
- -
- -
- +
+ +
+ +
diff --git a/resources/js/Pages/Auth/VerifyEmail.tsx b/resources/js/Pages/Auth/VerifyEmail.tsx index 4d96b7f..d2f7853 100644 --- a/resources/js/Pages/Auth/VerifyEmail.tsx +++ b/resources/js/Pages/Auth/VerifyEmail.tsx @@ -2,6 +2,7 @@ import GuestLayout from '@/Layouts/GuestLayout'; import { Head, Link, useForm } from '@inertiajs/react'; import { FormEventHandler } from 'react'; import { Button } from '@/Components/ui/button'; +import { Card } from '@/Components/ui/card'; export default function VerifyEmail({ status }: { status?: string }) { const { post, processing } = useForm({}); @@ -17,7 +18,7 @@ export default function VerifyEmail({ status }: { status?: string }) {
-
+
Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to @@ -33,9 +34,9 @@ export default function VerifyEmail({ status }: { status?: string }) { )}
- +
-
+
); diff --git a/resources/js/Pages/Dashboard.tsx b/resources/js/Pages/Dashboard.tsx index 45446b3..48d52df 100644 --- a/resources/js/Pages/Dashboard.tsx +++ b/resources/js/Pages/Dashboard.tsx @@ -57,7 +57,7 @@ export default function Dashboard({
{/* Stats Grid */}
- + Total XP @@ -66,7 +66,7 @@ export default function Dashboard({
{stats.xp_points.toLocaleString()}
- + Streak @@ -75,7 +75,7 @@ export default function Dashboard({
{stats.current_streak} Hari
- + Kursus @@ -84,7 +84,7 @@ export default function Dashboard({
{stats.active_courses} Aktif
- + Sertifikat diff --git a/resources/js/Pages/Welcome.tsx b/resources/js/Pages/Welcome.tsx index 2e10f91..64fa3b5 100644 --- a/resources/js/Pages/Welcome.tsx +++ b/resources/js/Pages/Welcome.tsx @@ -5,7 +5,7 @@ import { Hero } from '@/Components/Landing/Hero'; export default function Welcome({ auth }: PageProps) { return ( - + diff --git a/resources/js/app.tsx b/resources/js/app.tsx index 574fbe7..19422be 100644 --- a/resources/js/app.tsx +++ b/resources/js/app.tsx @@ -19,7 +19,7 @@ createInertiaApp({ const root = createRoot(el); root.render( - + ); diff --git a/resources/views/app.blade.php b/resources/views/app.blade.php index 28d941b..2f2ed1e 100644 --- a/resources/views/app.blade.php +++ b/resources/views/app.blade.php @@ -30,6 +30,20 @@ + + @routes @viteReactRefresh diff --git a/tmp_hero_first.tsx b/tmp_hero_first.tsx new file mode 100644 index 0000000..a295b6c --- /dev/null +++ b/tmp_hero_first.tsx @@ -0,0 +1,91 @@ +"use client"; + +import { motion, Variants } from "framer-motion"; +import { ArrowRight, Sparkles } from "lucide-react"; +import { Button } from "@/Components/ui/button"; +import { Link } from "@inertiajs/react"; + +const containerVariants: Variants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.3, + }, + }, +}; + +const itemVariants: Variants = { + hidden: { y: 20, opacity: 0 }, + visible: { + y: 0, + opacity: 1, + transition: { + duration: 0.8, + ease: [0.215, 0.610, 0.355, 1.000], + }, + }, +}; + +export function Hero() { + return ( +
+ {/* Background Gradients - Boosted for Light Mode using CSS variables */} +
+
+ + {/* Grid Pattern Overlay */} +
+ + {/* Japanese Wave Pattern - Adjusted Opacity */} +
+ + + +
+ + Pendaftaran Batch 2026 Dibuka! +
+
+ + + Hubungkan Impianmu
+ + Ke Negeri Sakura + +
+ + + Platform edukasi terdepan untuk penguasaan Bahasa Jepang & karir profesional. + Belajar JLPT N5 hingga N2 dengan kurikulum modern dan Spaced Repetition System. + + + + + + +
+
+ ); +} diff --git a/tmp_hero_v1.tsx b/tmp_hero_v1.tsx new file mode 100644 index 0000000..a295b6c --- /dev/null +++ b/tmp_hero_v1.tsx @@ -0,0 +1,91 @@ +"use client"; + +import { motion, Variants } from "framer-motion"; +import { ArrowRight, Sparkles } from "lucide-react"; +import { Button } from "@/Components/ui/button"; +import { Link } from "@inertiajs/react"; + +const containerVariants: Variants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.2, + delayChildren: 0.3, + }, + }, +}; + +const itemVariants: Variants = { + hidden: { y: 20, opacity: 0 }, + visible: { + y: 0, + opacity: 1, + transition: { + duration: 0.8, + ease: [0.215, 0.610, 0.355, 1.000], + }, + }, +}; + +export function Hero() { + return ( +
+ {/* Background Gradients - Boosted for Light Mode using CSS variables */} +
+
+ + {/* Grid Pattern Overlay */} +
+ + {/* Japanese Wave Pattern - Adjusted Opacity */} +
+ + + +
+ + Pendaftaran Batch 2026 Dibuka! +
+
+ + + Hubungkan Impianmu
+ + Ke Negeri Sakura + +
+ + + Platform edukasi terdepan untuk penguasaan Bahasa Jepang & karir profesional. + Belajar JLPT N5 hingga N2 dengan kurikulum modern dan Spaced Repetition System. + + + + + + +
+
+ ); +}