feat(exports): Add export functionality for brands, categories, formulas, perfumes, and products with Excel integration and UI buttons for user access
This commit is contained in:
parent
fb5e920a11
commit
2f9c73576b
132
app/Exports/BrandExport.php
Normal file
132
app/Exports/BrandExport.php
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Brand;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class BrandExport implements FromCollection, ShouldAutoSize, WithColumnWidths, WithEvents, WithHeadings, WithMapping, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return Brand::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Merek';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Nama',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
'Tanggal Diperbarui',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Brand $brand
|
||||||
|
*/
|
||||||
|
public function map($brand): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$brand->name,
|
||||||
|
formatDateLocalized($brand->created_at, 'd/m/Y H:i'),
|
||||||
|
formatDateLocalized($brand->updated_at, 'd/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 20, // Brand Name
|
||||||
|
'B' => 18, // Created Date
|
||||||
|
'C' => 18, // Updated Date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
$lastRow = $sheet->getHighestRow();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
// Header style
|
||||||
|
$headerStyle = [
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 12,
|
||||||
|
'color' => ['rgb' => 'FFFFFF'],
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => '71717A'], // Zinc - elegant
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Data rows style
|
||||||
|
$dataStyle = [
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_TOP,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Header styling
|
||||||
|
1 => $headerStyle,
|
||||||
|
|
||||||
|
// Data rows styling
|
||||||
|
'A2:'.$lastColumn.$lastRow => $dataStyle,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
// Auto-size columns with max width
|
||||||
|
foreach (range('A', 'C') as $column) {
|
||||||
|
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set row height for header
|
||||||
|
$event->sheet->getRowDimension(1)->setRowHeight(25);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
135
app/Exports/CategoryExport.php
Normal file
135
app/Exports/CategoryExport.php
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class CategoryExport implements FromCollection, ShouldAutoSize, WithColumnWidths, WithEvents, WithHeadings, WithMapping, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return Category::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Kategori';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Nama',
|
||||||
|
'Deskripsi',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
'Tanggal Diperbarui',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
*/
|
||||||
|
public function map($category): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$category->name,
|
||||||
|
strip_tags($category->description) ?: '-',
|
||||||
|
formatDateLocalized($category->created_at, 'd/m/Y H:i'),
|
||||||
|
formatDateLocalized($category->updated_at, 'd/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 20, // Category Name
|
||||||
|
'B' => 30, // Description
|
||||||
|
'C' => 18, // Created Date
|
||||||
|
'D' => 18, // Updated Date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
$lastRow = $sheet->getHighestRow();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
// Header style
|
||||||
|
$headerStyle = [
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 12,
|
||||||
|
'color' => ['rgb' => 'FFFFFF'],
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => '78716C'], // Stone - elegant
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Data rows style
|
||||||
|
$dataStyle = [
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_TOP,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Header styling
|
||||||
|
1 => $headerStyle,
|
||||||
|
|
||||||
|
// Data rows styling
|
||||||
|
'A2:'.$lastColumn.$lastRow => $dataStyle,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
// Auto-size columns with max width
|
||||||
|
foreach (range('A', 'D') as $column) {
|
||||||
|
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set row height for header
|
||||||
|
$event->sheet->getRowDimension(1)->setRowHeight(25);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
138
app/Exports/FormulaExport.php
Normal file
138
app/Exports/FormulaExport.php
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Formula;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class FormulaExport implements FromCollection, ShouldAutoSize, WithColumnWidths, WithEvents, WithHeadings, WithMapping, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return Formula::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Rumus';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Kualitas',
|
||||||
|
'Ukuran (ML)',
|
||||||
|
'Volume (ML)',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
'Tanggal Diperbarui',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Formula $formula
|
||||||
|
*/
|
||||||
|
public function map($formula): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$formula->quality,
|
||||||
|
$formula->size,
|
||||||
|
$formula->volume,
|
||||||
|
formatDateLocalized($formula->created_at, 'd/m/Y H:i'),
|
||||||
|
formatDateLocalized($formula->updated_at, 'd/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 18, // Quality
|
||||||
|
'B' => 15, // Size (ML)
|
||||||
|
'C' => 15, // Volume (ML)
|
||||||
|
'D' => 21, // Created Date
|
||||||
|
'E' => 21, // Updated Date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
$lastRow = $sheet->getHighestRow();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
// Header style
|
||||||
|
$headerStyle = [
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 12,
|
||||||
|
'color' => ['rgb' => 'FFFFFF'],
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => '475569'], // Slate - elegant
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Data rows style
|
||||||
|
$dataStyle = [
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_TOP,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Header styling
|
||||||
|
1 => $headerStyle,
|
||||||
|
|
||||||
|
// Data rows styling
|
||||||
|
'A2:'.$lastColumn.$lastRow => $dataStyle,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
// Auto-size columns with max width
|
||||||
|
foreach (range('A', 'E') as $column) {
|
||||||
|
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set row height for header
|
||||||
|
$event->sheet->getRowDimension(1)->setRowHeight(25);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
168
app/Exports/PerfumeExport.php
Normal file
168
app/Exports/PerfumeExport.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Perfume;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class PerfumeExport implements FromCollection, ShouldAutoSize, WithColumnWidths, WithEvents, WithHeadings, WithMapping, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return Perfume::with('brand')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Parfum';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Aroma',
|
||||||
|
'SKU',
|
||||||
|
'Merek',
|
||||||
|
'Konsentrasi',
|
||||||
|
'Harga Jual',
|
||||||
|
'Base Notes',
|
||||||
|
'Middle Notes',
|
||||||
|
'Top Notes',
|
||||||
|
'Deskripsi',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
'Tanggal Diperbarui',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Perfume $perfume
|
||||||
|
*/
|
||||||
|
public function map($perfume): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$perfume->name,
|
||||||
|
$perfume->sku,
|
||||||
|
$perfume->brand?->name,
|
||||||
|
$perfume->concentration->label(),
|
||||||
|
$perfume->sale_price,
|
||||||
|
$perfume->base_notes,
|
||||||
|
$perfume->middle_notes,
|
||||||
|
$perfume->top_notes,
|
||||||
|
strip_tags($perfume->description),
|
||||||
|
formatDateLocalized($perfume->created_at, 'd/m/Y H:i'),
|
||||||
|
formatDateLocalized($perfume->updated_at, 'd/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 28, // Perfume Name
|
||||||
|
'B' => 18, // SKU
|
||||||
|
'C' => 23, // Brand
|
||||||
|
'D' => 23, // Concentration
|
||||||
|
'E' => 18, // Sale Price
|
||||||
|
'F' => 23, // Base Notes
|
||||||
|
'G' => 23, // Middle Notes
|
||||||
|
'H' => 23, // Top Notes
|
||||||
|
'I' => 35, // Description
|
||||||
|
'J' => 21, // Created Date
|
||||||
|
'K' => 21, // Updated Date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
$lastRow = $sheet->getHighestRow();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
// Header style
|
||||||
|
$headerStyle = [
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 12,
|
||||||
|
'color' => ['rgb' => 'FFFFFF'],
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => '1E40AF'], // Navy Blue - elegant
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Data rows style
|
||||||
|
$dataStyle = [
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_TOP,
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_LEFT,
|
||||||
|
'indent' => 1, // Add padding
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Currency columns style (format currency)
|
||||||
|
$currencyStyle = [
|
||||||
|
'numberFormat' => [
|
||||||
|
'formatCode' => '"Rp" #,##0',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Header styling
|
||||||
|
1 => $headerStyle,
|
||||||
|
|
||||||
|
// Data rows styling
|
||||||
|
'A2:'.$lastColumn.$lastRow => $dataStyle,
|
||||||
|
|
||||||
|
// Currency columns styling
|
||||||
|
'E2:E'.$lastRow => $currencyStyle,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
// Auto-size columns with max width
|
||||||
|
foreach (range('A', 'K') as $column) {
|
||||||
|
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set row height for header
|
||||||
|
$event->sheet->getRowDimension(1)->setRowHeight(25);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
153
app/Exports/ProductExport.php
Normal file
153
app/Exports/ProductExport.php
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\Product;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
class ProductExport implements FromCollection, ShouldAutoSize, WithColumnWidths, WithEvents, WithHeadings, WithMapping, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return Product::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Produk Botol';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Nama',
|
||||||
|
'SKU',
|
||||||
|
'Harga Jual',
|
||||||
|
'Deskripsi',
|
||||||
|
'Tanggal Dibuat',
|
||||||
|
'Tanggal Diperbarui',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Product $product
|
||||||
|
*/
|
||||||
|
public function map($product): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$product->name,
|
||||||
|
$product->sku,
|
||||||
|
$product->sale_price,
|
||||||
|
strip_tags($product->description) ?: '-',
|
||||||
|
formatDateLocalized($product->created_at, 'd/m/Y H:i'),
|
||||||
|
formatDateLocalized($product->updated_at, 'd/m/Y H:i'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 28, // Product Name
|
||||||
|
'B' => 18, // SKU
|
||||||
|
'C' => 18, // Sale Price
|
||||||
|
'D' => 35, // Description
|
||||||
|
'E' => 21, // Created Date
|
||||||
|
'F' => 21, // Updated Date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
$lastRow = $sheet->getHighestRow();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
// Header style
|
||||||
|
$headerStyle = [
|
||||||
|
'font' => [
|
||||||
|
'bold' => true,
|
||||||
|
'size' => 12,
|
||||||
|
'color' => ['rgb' => 'FFFFFF'],
|
||||||
|
],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => '0F766E'], // Teal - elegant
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_CENTER,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Data rows style
|
||||||
|
$dataStyle = [
|
||||||
|
'borders' => [
|
||||||
|
'allBorders' => [
|
||||||
|
'borderStyle' => Border::BORDER_THIN,
|
||||||
|
'color' => ['rgb' => '000000'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'vertical' => Alignment::VERTICAL_TOP,
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_LEFT,
|
||||||
|
'indent' => 1, // Add padding
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Currency columns style (format currency)
|
||||||
|
$currencyStyle = [
|
||||||
|
'numberFormat' => [
|
||||||
|
'formatCode' => '"Rp" #,##0',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
// Header styling
|
||||||
|
1 => $headerStyle,
|
||||||
|
|
||||||
|
// Data rows styling
|
||||||
|
'A2:'.$lastColumn.$lastRow => $dataStyle,
|
||||||
|
|
||||||
|
// Currency columns styling
|
||||||
|
'C2:C'.$lastRow => $currencyStyle,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
// Auto-size columns with max width
|
||||||
|
foreach (range('A', 'F') as $column) {
|
||||||
|
$event->sheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set row height for header
|
||||||
|
$event->sheet->getRowDimension(1)->setRowHeight(25);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
69
app/Http/Controllers/ExportController.php
Normal file
69
app/Http/Controllers/ExportController.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Exports\BrandExport;
|
||||||
|
use App\Exports\CategoryExport;
|
||||||
|
use App\Exports\FormulaExport;
|
||||||
|
use App\Exports\PerfumeExport;
|
||||||
|
use App\Exports\ProductExport;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
|
||||||
|
class ExportController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Export perfumes to Excel
|
||||||
|
*/
|
||||||
|
public function perfumes(): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new PerfumeExport,
|
||||||
|
'data_parfum_'.now()->format('Y-m-d_H-i-s').'.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export products to Excel
|
||||||
|
*/
|
||||||
|
public function products(): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new ProductExport,
|
||||||
|
'data_produk_botol_'.now()->format('Y-m-d_H-i-s').'.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export formulas to Excel
|
||||||
|
*/
|
||||||
|
public function formulas(): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new FormulaExport,
|
||||||
|
'data_rumus_'.now()->format('Y-m-d_H-i-s').'.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export categories to Excel
|
||||||
|
*/
|
||||||
|
public function categories(): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new CategoryExport,
|
||||||
|
'data_kategori_'.now()->format('Y-m-d_H-i-s').'.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export brands to Excel
|
||||||
|
*/
|
||||||
|
public function brands(): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(
|
||||||
|
new BrandExport,
|
||||||
|
'data_merek_'.now()->format('Y-m-d_H-i-s').'.xlsx'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@
|
|||||||
"livewire/flux": "2.2.5",
|
"livewire/flux": "2.2.5",
|
||||||
"livewire/flux-pro": "2.2.5",
|
"livewire/flux-pro": "2.2.5",
|
||||||
"livewire/livewire": "^3.6",
|
"livewire/livewire": "^3.6",
|
||||||
|
"maatwebsite/excel": "^3.1",
|
||||||
"minishlink/web-push": "^9.0",
|
"minishlink/web-push": "^9.0",
|
||||||
"rappasoft/laravel-livewire-tables": "^3.7",
|
"rappasoft/laravel-livewire-tables": "^3.7",
|
||||||
"spatie/laravel-activitylog": "^4.10",
|
"spatie/laravel-activitylog": "^4.10",
|
||||||
|
|||||||
2
composer.lock
generated
2
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "c3882fb2ea84252fd7d1709795007970",
|
"content-hash": "a6ef280e8ed158371bb27e1088a51102",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "archtechx/enums",
|
"name": "archtechx/enums",
|
||||||
|
|||||||
@ -3,15 +3,22 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@can('create brand')
|
<div class="flex gap-2">
|
||||||
<div>
|
@can('view brand')
|
||||||
|
<a href="{{ route('studio.export.brands') }}" class="inline-flex">
|
||||||
|
<flux:button variant="primary" color="zinc" class="text-sm">
|
||||||
|
Ekspor Ecxel
|
||||||
|
</flux:button>
|
||||||
|
</a>
|
||||||
|
@endcan
|
||||||
|
@can('create brand')
|
||||||
<flux:modal.trigger name="form-modal">
|
<flux:modal.trigger name="form-modal">
|
||||||
<flux:button variant="primary" class="text-sm"
|
<flux:button variant="primary" class="text-sm"
|
||||||
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Merek'})">Tambah
|
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Merek'})">Tambah
|
||||||
</flux:button>
|
</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
</div>
|
@endcan
|
||||||
@endcan
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|||||||
@ -3,15 +3,22 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@can('create category')
|
<div class="flex gap-2">
|
||||||
<div>
|
@can('view category')
|
||||||
|
<a href="{{ route('studio.export.categories') }}" class="inline-flex">
|
||||||
|
<flux:button variant="primary" color="zinc" class="text-sm">
|
||||||
|
Ekspor Ecxel
|
||||||
|
</flux:button>
|
||||||
|
</a>
|
||||||
|
@endcan
|
||||||
|
@can('create category')
|
||||||
<flux:modal.trigger name="form-modal">
|
<flux:modal.trigger name="form-modal">
|
||||||
<flux:button variant="primary" class="text-sm"
|
<flux:button variant="primary" class="text-sm"
|
||||||
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Kategori'})">Tambah
|
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Kategori'})">Tambah
|
||||||
</flux:button>
|
</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
</div>
|
@endcan
|
||||||
@endcan
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
@ -32,8 +39,7 @@
|
|||||||
|
|
||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Nama <span class="text-red-500 ms-1">*</span></flux:label>
|
<flux:label>Nama <span class="text-red-500 ms-1">*</span></flux:label>
|
||||||
<flux:input placeholder="Aromaterapi" wire:model="form.name" autofocus
|
<flux:input placeholder="Aromaterapi" wire:model="form.name" autofocus autocomplete="off" />
|
||||||
autocomplete="off" />
|
|
||||||
<flux:error name="form.name" />
|
<flux:error name="form.name" />
|
||||||
</flux:field>
|
</flux:field>
|
||||||
|
|
||||||
|
|||||||
@ -3,14 +3,21 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@can('create perfume')
|
<div class="flex gap-2">
|
||||||
<div>
|
@can('view perfume')
|
||||||
|
<a href="{{ route('studio.export.perfumes') }}" class="inline-flex">
|
||||||
|
<flux:button variant="primary" color="zinc" class="text-sm">
|
||||||
|
Ekspor Ecxel
|
||||||
|
</flux:button>
|
||||||
|
</a>
|
||||||
|
@endcan
|
||||||
|
@can('create perfume')
|
||||||
<flux:button href="{{ route('studio.catalog.perfume.create') }}" variant="primary" wire:navigate
|
<flux:button href="{{ route('studio.catalog.perfume.create') }}" variant="primary" wire:navigate
|
||||||
class="text-sm">
|
class="text-sm">
|
||||||
Tambah
|
Tambah
|
||||||
</flux:button>
|
</flux:button>
|
||||||
</div>
|
@endcan
|
||||||
@endcan
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|||||||
@ -3,14 +3,21 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@can('create product')
|
<div class="flex gap-2">
|
||||||
<div>
|
@can('view product')
|
||||||
|
<a href="{{ route('studio.export.products') }}" class="inline-flex">
|
||||||
|
<flux:button variant="primary" color="zinc" class="text-sm">
|
||||||
|
Ekspor Ecxel
|
||||||
|
</flux:button>
|
||||||
|
</a>
|
||||||
|
@endcan
|
||||||
|
@can('create product')
|
||||||
<flux:button href="{{ route('studio.catalog.product.create') }}" variant="primary" wire:navigate
|
<flux:button href="{{ route('studio.catalog.product.create') }}" variant="primary" wire:navigate
|
||||||
class="text-sm">
|
class="text-sm">
|
||||||
Tambah
|
Tambah
|
||||||
</flux:button>
|
</flux:button>
|
||||||
</div>
|
@endcan
|
||||||
@endcan
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|||||||
@ -3,15 +3,22 @@
|
|||||||
<div>
|
<div>
|
||||||
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@can('create formula')
|
<div class="flex gap-2">
|
||||||
<div>
|
@can('view formula')
|
||||||
|
<a href="{{ route('studio.export.formulas') }}" class="inline-flex">
|
||||||
|
<flux:button variant="primary" color="zinc" class="text-sm">
|
||||||
|
Ekspor Ecxel
|
||||||
|
</flux:button>
|
||||||
|
</a>
|
||||||
|
@endcan
|
||||||
|
@can('create formula')
|
||||||
<flux:modal.trigger name="form-modal">
|
<flux:modal.trigger name="form-modal">
|
||||||
<flux:button variant="primary" class="text-sm"
|
<flux:button variant="primary" class="text-sm"
|
||||||
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Rumus'})">Tambah
|
wire:click="$dispatch('modal:open', {method: 'create', 'modalTitle': 'Tambah Rumus'})">Tambah
|
||||||
</flux:button>
|
</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
</div>
|
@endcan
|
||||||
@endcan
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
@ -25,7 +32,7 @@
|
|||||||
</flux:heading>
|
</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
@foreach ($formula as $item)
|
@foreach ($formula as $item)
|
||||||
<flux:callout variant="secondary" inline>
|
<flux:callout variant="primary" color="zinc" inline>
|
||||||
<div class="flex items-center space-x-1">
|
<div class="flex items-center space-x-1">
|
||||||
<flux:callout.heading>{{ $item['quality'] }}</flux:callout.heading>
|
<flux:callout.heading>{{ $item['quality'] }}</flux:callout.heading>
|
||||||
<flux:text class="text-xs text-gray-400">({{ $item['volume'] }} ml)</flux:text>
|
<flux:text class="text-xs text-gray-400">({{ $item['volume'] }} ml)</flux:text>
|
||||||
@ -80,8 +87,7 @@
|
|||||||
|
|
||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Kualitas <span class="text-red-500 ms-1">*</span></flux:label>
|
<flux:label>Kualitas <span class="text-red-500 ms-1">*</span></flux:label>
|
||||||
<flux:select variant="listbox" searchable placeholder="Pilih Kualitas"
|
<flux:select variant="listbox" searchable placeholder="Pilih Kualitas" wire:model="form.quality">
|
||||||
wire:model="form.quality">
|
|
||||||
@foreach ($qualities as $key => $value)
|
@foreach ($qualities as $key => $value)
|
||||||
<flux:select.option value="{{ $value }}">{{ $value }}
|
<flux:select.option value="{{ $value }}">{{ $value }}
|
||||||
</flux:select.option>
|
</flux:select.option>
|
||||||
@ -92,8 +98,7 @@
|
|||||||
|
|
||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Ukuran <span class="text-red-500 ms-1">*</span></flux:label>
|
<flux:label>Ukuran <span class="text-red-500 ms-1">*</span></flux:label>
|
||||||
<flux:select variant="listbox" searchable placeholder="Pilih Ukuran"
|
<flux:select variant="listbox" searchable placeholder="Pilih Ukuran" wire:model="form.size">
|
||||||
wire:model="form.size">
|
|
||||||
@foreach ($sizes as $key => $value)
|
@foreach ($sizes as $key => $value)
|
||||||
<flux:select.option value="{{ $value }}">{{ $value }} ml
|
<flux:select.option value="{{ $value }}">{{ $value }} ml
|
||||||
</flux:select.option>
|
</flux:select.option>
|
||||||
@ -105,8 +110,8 @@
|
|||||||
<flux:field>
|
<flux:field>
|
||||||
<flux:label>Volume <span class="text-red-500 ms-1">*</span></flux:label>
|
<flux:label>Volume <span class="text-red-500 ms-1">*</span></flux:label>
|
||||||
<flux:input.group>
|
<flux:input.group>
|
||||||
<flux:input placeholder="20" x-mask:dynamic="$money($input, ',')"
|
<flux:input placeholder="20" x-mask:dynamic="$money($input, ',')" wire:model="form.volume"
|
||||||
wire:model="form.volume" autocomplete="off" />
|
autocomplete="off" />
|
||||||
<flux:input.group.suffix>ml</flux:input.group.suffix>
|
<flux:input.group.suffix>ml</flux:input.group.suffix>
|
||||||
</flux:input.group>
|
</flux:input.group>
|
||||||
<flux:error name="form.volume" />
|
<flux:error name="form.volume" />
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\ExportController;
|
||||||
use App\Livewire\Studio\Catalog\Bottle\Audit as BottleAudit;
|
use App\Livewire\Studio\Catalog\Bottle\Audit as BottleAudit;
|
||||||
use App\Livewire\Studio\Catalog\Bottle\Create as BottleCreate;
|
use App\Livewire\Studio\Catalog\Bottle\Create as BottleCreate;
|
||||||
use App\Livewire\Studio\Catalog\Bottle\Edit as BottleEdit;
|
use App\Livewire\Studio\Catalog\Bottle\Edit as BottleEdit;
|
||||||
@ -186,4 +187,13 @@
|
|||||||
Route::get('/', ChooseUsComponent::class)->name('index')->middleware('can:view choose us');
|
Route::get('/', ChooseUsComponent::class)->name('index')->middleware('can:view choose us');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Export Routes
|
||||||
|
Route::prefix('export')->name('studio.export.')->group(function () {
|
||||||
|
Route::get('/perfumes', [ExportController::class, 'perfumes'])->name('perfumes')->middleware('can:view perfume');
|
||||||
|
Route::get('/products', [ExportController::class, 'products'])->name('products')->middleware('can:view product');
|
||||||
|
Route::get('/formulas', [ExportController::class, 'formulas'])->name('formulas')->middleware('can:view formula');
|
||||||
|
Route::get('/categories', [ExportController::class, 'categories'])->name('categories')->middleware('can:view category');
|
||||||
|
Route::get('/brands', [ExportController::class, 'brands'])->name('brands')->middleware('can:view brand');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user