Skip to main content
Back to ScopeForged

ScopeForged Documentation

Technical documentation, guides, and feature references for the ScopeForged client portal.

Frontend & UI/Views Organization

Views Organization Guide

Last Updated: 2026-01-22 Status: Active Audience: Developers

This guide defines the standard organization for all files in resources/views/. Follow these conventions when creating new views or refactoring existing ones.


Table of Contents

  1. Directory Structure
  2. Top-Level Directories
  3. Components Organization
  4. Naming Conventions
  5. File Placement Rules
  6. Layouts
  7. Partials vs Components
  8. Examples

Directory Structure

resources/views/
├── admin/                    # Admin portal views (admin.scopeforged.com)
├── api/                      # API documentation views
├── auth/                     # Authentication views (login, register, etc.)
├── components/               # Reusable Blade components
├── emails/                   # Email templates
├── errors/                   # Error pages (404, 500, etc.)
├── layouts/                  # Page layout templates
├── marketing/                # Marketing site views (scopeforged.com)
├── pdf/                      # PDF generation templates
├── portal/                   # Client portal views (portal.scopeforged.com)
├── settings/                 # User settings views
└── shared/                   # Views shared across domains

Top-Level Directories

admin/

Views for the admin portal (admin.scopeforged.com). Organize by feature/resource.

admin/
├── clients/                  # Client management
│   ├── index.blade.php
│   ├── create.blade.php
│   ├── edit.blade.php
│   ├── show.blade.php
│   └── _form.blade.php       # Shared form partial
├── invoices/
├── projects/
├── analytics/
├── notifications/
│   ├── templates/            # Nested resource
│   └── analytics/
└── settings/

portal/

Views for the client portal (portal.scopeforged.com). Simpler structure focused on client-facing features.

portal/
├── dashboard.blade.php
├── projects/
├── invoices/
├── files/
├── messages/
└── settings/

marketing/

Views for the public marketing site (scopeforged.com).

marketing/
├── home.blade.php
├── about.blade.php
├── contact.blade.php
├── pricing.blade.php
├── blog/
│   ├── index.blade.php
│   └── show.blade.php
├── case-studies/
└── legal/
    ├── privacy.blade.php
    └── terms.blade.php

layouts/

Base layout templates. Keep minimal - most views should use one of these.

layouts/
├── app.blade.php             # Main authenticated layout (admin/portal)
├── guest.blade.php           # Unauthenticated layout
├── marketing.blade.php       # Marketing site layout
├── pdf.blade.php             # PDF generation layout
└── navigation.blade.php      # Main navigation partial

emails/

Email templates using Laravel's markdown mail format.

emails/
├── invoices/
│   ├── sent.blade.php
│   └── reminder.blade.php
├── projects/
│   └── status-update.blade.php
├── auth/
│   └── welcome.blade.php
└── notifications/
    └── generic.blade.php

errors/

Custom error pages.

errors/
├── 401.blade.php
├── 403.blade.php
├── 404.blade.php
├── 419.blade.php
├── 429.blade.php
├── 500.blade.php
└── 503.blade.php

Components Organization

Components live in resources/views/components/ and are organized by purpose, not by where they're used.

Component Categories

