Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

InkPavo

A Laravel + React (Inertia) e-commerce application.

Project overview

InkPavo is a full-stack print-commerce platform built as a Laravel monolith with an Inertia-powered React frontend. It combines a public marketing/storefront site, authenticated customer workflows, and an internal admin panel in one codebase.

Core capabilities

  • Storefront + content: Home, static marketing pages, product catalog/detail pages, blog pages, and SEO sitemap routes.
  • Shopping flow: Session-based cart, checkout, order creation, and PayPal order create/capture integration.
  • Customer account: Dashboard, profile/security settings, order history, and support tickets with threaded replies.
  • Growth features: Referral links and affiliate tracking, commission accrual, and payout request flows.
  • Admin operations: Filament resources for products, product categories, blog posts, orders, users, tickets, and dashboard widgets.

Tech stack

  • Backend: PHP 8.4, Laravel 13, Inertia Laravel, Fortify authentication.
  • Frontend: React 19 + TypeScript, Vite 8, Tailwind CSS 4, Radix UI primitives.
  • Data/services: SQLite by default, session cart service, PayPal API service, content JSON loader shared through Inertia middleware.
  • Tooling: PHPUnit, PHPStan (Larastan), Laravel Pint, ESLint, Prettier.

Repository layout

app/
  Http/Controllers/     # Storefront, checkout, dashboard, settings, support flows
  Filament/             # Admin panel resources and widgets
  Models/               # Domain entities (products, orders, tickets, affiliates, posts, etc.)
  Services/             # Cart and PayPal integrations
  Support/              # Shared helpers (e.g., hardcoded content loader)
resources/js/
  pages/                # Inertia pages (shop, auth, settings, blog, dashboard)
routes/
  web.php               # Public/customer route map
  settings.php          # Authenticated settings routes
content/
  hardcoded-content.json
  product-options/      # Product-specific option definitions used by product pages

Docker development

This project includes a Docker setup for consistent local development. The container runs Apache + PHP 8.4, Node.js, and the Vite dev server together, with your local source code synced into the container.

Requirements

Quick start

  1. Copy the environment file if you haven't already:

    cp .env.example .env
  2. Build and start the container:

    docker compose up --build -d
  3. Open the application:

The first build installs Composer and npm dependencies automatically, creates the SQLite database file if it is missing, and runs migrations.

Useful commands

# Start the environment
docker compose up -d

# Stop the environment
docker compose down

# View logs
docker compose logs -f app

# Run artisan commands
docker compose exec app php artisan <command>

# Run npm commands
docker compose exec app npm <command>

# Run composer commands
docker compose exec app composer <command>

# Rebuild the image after changing the Dockerfile
docker compose up --build -d

Port configuration

Ports are read from .env:

  • APP_PORT — the port exposed for the Apache server (default: 8080)
  • VITE_PORT — the port exposed for the Vite dev server (default: 5173)

Change them in .env and restart the container with docker compose up -d.

Product image queue

Product image uploads preserve the original immediately and generate the 2000px WebP derivative on the database queue. The storefront uses the original until the derivative is ready, so uploads remain usable even if the worker is temporarily unavailable.

The Docker image runs the queue worker through Supervisor. Rebuild and restart after changing its configuration:

docker compose up --build -d
docker compose logs -f app

On a non-Docker server, run the equivalent command under Supervisor, systemd, or another persistent process manager:

php -d memory_limit=512M artisan queue:work database \
    --queue=default --sleep=1 --timeout=180 --tries=3 --backoff=10 --memory=450

Useful operational commands:

php artisan queue:restart
php artisan queue:failed
php artisan queue:retry <job-id>

Keep DB_QUEUE_RETRY_AFTER above the worker timeout; the supplied default is 240 seconds. Conversion failures leave the original available and appear as failed in the Filament media picker until the job succeeds or the image is uploaded again.

Run the image-enabled PHP suite with the same memory ceiling used by the worker:

php -d memory_limit=512M vendor/bin/phpunit

Safe catalog synchronization

Product categories and products can be moved between environments without replacing users, orders, payments, or other live data.

Export the local catalog snapshots:

php artisan db:export-seeders --tables=product_categories,products

Preview and apply the catalog on the destination server:

php artisan migrate --force
php artisan catalog:sync --dry-run
php artisan catalog:sync

The command matches categories and products by slug. Source numeric IDs are used only to understand relationships inside the snapshot; destination relationships are rebuilt from category slugs.

Records that exist only on the destination are preserved by default. To preview and then explicitly remove them:

php artisan catalog:sync --dry-run --prune
php artisan catalog:sync --prune --force

Use --source=/path/to/snapshots to read the two JSON files from another directory. Empty or invalid snapshots are rejected before database writes, and real synchronization runs in a transaction.

Do not use LiveDataSeeder to synchronize a populated production database: it truncates every table represented in database/seeders/data. Uploaded files are also separate from catalog data and must be deployed from storage/app/public or shared object storage.

How file syncing works

  • Your project root is bind-mounted into the container at /var/www/html, so changes you make locally appear inside the container immediately.
  • vendor/ and node_modules/ are stored in Docker named volumes instead of being synced from Windows. This keeps file-watching and dependency installs fast.
  • The SQLite database (database/database.sqlite) and uploaded images (public/images/product-options/uploads/) live inside the bind-mounted project, so they persist across container restarts.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages