Lewati ke isi

Scola-FE-V2 UI Design Pattern & Styles (SSOT)

This document establishes the official Single Source of Truth (SSOT) for UI design patterns in the Scola-FE-V2 repository. By following these guidelines, we ensure consistency, cross-mode visibility (Light/Dark Mode), and maintainability across all module boundaries.

1. Banner Systems & Gradient Layouts

Gradient banners give areas like Dashboards or Admission Landing a premium feel. However, embedding content inside them requires care for Light/Dark mode resilience.

a. Gradient Guidelines

  • Primary Gradients: Use bg-linear-to-r or bg-linear-to-br. Avoid generic solid colors.
  • Palette Matching:
  • Educational/Core (Teachers/Students): from-blue-600 to-indigo-600 or from-sky-500 to-blue-600.
  • Homeroom/Class Specific: from-indigo-500 to-purple-600.
  • Action/Highlights: from-emerald-500 to-teal-600.

b. Translucency & Contrast Rules (The Visibility Bug Fix)

If a container inherits text colors (like text-white inside a banner), never use opaque backgrounds (e.g. bg-white) for nested container elements (like badges or icon wrappers). Doing so results in invisible white-on-white text in light mode.

  • Use Translucent Backgrounds: Use bg-white/20 along with dark:bg-slate-800/20 inside gradient banners.
  • Example Pattern:
    <!-- Outer Banner -->
    <div class="bg-linear-to-r from-blue-600 to-indigo-600 p-6 text-white rounded-3xl">
        <!-- Inner Item Wrapper -->
        <div class="w-14 h-14 rounded-2xl bg-white/20 dark:bg-slate-800/20 flex flex-center">
            <GraduationCap class="w-7 h-7 text-white" />
        </div>
    </div>
    

2. Layout Rules: Pages & Sections

  • AppLayout: Always wrap main application routes within the <AppLayout> component.
  • TopbarMobile: Always implement a topbar for mobile compatibility with <template #topbar>.
  • Page Spacing: Utilize px-4 py-5 md:px-6 md:py-7 for standard container padding.
  • Headers & Titles: Standardize page headers with flex items-center gap-3 mb-5. Give titles the truncate class to prevent flex-box overflow issues on narrow screens.

3. UI Cards & Content Organization

  • Cards: Use <AppCard> for standardization, otherwise follow this pattern: bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4.
  • Lists: When displaying list items, structure rows with Flexbox (flex items-start justify-between). Separate metadata into a column:
    <div class="flex items-start justify-between mb-2">
        <div>
            <h4 class="font-medium text-slate-800 dark:text-slate-200 text-sm">Title</h4>
            <p class="text-xs text-slate-500 dark:text-slate-400">Subtitle</p>
        </div>
        <AppBadge color="sky" size="sm">Active</AppBadge>
    </div>
    

4. Status Badges & Motivations

  • AppBadge: Use <AppBadge> for statuses (color="sky" | "emerald" | "amber" | "rose").
  • Custom Badges: If crafting a custom label format, adhere strictly to semantic light/dark states:
  • Backgrounds: bg-blue-50 dark:bg-blue-900/20.
  • Borders: border border-blue-200 dark:border-blue-800/50.
  • Text: text-blue-700 dark:text-blue-400.

5. UI States (Empty, Loading, Error)

Consistent communication of system states improves UX. All states should be centered.

a. Loading State

Always use the Loader2 from lucide-vue-next with the animate-spin class and a sky-blue hue.

<div class="flex items-center justify-center py-20 text-center">
    <Loader2 :size="32" class="animate-spin text-sky-500 mx-auto mb-3" />
    <p class="text-sm text-slate-500 dark:text-slate-400">Memuat data...</p>
</div>

b. Empty State

Use distinct visual elements (large tinted box) and descriptive guidance rather than a simple "Data empty":

<div class="text-center py-16">
    <div class="w-20 h-20 rounded-full bg-slate-100 dark:bg-slate-700 flex flex-center mx-auto mb-4">
        <FileX :size="40" class="text-slate-400 dark:text-slate-500" />
    </div>
    <h3 class="text-lg font-semibold text-slate-700 dark:text-slate-300 mb-2">Belum ada tugas</h3>
    <p class="text-sm text-slate-500 dark:text-slate-400 max-w-sm mx-auto">
        Tugas yang dikumpulkan akan muncul di sini.
    </p>
</div>

c. Error State

Make errors visually distinct using red palettes. Provide actionable buttons to re-fetch if possible.

<div class="text-center py-12">
    <div class="w-20 h-20 mx-auto mb-4 rounded-3xl bg-red-100 flex items-center justify-center">
        <AlertCircle :size="36" class="text-red-600" />
    </div>
    <h3 class="text-lg font-bold text-slate-900 dark:text-slate-100 mb-2">Gagal Memuat</h3>
    <p class="text-sm text-slate-500 dark:text-slate-400 mt-1">{{ error }}</p>
</div>

Quick Checklist for New Features

  1. [ ] Did you use bg-white/20 inside gradient containers?
  2. [ ] Does the page display loading, empty, and proper error states?
  3. [ ] Are semantic colors (Amber = Warning/Pending, Emerald = Success, Rose = Danger) respected?
  4. [ ] Did you implement Dark Mode classes (e.g. dark:bg-slate-800, dark:text-slate-300) on all typography?