This repository houses an experimental E-commerce dashboard that serves as a practical application for learning and implementing Laravel. I scaffolded this with Laravel Breeze and use Laravel Valet for local development.
- CRUD Operations: Comprehensive Create, Read, Update, and Delete functionalities for products and customers, showcasing Laravel's robust back-end capabilities.
- Laravel 10: A powerful PHP framework for building scalable web applications with a clean, expressive syntax.
- TypeScript: A superset of JavaScript that adds static type definitions, enabling a more robust development experience.
- Vue.js 3: A dynamic and reactive frontend built with Vue.js, offering an engaging user experience.
- Ziggy: Exposes Laravel's named server-side routes via a global
route()
function, allowing for easy route generation in Vue components. - Inertia.js: Bridges Laravel and Vue.js, enabling server-side rendering and client-side navigation without page reloads.
- TailwindCSS: A utility-first CSS framework used for designing sleek, responsive layouts with speed and efficiency.
- Storybook: A development environment for UI components, allowing for rapid iteration and testing.
- Atomic Design: A methodology for designing UIs with a focus on reusability and scalability.
- Tests: Unit tests for all models and controllers using PHPUnit, and component tests for Vue.js components using Vitest and Vue Test Utils.
- Linting and Formatting: Automatic linting and formatting for PHP, JavaScript, CSS and Vue.js files.
- Github Actions: Continuous integration and testing with Github Actions.
- Mastering Laravel's MVC architecture for building scalable web applications.
- Implementing SPA behaviors in Laravel with Vue.js and Inertia.js.
- Developing intuitive UIs with Tailwind CSS.
- Understanding state management and reactivity in Vue.js.
- Grasping the principles of RESTful API design and CRUD operations in Laravel.
- Writing unit tests for models and controllers with PHPUnit and Vitest.
- Products: Includes features like product listing, adding new products, editing, and deleting.
- Customers: Manages customer data with functionalities for adding, viewing, editing, and removing customer records.
- Orders: Allows users to place orders for products, with a dedicated page for viewing all orders.
- Reports: Provides a dashboard for viewing sales reports and other metrics.
This project serves as a comprehensive example for anyone interested in developing full-featured web applications using these technologies.
Clone the repository (into your Valet sites directory):
git clone [email protected]:gregrickaby/vue-commerce-lab.git
Install dependencies:
composer install && npm install
Create .env
file:
cp .env.example .env
Create database.sqlite
file:
touch database/database.sqlite
Generate application key:
php artisan key:generate
Run a migration:
php artisan migrate:fresh
Seed the database:
php artisan db:seed
Set the PHP version to 8.3:
valet isolate [email protected]
Secure the site:
valet secure
Start development server:
npm run dev
Visit the site: https://vue-commerce-lab.test and login with the following credentials:
- user: [email protected]
- pass:
password
Models are located in the app/Models
directory. Each model has a corresponding factory and seeder in the database/factories
and database/seeders
directories.
Models are responsible for managing the data of the application. They receive input from the controller, validate it, then send it to the database.
This application uses Vue and Inertia, so the views are in the resources/js/pages
directory and routed via the web.php file.
Views are responsible for displaying the data to the user. They receive data from the controller, then render it to the browser.
Controllers are located in the app/Http/Controllers
directory. Each controller has a corresponding test in the tests/Feature
directory
Controllers are responsible for handling requests and returning responses. They receive input from the user, validate it, then pass it to the model.
Routes are located in the routes
directory. The web.php
file contains all the routes for the application.
Vue.js files are located in the resources/js
directory.
The directory structure follows standard Laravel conventions, with the addition of a types
directory for TypeScript interfaces and types, and a utils
directory for utility and helper functions.
โโโ resources
โ โโโ css
โ โ โโโ app.css <-- TailwindCSS
โ โโโ js
โ โ โโโ Components
โ โ โ โโโ Atoms
โ โ โ โ โโโ ApplicationLogo
โ โ โ โ โ โโโ ApplicationLogo.stories.ts <-- Storybook
โ โ โ โ โ โโโ ApplicationLogo.test.ts <-- Test
โ โ โ โ โ โโโ ApplicationLogo.test.ts.snap <-- Snapshot
โ โ โ โ โ โโโ ApplicationLogo.vue <-- Vue Component
โ โ โ โโโ Molecules
โ โ โ โโโ Organisms
โ โ โโโ Layouts
โ โ โโโ Pages
โ โ โ โโโ Customers
โ โ โ โ โโโ Create.vue
โ โ โ โ โโโ Index.vue
โ โ โ โ โโโ {customer} <-- Dynamic route
โ โ โ โ โโโ Edit.vue
โ โ โ โ โโโ Show.vue
โ โ โโโ app.ts <-- Vue app
โ โ โโโ types
โ โ โ โโโ index.d.ts <-- Typescript interfaces and types
โ โ โโโ utils
โ โ โโโ index.ts <-- Utility and helper functions
โ โโโ views
โ โโโ app.blade.php
โ โโโ welcome.blade.php
Folders with a {}
around them are dynamic routes. For example, /Pages/Customers/{customers}/Edit.vue
is a dynamic route that will match any customer ID. The ID is then available in the Edit.vue
component.
This application is equipped with both PHPUnit and Vitest for testing. It also leverages Github Actions for continuous integration and testing, and Storybook for developing UI components in isolation.
This application is equipped with PHPUnit tests for all models and controllers. PHP tests are located in the /tests
directory:
โโโ tests
โ โโโ Feature
โ โ โโโ Auth
โ โ โ โโโ AuthenticationTest.php
โ โ โโโ ExampleTest.php
โ โโโ Unit
โ โโโ ExampleTest.php
Laravel routes return Inertia responses that depend on the presence of Vue components. Without the built front-end assets, these components won't be available, leading to failures in tests that make requests to these routes. To avoid this, you must run the development server in the background while running tests.
Start the development server:
npm run dev
Run PHPUnit tests with:
php artisan test
Run a specific test with:
php artisan test --filter=CustomerTest
This application is equipped with both Vitest (official test runner) and Vue Test Utils (official testing library) for testing Vue components. Tests must be placed next to the component and named ComponentName.test.ts
:
โโโ resources
โ โโโ js
โ โ โโโ Components
โ โ โ โโโ Atoms
โ โ โ โ โโโ ApplicationLogo
โ โ โ โ โ โโโ ApplicationLogo.stories.ts <-- Storybook
โ โ โ โ โ โโโ ApplicationLogo.test.ts <-- Test
โ โ โ โ โ โโโ ApplicationLogo.test.ts.snap <-- Snapshot
โ โ โ โ โ โโโ ApplicationLogo.vue <-- Vue Component
You can run the tests with:
npm run test
Vitest will run the tests in watch mode, so you can make changes to the component and see the results in real-time.
Component tests are written in TypeScript and use the Vitest API for assertions. Here's an example:
import ApplicationLogo from '@/Components/Atoms/ApplicationLogo/ApplicationLogo.vue'
import { mount } from '@vue/test-utils'
import { describe, expect, test } from 'vitest'
/**
* Define a test suite.
*
* @see https://vitest.dev/api/#describe
*/
describe('ApplicationLogo', () => {
/**
* Mount the component.
*
* @see https://vue-test-utils.vuejs.org/api/#mount
*/
const wrapper = mount(ApplicationLogo)
/**
* Assert the component renders.
*
* @see https://vitest.dev/api/expect.html
*/
test('component renders', () => {
expect(wrapper).toBeTruthy()
})
/**
* Assert the component is a SVG.
*/
test('component is SVG', () => {
wrapper.find('svg')
})
/**
* Assert the component matches the snapshot.
*
* @see https://vitest.dev/api/expect.html#tomatchsnapshot
*/
test('component matches snapshot', () => {
expect(wrapper.html()).toMatchSnapshot()
})
})
Github Actions will also run the tests on every PR to the main
branch.
This application is equipped with ESLint and configured for parsing TypeScript. Automatic linting JavaScript and Vue files happens on_save
.
You can also run lint manually:
npm run lint
This application is equipped with Stylelint and the Prettier plugin for TailwindCSS. Automatic linting and formatting happens on_save
.
Automatic formatting for both JavaScript and PHP files is configured for on_save
. Please see the VSCode settings and extension configs for more information.
Manually run Prettier and Pint with:
npm run format && composer run lint
View Storybook: https://gregrickaby.github.io/vue-commerce-lab/ ๐
This application is equipped with Storybook for developing UI components in isolation. Stories must be written in CSF, placed next to the component in the resources/js/Components
directory. Stories must be named ComponentName.stories.ts
:
โโโ resources
โ โโโ js
โ โ โโโ Components
โ โ โ โโโ Atoms
โ โ โ โ โโโ ApplicationLogo
โ โ โ โ โ โโโ ApplicationLogo.stories.ts <-- Storybook
โ โ โ โ โ โโโ ApplicationLogo.test.ts <-- Test
โ โ โ โ โ โโโ ApplicationLogo.test.ts.snap <-- Snapshot
โ โ โ โ โ โโโ ApplicationLogo.vue <-- Vue Component
Run Storybook with:
npm run storybook
Build Storybook with:
npm run build:storybook
The MIT License (MIT). Please see LICENSE