TeamUP is a project and activity management platform built to explore and master the Laravel ecosystem, from RESTful API design with Sanctum authentication to Eloquent ORM relationships and scheduled commands.
The backend is a fully structured Laravel 12 REST API, while the frontend is a React + TypeScript SPA built with Vite, consuming the API via Axios with token-based auth.
- Laravel 12 (PHP 8.2+)
- Laravel Sanctum β token-based API authentication
- Eloquent ORM β models, relationships, eager loading
- Laravel Scheduler β automated activity expiration via scheduled command
- RESTful API β resource controllers, middleware, route groups
- React 19 + TypeScript
- Vite
- Zustand (auth state management)
- Axios (API client with auth interceptor)
- React Router DOM v7
- Tailwind CSS v4
The API follows Laravel conventions with route-based resource separation, middleware protection, and clean controller logic.
routes/api.php β API route definitions
app/Http/Controllers/ β AuthController, UserController, ProjectController, ActivityController
app/Http/Middleware/ β RoleMiddleware (admin/user access control)
app/Models/ β User, Project, Activity (with Eloquent relations)
app/Console/Commands/ β ExpireActivities (scheduled command)
Key Laravel features used:
- Sanctum for stateless API token authentication
- RoleMiddleware restricting admin-only routes
- Eloquent eager loading for relations (project users, activities, owner)
- Scheduled command to automatically mark overdue activities as
expired - Unique token generation on project creation (join via token)
- Form Request validation across all endpoints
src/
βββ api/ β axios instance with auth interceptor
βββ services/ β authService, userService, projectService, activityService
βββ store/ β Zustand auth store (persisted)
βββ types/ β TypeScript types for all entities
βββ components/ β Header, modals, cards, StatsCards, ConfirmationModal...
βββ pages/ β Home, ProjectsList, ActivitiesList, ProjectPage, ActivityPage, ProfilePage...
βββ routes/ β PrivateRoute, PublicRoute, RedirectByRole...
Authentication is handled by Laravel Sanctum, issuing API tokens on login. Every protected request includes an Authorization: Bearer TOKEN header injected automatically by the Axios interceptor.
Role-based access control is enforced on the backend via RoleMiddleware:
| Role | Access |
|---|---|
admin |
Create/delete projects, manage users, view all data |
user |
Join projects, manage assigned activities, view own data |
users β id, name, email, password, role (admin/user)
projects β id, name, description, token, status (active/archived), owner_id
project_user β user_id, project_id, role_in_project (member/moderator), joined_at
activities β id, name, description, status (pending/in_progress/done/expired),
project_id, created_by_id, assigned_to_id, due_date
All relationships are managed with Eloquent β hasMany, belongsTo, belongsToMany β with eager loading on relevant endpoints to minimize queries.
A Laravel scheduled command runs automatically to expire overdue activities:
// Marks all activities as 'expired' where due_date < today and status != done
php artisan activities:expireRegistered in the Laravel scheduler to run daily.
All routes are prefixed with /api and protected with Sanctum middleware where required.
| Method | Endpoint | Access |
|---|---|---|
| POST | /register |
Public |
| POST | /login |
Public |
| POST | /logout |
Auth |
| Method | Endpoint | Access |
|---|---|---|
| GET | /me |
Auth |
| PATCH | /me |
Auth |
| DELETE | /me |
Auth |
| GET | /me/stats |
Auth |
| GET | /users |
Admin |
| GET | /users/{id} |
Admin |
| Method | Endpoint | Access |
|---|---|---|
| GET | /projects |
Auth |
| GET | /projects/my |
Auth |
| GET | /projects/{id} |
Auth |
| GET | /projects/{id}/users |
Auth |
| POST | /projects |
Admin |
| PATCH | /projects/{id} |
Auth |
| PATCH | /projects/{id}/status |
Auth |
| DELETE | /projects/{id} |
Auth |
| POST | /projects/join/{token} |
Auth |
| DELETE | /projects/{id}/leave |
Auth |
| Method | Endpoint | Access |
|---|---|---|
| GET | /activities |
Auth |
| GET | /activities/{id} |
Auth |
| POST | /activities |
Admin |
| PATCH | /activities/{id} |
Auth |
| DELETE | /activities/{id} |
Auth |
| POST | /activities/{id}/assign |
Auth |
| PATCH | /activities/{id}/complete |
Auth |
| PATCH | /activities/{id}/unassign |
Auth |
Activity listing supports optional filters:
GET /activities?status=pending
GET /activities?assigned_to_me=true
GET /activities?my_projects=true
GET /activities?project_status=active
- PHP 8.2+
- Composer
- Node.js 18+
- MySQL or PostgreSQL
# Clone the repository
git clone https://github.com/DavidEricson00/TeamUP.git
cd TeamUP/backend
# Install dependencies
composer install
# Configure environment
cp .env.example .env
php artisan key:generate
# Set up database in .env, then run migrations
php artisan migrate
# Start the server
php artisan serve
# (Optional) Run the scheduler manually
php artisan schedule:runcd frontend
# Install dependencies
npm install
# Configure API base URL in .env
VITE_API_URL=http://localhost:8000/api
# Start development server
npm run devTeamUP was built to:
- Deep dive into the Laravel ecosystem β Sanctum, Eloquent, Middleware, Scheduler, Resource Controllers
- Practice structuring a production-grade REST API with proper auth, validation, and role-based access
- Build a complete fullstack SPA integrating a Laravel backend with a React + TypeScript frontend
- Work with relational data modeling β pivot tables, eager loading, and complex query filters
- Handle real-world flows like project membership via invite tokens, activity assignment, and automated status expiration



