Chinh sua giao dien phu hop tailwind css va upload
This commit is contained in:
75
AGENTS.md
75
AGENTS.md
@@ -424,3 +424,78 @@ $user->assignRole('manager');
|
||||
13. **i18n - ChartWidget heading**: `$heading`/`$description` are raw properties — must override `getHeading()`/`getDescription()`.
|
||||
14. **i18n - form labels**: Form fields without `->label()` use Filament's `filament-panels::` namespace — always add explicit `->label(__('key'))`.
|
||||
15. **i18n - Filament vendor**: Filament ships 57 Vietnamese translation files — auto-activated when `APP_LOCALE=vi`.
|
||||
16. **FileUpload disk**: Always use `disk('public')` for all FileUpload components. NEVER use `disk('local')` — causes file not found errors.
|
||||
17. **FileUpload dehydrated**: Do NOT use `dehydrated(false)` — prevents file paths from being available in afterSave()/afterCreate(). Use property to store paths in mutateFormDataBeforeSave().
|
||||
18. **File metadata safety**: Always check `$disk->exists($path)` before calling `$disk->mimeType()` or `$disk->size()` — prevents UnableToRetrieveMetadata error.
|
||||
19. **FileUpload in Actions**: When handling file uploads in Action callbacks (e.g., transfer attachments), file paths are strings (not UploadedFile). Create records directly instead of using FileService::upload().
|
||||
20. **Tailwind CSS in Filament**: Custom blade views render inside Filament layout which does NOT include full Tailwind CSS build. Must add needed utilities to `public/css/filament-custom.css` with `!important`.
|
||||
21. **SVG icon sizing**: Use inline `width`/`height` attributes on SVG icons (e.g., `<svg width="14" height="14">`) instead of Tailwind classes (`w-3.5 h-3.5`) — prevents Filament CSS from overriding sizes.
|
||||
|
||||
## File Upload Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FileUpload Component (disk='public') │
|
||||
│ → Filament uploads via AJAX to storage/app/public/ │
|
||||
│ → File path stored in Livewire state │
|
||||
│ │
|
||||
│ Form Submit │
|
||||
│ → mutateFormDataBeforeSave() stores paths in property │
|
||||
│ → Removes 'attachments' from $data before saving model │
|
||||
│ │
|
||||
│ afterSave()/afterCreate() │
|
||||
│ → Uses stored paths to create FeedbackAttachment records │
|
||||
│ → Checks $disk->exists($path) before getting metadata │
|
||||
│ → Uses asset('storage/' . $path) for URLs │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### FileUpload Pattern (correct):
|
||||
```php
|
||||
// In Form
|
||||
FileUpload::make('attachments')
|
||||
->disk('public') // ALWAYS public
|
||||
->directory('feedback-attachments')
|
||||
// Do NOT use ->dehydrated(false)
|
||||
|
||||
// In Page class
|
||||
protected array $pendingAttachments = [];
|
||||
|
||||
protected function mutateFormDataBeforeSave(array $data): array
|
||||
{
|
||||
$this->pendingAttachments = $data['attachments'] ?? [];
|
||||
unset($data['attachments']); // Remove before saving model
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
$disk = Storage::disk('public');
|
||||
foreach ($this->pendingAttachments as $path) {
|
||||
if (! $disk->exists($path)) continue; // Safety check
|
||||
|
||||
$this->getRecord()->attachments()->create([
|
||||
'path' => $path,
|
||||
'disk' => 'public',
|
||||
'mime_type' => $disk->mimeType($path),
|
||||
'size' => $disk->size($path),
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Tailwind CSS in Filament (correct):
|
||||
```php
|
||||
// Filament uses its own CSS build, NOT the project's Tailwind build
|
||||
// Custom blade views need utilities added to public/css/filament-custom.css
|
||||
|
||||
// In filament-custom.css:
|
||||
.flex { display: flex !important; }
|
||||
.items-center { align-items: center !important; }
|
||||
.gap-2 { gap: 0.5rem !important; }
|
||||
// ... add all needed utilities with !important
|
||||
|
||||
// For SVG icons, use inline attributes:
|
||||
<svg width="14" height="14" class="text-blue-600">...</svg>
|
||||
// NOT: <svg class="w-3.5 h-3.5 text-blue-600">...</svg>
|
||||
|
||||
Reference in New Issue
Block a user