generated from theradcoza/Laravel-Docker-Dev-Template
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bc6781e17 | ||
|
|
c936670573 | ||
| 2475daca4b |
48
README.md
48
README.md
@@ -28,10 +28,52 @@ A shift management application for scheduling staff, tracking attendance, and ge
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
- Docker & Docker Compose
|
||||
## Prerequisites
|
||||
|
||||
### Setup
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop) installed
|
||||
- [Docker Compose](https://docs.docker.com/compose/) (usually included with Docker Desktop)
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Clone the repository:**
|
||||
```sh
|
||||
git clone <your-repo-url>
|
||||
cd bhoza-shift-manager
|
||||
```
|
||||
|
||||
2. **Copy the example environment file:**
|
||||
```sh
|
||||
cp src/.env.example src/.env
|
||||
# Or manually create src/.env based on src/.env.example
|
||||
```
|
||||
|
||||
3. **Start the app with MariaDB:**
|
||||
```sh
|
||||
docker-compose --profile mysql up -d
|
||||
```
|
||||
This will start the app, Nginx, MariaDB, Redis, and Mailpit containers.
|
||||
|
||||
4. **Install Composer dependencies:**
|
||||
```sh
|
||||
docker-compose exec app composer install
|
||||
```
|
||||
|
||||
5. **Generate the application key:**
|
||||
```sh
|
||||
docker-compose exec app php artisan key:generate
|
||||
```
|
||||
|
||||
6. **Run database migrations and seeders:**
|
||||
```sh
|
||||
docker-compose exec app php artisan migrate --seed
|
||||
```
|
||||
|
||||
7. **Access the app:**
|
||||
- Web: [http://localhost:8080](http://localhost:8080)
|
||||
- Admin: [http://localhost:8080/admin/login](http://localhost:8080/admin/login)
|
||||
- Mailpit: [http://localhost:8025](http://localhost:8025)
|
||||
|
||||
### Setup(Maybe you should run the one above 🤷🏿♂️)
|
||||
|
||||
```bash
|
||||
git clone <repo-url> bhoza-shift-manager
|
||||
|
||||
@@ -56,7 +56,7 @@ public static function form(Form $form): Form
|
||||
Forms\Components\Select::make('staffMembers')
|
||||
->label('Assign Staff')
|
||||
->multiple()
|
||||
->relationship('staff', 'name')
|
||||
->options(User::query()->pluck('name', 'id'))
|
||||
->preload()
|
||||
->searchable(),
|
||||
])
|
||||
|
||||
@@ -17,4 +17,17 @@ protected function mutateFormDataBeforeCreate(array $data): array
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
$staffIds = $this->data['staffMembers'] ?? [];
|
||||
|
||||
if (empty($staffIds)) {
|
||||
return;
|
||||
}
|
||||
$this->record->staff()->syncWithPivotValues(
|
||||
$staffIds,
|
||||
['assigned_by' => auth()->id()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,4 +54,14 @@ protected function getHeaderActions(): array
|
||||
->visible(fn () => $this->record->isPlanned()),
|
||||
];
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
$staffIds = $this->data['staffMembers'] ?? [];
|
||||
|
||||
$this->record->staff()->syncWithPivotValues(
|
||||
$staffIds,
|
||||
['assigned_by' => auth()->id()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,13 @@ public function table(Table $table): Table
|
||||
Tables\Actions\AttachAction::make()
|
||||
->label('Add Staff')
|
||||
->preloadRecordSelect()
|
||||
->visible(fn () => $this->getOwnerRecord()->isPlanned()),
|
||||
->visible(fn () => $this->getOwnerRecord()->isPlanned())
|
||||
->action(function (array $data, $ownerRecord) {
|
||||
$staffId = $data['record'] ?? null;
|
||||
if ($staffId) {
|
||||
app(\App\Services\ShiftService::class)->assignStaff($ownerRecord, [$staffId]);
|
||||
}
|
||||
}),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\DetachAction::make()
|
||||
|
||||
@@ -29,6 +29,7 @@ public function createShift(array $data, ?array $staffIds = null): Shift
|
||||
]);
|
||||
|
||||
if ($staffIds) {
|
||||
logger()->info('Staff IDs:', $staffIds);
|
||||
$this->assignStaff($shift, $staffIds);
|
||||
}
|
||||
|
||||
@@ -102,6 +103,11 @@ public function assignStaff(Shift $shift, array $staffIds): void
|
||||
}
|
||||
|
||||
$managerId = Auth::id();
|
||||
|
||||
if(!$managerId) {
|
||||
throw new InvalidArgumentException('Authenticated user is required to assign staff.');
|
||||
}
|
||||
|
||||
$syncData = [];
|
||||
|
||||
foreach ($staffIds as $staffId) {
|
||||
|
||||
@@ -13,11 +13,24 @@ class DatabaseSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// Create the admin user
|
||||
User::factory()->create([
|
||||
'name' => 'Admin User',
|
||||
'email' => 'admin@example.com',
|
||||
]);
|
||||
|
||||
// Create 10 random staff users
|
||||
User::factory()->create(['name' => 'Staff One', 'email' => 'staff1@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Two', 'email' => 'staff2@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Three', 'email' => 'staff3@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Four', 'email' => 'staff4@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Five', 'email' => 'staff5@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Six', 'email' => 'staff6@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Seven', 'email' => 'staff7@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Eight', 'email' => 'staff8@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Nine', 'email' => 'staff9@example.com']);
|
||||
User::factory()->create(['name' => 'Staff Ten', 'email' => 'staff10@example.com']);
|
||||
|
||||
$this->call(RolePermissionSeeder::class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user