DirectoryPurposeExamples
actions/User action controlsbulk-actions, filter-panel, search
analytics/Charts, metrics, dashboardsanalytics-chart, trend, widget
collaboration/Multi-user interactioncomments, notes, mentions
dashboard/Dashboard-specific widgetsgrid, section, widgets/*
data-table/Table sub-componentssortable-header, pagination, filter
display/Data presentationstat-card, badge, avatar, progress-bar
feedback/User feedback/alertsmodal, toast, flash-messages, tooltip
files/File handlingupload, preview, versions
form/Form inputsinput, select, checkbox, textarea
marketing/Marketing-specifictestimonial, team-card, pricing
navigation/Navigation elementsdropdown, nav-link, breadcrumb
portal/Portal-specific componentstimeline, mobile-nav
realtime/Real-time/WebSocketpresence, typing-indicator, notifications
skeletons/Loading placeholderscard, table-row, avatar
state/State indicatorsempty-state, spinner, loading
ui/Generic UI primitivesbutton, card, badge, accordion
utility/Utility/helper componentslogo, theme-toggle, banner

Root-Level Components

Only high-usage primitive components stay at the root level:

ComponentReason
icon.blade.phpFundamental - used everywhere
date.blade.phpFundamental date formatter
datetime.blade.phpFundamental datetime formatter
data-table.blade.phpCore table component

Rule: If a component has fewer than 100 usages, it belongs in a subdirectory.

Component Directory Structure

components/
├── icon.blade.php            # Root - high usage primitive
├── date.blade.php            # Root - high usage primitive
├── datetime.blade.php        # Root - high usage primitive
├── data-table.blade.php      # Root - high usage primitive
│
├── actions/
│   ├── accessible-search.blade.php
│   ├── bulk-actions.blade.php
│   ├── bulk-checkbox.blade.php
│   └── filter-panel.blade.php
│
├── dashboard/
│   ├── grid.blade.php
│   ├── section.blade.php
│   └── widgets/
│       ├── base.blade.php
│       ├── loading.blade.php
│       ├── error.blade.php
│       └── empty.blade.php
│
├── display/
│   ├── stat-card.blade.php
│   ├── status-badge.blade.php
│   ├── progress-bar.blade.php
│   └── user-avatar.blade.php
│
├── feedback/
│   ├── modal.blade.php
│   ├── confirm-modal.blade.php
│   ├── flash-messages.blade.php
│   ├── toast-notifications.blade.php
│   └── tooltip.blade.php
│
├── form/
│   ├── input.blade.php
│   ├── textarea.blade.php
│   ├── select.blade.php
│   ├── checkbox.blade.php
│   ├── radio.blade.php
│   ├── toggle.blade.php
│   └── group.blade.php
│
├── navigation/
│   ├── dropdown.blade.php
│   ├── dropdown-link.blade.php
│   ├── nav-link.blade.php
│   ├── breadcrumb.blade.php
│   └── settings-nav.blade.php
│
├── state/
│   ├── spinner.blade.php
│   ├── loading-dots.blade.php
│   ├── loading-overlay.blade.php
│   ├── empty-state.blade.php
│   └── upload-progress.blade.php
│
└── ui/
    ├── button.blade.php
    ├── card.blade.php
    ├── badge.blade.php
    ├── accordion.blade.php
    └── table.blade.php

Naming Conventions

Files

TypeConventionExample
Viewskebab-caseproject-details.blade.php
Componentskebab-casestatus-badge.blade.php
Partialsunderscore prefix_form.blade.php
Layoutskebab-caseapp.blade.php

Component Usage

{{-- Root-level components --}}
<x-icon name="check" />
<x-date :value="$createdAt" />
<x-data-table :items="$clients" />

{{-- Categorized components (dot notation) --}}
<x-ui.button variant="primary">Save</x-ui.button>
<x-form.input name="email" label="Email" />
<x-feedback.modal name="confirm-delete" />
<x-state.spinner />
<x-display.stat-card title="Revenue" :value="$revenue" />
<x-navigation.dropdown />

CRUD Views

Standard naming for resource views:

{resource}/
├── index.blade.php           # List all
├── create.blade.php          # Create form
├── edit.blade.php            # Edit form
├── show.blade.php            # View single
└── _form.blade.php           # Shared form partial (optional)

File Placement Rules

Decision Tree: Where Does This View Go?

Is it a reusable UI element?
├── YES → components/{category}/
└── NO ↓

Is it for email?
├── YES → emails/{feature}/
└── NO ↓

Is it a PDF template?
├── YES → pdf/{feature}/
└── NO ↓

Is it an error page?
├── YES → errors/
└── NO ↓

Is it for the admin portal?
├── YES → admin/{feature}/
└── NO ↓

Is it for the client portal?
├── YES → portal/{feature}/
└── NO ↓

Is it for the marketing site?
├── YES → marketing/{feature}/
└── NO ↓

Is it shared across domains?
└── YES → shared/{feature}/

Decision Tree: Which Component Category?

Does it handle user input?
├── YES → form/
└── NO ↓

Does it display data/status?
├── YES → display/
└── NO ↓

Does it provide user feedback?
├── YES → feedback/
└── NO ↓

Does it handle navigation?
├── YES → navigation/
└── NO ↓

Is it a loading/empty state?
├── YES → state/
└── NO ↓

Is it for file operations?
├── YES → files/
└── NO ↓

Is it for real-time features?
├── YES → realtime/
└── NO ↓

Is it for dashboards/analytics?
├── YES → dashboard/ or analytics/
└── NO ↓

Is it a generic UI primitive?
└── YES → ui/

Layouts

Available Layouts

LayoutUse For
layouts.appAuthenticated admin/portal pages
layouts.guestUnauthenticated pages (login, register)
marketing-layoutMarketing site pages
settings-layoutSettings pages with sidebar
error-layoutError pages

Layout Usage

{{-- Standard authenticated page --}}
<x-app-layout>
    <x-slot name="header">
        <h2>Page Title</h2>
    </x-slot>

    {{-- Page content --}}
</x-app-layout>

{{-- Marketing page --}}
<x-marketing-layout>
    {{-- Page content --}}
</x-marketing-layout>

{{-- Settings page --}}
<x-settings-layout>
    {{-- Settings content --}}
</x-settings-layout>

Partials vs Components

When to Use Partials (_filename.blade.php)

  • Feature-specific markup not reused elsewhere
  • Form fragments shared between create/edit views
  • Section fragments for very long views
  • Livewire partial updates (rows for HTMX/Livewire)
{{-- admin/clients/_form.blade.php --}}
{{-- Only used in admin/clients/create.blade.php and edit.blade.php --}}

@include('admin.clients._form', ['client' => $client])

When to Use Components

  • Reusable across multiple features
  • Configurable via props
  • Self-contained with own styling/logic
  • UI patterns that should be consistent
{{-- Reusable, configurable, consistent --}}
<x-form.input name="email" label="Email" type="email" required />

Partial Naming

  • Prefix with underscore: _form.blade.php, _filters.blade.php
  • Keep in same directory as parent view
  • Never put partials in components/

Examples

Creating a New Admin Feature

Adding a "Reports" feature to admin:

admin/
└── reports/
    ├── index.blade.php       # List all reports
    ├── create.blade.php      # Create report form
    ├── show.blade.php        # View single report
    └── _filters.blade.php    # Filter partial (if complex)

Creating a New Component

Adding a "rating" display component:

  1. Determine category: Displays data → display/
  2. Create file: components/display/rating.blade.php
  3. Usage: <x-display.rating :value="4.5" :max="5" />
{{-- components/display/rating.blade.php --}}
@props(['value', 'max' => 5])

<div class="flex items-center gap-1">
    @for ($i = 1; $i <= $max; $i++)
        <x-icon
            name="{{ $i <= $value ? 'star-filled' : 'star' }}"
            class="{{ $i <= $value ? 'text-yellow-400' : 'text-gray-300' }}"
        />
    @endfor
    <span class="ml-2 text-sm text-gray-600">{{ $value }}/{{ $max }}</span>
</div>

Form Component Standard API

All form components should follow this prop pattern:

@props([
    'name',                    # Required: field name
    'label' => null,           # Optional: label text
    'hint' => null,            # Optional: help text
    'error' => null,           # Optional: override error message
    'required' => false,       # Optional: mark as required
    'disabled' => false,       # Optional: disable input
])

Usage:

<x-form.input
    name="company_name"
    label="Company Name"
    hint="Enter the legal business name"
    required
/>

Button Component Variants

Use x-ui.button with variants instead of separate button components:

{{-- Correct --}}
<x-ui.button variant="primary">Save</x-ui.button>
<x-ui.button variant="secondary">Cancel</x-ui.button>
<x-ui.button variant="danger">Delete</x-ui.button>
<x-ui.button variant="ghost">More Options</x-ui.button>
<x-ui.button variant="link" href="/docs">Learn More</x-ui.button>

{{-- Deprecated - do not use --}}
<x-primary-button>Save</x-primary-button>
<x-secondary-button>Cancel</x-secondary-button>
<x-danger-button>Delete</x-danger-button>

Best Practices

Do

  • Place components in the appropriate category directory
  • Use dot notation for categorized components (x-form.input)
  • Follow the standard form component API
  • Use layouts consistently
  • Keep partials with their parent views
  • Name files descriptively using kebab-case

Don't

  • Create components at the root level (unless >100 usages)
  • Mix concerns in component categories
  • Use @include for reusable UI (use components)
  • Create feature-specific components in generic categories
  • Duplicate component functionality