Compare commits
49 Commits
b405cad6fe
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bc56a1824f | |||
| 6405150dd2 | |||
| 1a3f82b22c | |||
| 0b6cbc8d9e | |||
| 834822e182 | |||
| e927a912e1 | |||
| 643ccd6d9e | |||
| 3e80ea4d5e | |||
| fe42967a74 | |||
| a1826ae53c | |||
| c7e01f404d | |||
| 0a3fdf347f | |||
| e97a80bfdb | |||
| dd167d9aaa | |||
| 8f36f7d715 | |||
| 453e8caa82 | |||
| 76397637f0 | |||
| 8e770941fa | |||
| c37f5fadf1 | |||
| 287fbf55f9 | |||
| 3ca39597a2 | |||
| affe615592 | |||
| c1770cafa5 | |||
| d4403ce365 | |||
| b9bc8fbcee | |||
| f6ddf1d9c1 | |||
| 9603402fee | |||
| 1f8888d31c | |||
| 330fc76ed3 | |||
| a627c85416 | |||
| f9f08c7adf | |||
| 8a2166bd78 | |||
| a89e2a71d8 | |||
| 9b3ca3ff66 | |||
| 41abdb6fc8 | |||
| 6b0c92d838 | |||
| 1b4989b440 | |||
| e2323c7949 | |||
| b23f537086 | |||
| 7fdb99cc79 | |||
| 74fc3b5e6a | |||
| 189cb53856 | |||
| d316f392bc | |||
| 2d1c7ea4f9 | |||
| bae4204d44 | |||
| 1ceccb0d79 | |||
| ed369a5bf2 | |||
| 6d564bb285 | |||
| fb4479929d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ yarn-error.log
|
||||
/.vscode
|
||||
/.zed
|
||||
**/.DS_Store
|
||||
IntelephenseHelper.php
|
||||
|
||||
259
app/Filament/Pages/AboutPageSettings.php
Normal file
259
app/Filament/Pages/AboutPageSettings.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\AboutSettings;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class AboutPageSettings extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'CMS';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-information-circle';
|
||||
|
||||
protected static string $settings = AboutSettings::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make('Our Story Section')
|
||||
->description("Manage the 'Our Story' content on the About Us page.")
|
||||
->icon('heroicon-o-book-open')
|
||||
->schema([
|
||||
TextInput::make('our_story_title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('our_story_subtitle')
|
||||
->label('Subtitle')
|
||||
->rows(2)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
Textarea::make('our_story_paragraph_one')
|
||||
->label('Paragraph One')
|
||||
->rows(4)
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
Textarea::make('our_story_paragraph_two')
|
||||
->label('Paragraph Two')
|
||||
->rows(4)
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
Textarea::make('our_story_paragraph_three')
|
||||
->label('Paragraph Three')
|
||||
->rows(4)
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
Grid::make(2)->schema([
|
||||
TextInput::make('our_story_button_text')
|
||||
->label('Button Text')
|
||||
->maxLength(50)
|
||||
->required(),
|
||||
TextInput::make('our_story_button_url')
|
||||
->label('Button URL')
|
||||
->url()
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
]),
|
||||
FileUpload::make('our_story_video_poster')
|
||||
->label('Video Poster Image')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('about-us')
|
||||
->required(),
|
||||
FileUpload::make('our_story_video_source')
|
||||
->label('Video Source File')
|
||||
->acceptedFileTypes(['video/mp4', 'video/webm', 'video/ogg'])
|
||||
->maxSize(102400) // 100MB
|
||||
->disk('public')
|
||||
->directory('about-us-videos')
|
||||
->required(),
|
||||
]),
|
||||
|
||||
Section::make('Our Journey Section')
|
||||
->description("Manage the 'Our Journey' milestones on the About Us page.")
|
||||
->icon('heroicon-o-map')
|
||||
->schema([
|
||||
TextInput::make('our_journey_title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('our_journey_subtitle')
|
||||
->label('Subtitle')
|
||||
->rows(2)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
Repeater::make('our_journey_milestones')
|
||||
->label('Milestones')
|
||||
->schema([
|
||||
TextInput::make('year')
|
||||
->label('Year')
|
||||
->numeric()
|
||||
->required(),
|
||||
TextInput::make('title')
|
||||
->label('Milestone Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('description')
|
||||
->label('Description')
|
||||
->rows(3)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
FileUpload::make('image')
|
||||
->label('Image')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('about-us-milestones')
|
||||
->required(),
|
||||
])
|
||||
->minItems(1)
|
||||
->columns(1)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
|
||||
Section::make('Company Structure Section')
|
||||
->description("Manage the 'Company Structure' details on the About Us page.")
|
||||
->icon('heroicon-o-user-group')
|
||||
->schema([
|
||||
TextInput::make('company_structure_title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('company_structure_subtitle')
|
||||
->label('Subtitle')
|
||||
->rows(2)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
TextInput::make('company_structure_director_name')
|
||||
->label('Director Name')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('company_structure_advisor_name')
|
||||
->label('Technical Advisor Name')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Repeater::make('company_structure_departments')
|
||||
->label('Departments')
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label('Department Name')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('person')
|
||||
->label('Contact Person')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
])
|
||||
->minItems(1)
|
||||
->columns(2)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
|
||||
Section::make('Our Facilities Section')
|
||||
->description("Manage the 'Our Facilities' details on the About Us page.")
|
||||
->icon('heroicon-o-building-library')
|
||||
->schema([
|
||||
TextInput::make('our_facilities_title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('our_facilities_subtitle')
|
||||
->label('Subtitle')
|
||||
->rows(2)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
Repeater::make('our_facilities_locations')
|
||||
->label('Locations')
|
||||
->schema([
|
||||
FileUpload::make('image')
|
||||
->label('Image')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('about-us-facilities')
|
||||
->required(),
|
||||
TextInput::make('name')
|
||||
->label('Location Name')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('location')
|
||||
->label('Address/Location')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('description')
|
||||
->label('Description')
|
||||
->rows(3)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
Repeater::make('tags')
|
||||
->label('Tags')
|
||||
->simple(TextInput::make('value')
|
||||
->label('Tag')
|
||||
->required()
|
||||
->maxLength(50))
|
||||
->itemLabel(fn (array $state): ?string => $state['value'] ?? null)
|
||||
->minItems(1)
|
||||
->columns(1)
|
||||
->reorderable()
|
||||
->collapsible()
|
||||
->defaultItems(1),
|
||||
])
|
||||
->minItems(1)
|
||||
->columns(1)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('About US');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('About Page Settings');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return 'About Us';
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return 'Edit About Us page text and images from here';
|
||||
}
|
||||
|
||||
public function getSubheading(): string|Htmlable|null
|
||||
{
|
||||
return 'Manage the content sections of the About Us page.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
98
app/Filament/Pages/ContactPageSettings.php
Normal file
98
app/Filament/Pages/ContactPageSettings.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\ContactSettings;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ContactPageSettings extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Contact';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-phone';
|
||||
|
||||
protected static string $settings = ContactSettings::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make('Contact Section')
|
||||
->description('Manage the contact page content.')
|
||||
->schema([
|
||||
TextInput::make('contact_subtitle')
|
||||
->label('Subtitle')
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
TextInput::make('contact_header')
|
||||
->label('Header')
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
Textarea::make('contact_paragraph')
|
||||
->label('Paragraph')
|
||||
->rows(3)
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
TextInput::make('phone_number')
|
||||
->label('Phone Number')
|
||||
->tel()
|
||||
->required(),
|
||||
TextInput::make('email_address')
|
||||
->label('Email Address')
|
||||
->email()
|
||||
->required(),
|
||||
TextInput::make('location_address')
|
||||
->label('Location Address')
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
TextInput::make('map_embed_url')
|
||||
->label('Google Maps Embed URL')
|
||||
->url()
|
||||
->required(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Contact');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Contact Page Settings');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return 'Contact Page';
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return 'Edit contact page text and information from here';
|
||||
}
|
||||
|
||||
public function getSubheading(): string|Htmlable|null
|
||||
{
|
||||
return 'Manage the contact form details, contact information, and map embed.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,22 @@
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\HomeSettings;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class HomePageSettings extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-home';
|
||||
|
||||
protected static string $settings = HomeSettings::class;
|
||||
@@ -29,7 +32,8 @@ class HomePageSettings extends SettingsPage
|
||||
->schema([
|
||||
TextInput::make('hero_badge_text')
|
||||
->label('Hero Badge Text')
|
||||
->maxLength(50),
|
||||
->maxLength(50)
|
||||
->required(),
|
||||
TextInput::make('hero_header')
|
||||
->label('Hero Header')
|
||||
->required()
|
||||
@@ -37,15 +41,18 @@ class HomePageSettings extends SettingsPage
|
||||
Textarea::make('hero_sub_header')
|
||||
->label('Hero Sub Header')
|
||||
->rows(3)
|
||||
->maxLength(255),
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('hero_link_button_text')
|
||||
->label('Hero Button Text')
|
||||
->maxLength(50),
|
||||
->maxLength(50)
|
||||
->required(),
|
||||
TextInput::make('hero_link_button_url')
|
||||
->label('Hero Button URL')
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
->url()
|
||||
->required(),
|
||||
])->columns(2),
|
||||
]),
|
||||
|
||||
@@ -55,7 +62,8 @@ class HomePageSettings extends SettingsPage
|
||||
->schema([
|
||||
TextInput::make('about_subtitle')
|
||||
->label('About Subtitle')
|
||||
->maxLength(100),
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
TextInput::make('about_header')
|
||||
->label('About Header')
|
||||
->required()
|
||||
@@ -63,46 +71,55 @@ class HomePageSettings extends SettingsPage
|
||||
Textarea::make('about_paragraph')
|
||||
->label('About Paragraph')
|
||||
->rows(5)
|
||||
->maxLength(65535),
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('about_projects_text')
|
||||
->label('Projects Text')
|
||||
->maxLength(100),
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
|
||||
TextInput::make('about_projects_number')
|
||||
->label('Projects Number')
|
||||
->numeric(),
|
||||
|
||||
->numeric()
|
||||
->required(),
|
||||
|
||||
])->columns(2),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('about_members_text')
|
||||
->label('Members Text')
|
||||
->maxLength(100),
|
||||
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
|
||||
TextInput::make('about_members_number')
|
||||
->label('Members Number')
|
||||
->numeric(),
|
||||
|
||||
->numeric()
|
||||
->required(),
|
||||
|
||||
])->columns(2),
|
||||
Grid::make()->schema([
|
||||
|
||||
TextInput::make('about_reviews_text')
|
||||
->label('Reviews Text')
|
||||
->maxLength(100),
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
|
||||
TextInput::make('about_reviews_number')
|
||||
->label('Reviews Number')
|
||||
->numeric(),
|
||||
|
||||
->numeric()
|
||||
->required(),
|
||||
|
||||
])->columns(2),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('about_button_text')
|
||||
->label('About Button Text')
|
||||
->maxLength(50),
|
||||
->maxLength(50)
|
||||
->required(),
|
||||
TextInput::make('about_button_url')
|
||||
->label('About Button URL')
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
->url()
|
||||
->required(),
|
||||
])->columns(2),
|
||||
|
||||
Grid::make()->schema([
|
||||
@@ -111,13 +128,15 @@ class HomePageSettings extends SettingsPage
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('about-images'),
|
||||
->directory('about-images')
|
||||
->required(),
|
||||
FileUpload::make('about_image_two')
|
||||
->label('About Image Two (375x391)')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('about-images'),
|
||||
->directory('about-images')
|
||||
->required(),
|
||||
])->columns(2),
|
||||
]),
|
||||
|
||||
@@ -125,10 +144,125 @@ class HomePageSettings extends SettingsPage
|
||||
->description('Upload or link the background video for the hero section.')
|
||||
->icon('heroicon-o-camera')
|
||||
->schema([
|
||||
TextInput::make('bg_video')
|
||||
->label('Background Video URL')
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
FileUpload::make('bg_video')
|
||||
->label('Background Video')
|
||||
->acceptedFileTypes(['video/mp4', 'video/webm', 'video/ogg'])
|
||||
->disk('public')
|
||||
->directory('homepage-videos')
|
||||
->required(),
|
||||
]),
|
||||
|
||||
Section::make('Industry Area')
|
||||
->description('Manage the content for the industry area section.')
|
||||
->icon('heroicon-o-building-office')
|
||||
->schema([
|
||||
TextInput::make('industry_subtitle')
|
||||
->label('Subtitle')
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
TextInput::make('industry_header')
|
||||
->label('Header')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('industry_paragraph')
|
||||
->label('Paragraph')
|
||||
->rows(3)
|
||||
->maxLength(65535)
|
||||
->required(),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('industry_button_text')
|
||||
->label('Button Text')
|
||||
->maxLength(50)
|
||||
->required(),
|
||||
TextInput::make('industry_button_url')
|
||||
->label('Button URL')
|
||||
->maxLength(255)
|
||||
->url()
|
||||
->required(),
|
||||
])->columns(2),
|
||||
FileUpload::make('industry_image_one')
|
||||
->label('Industry Image One (520x400)')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('industry-images')
|
||||
->required(),
|
||||
Repeater::make('industry_items')
|
||||
->label('Industry Items')
|
||||
->schema([
|
||||
FileUpload::make('icon')
|
||||
->label('Icon (SVG)')
|
||||
->directory('industry-icons')
|
||||
->acceptedFileTypes(['image/svg+xml'])
|
||||
->maxSize(1024) // 1MB
|
||||
->required(),
|
||||
TextInput::make('title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
Textarea::make('description')
|
||||
->label('Description')
|
||||
->rows(2)
|
||||
->maxLength(255)
|
||||
->required(),
|
||||
])
|
||||
->columns(2)
|
||||
->minItems(1)
|
||||
->maxItems(5)
|
||||
->defaultItems(2)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
|
||||
Section::make('Text Slide Area')
|
||||
->description('Manage the content for the text slide area section.')
|
||||
->icon('heroicon-o-chat-bubble-bottom-center-text')
|
||||
->schema([
|
||||
TextInput::make('text_slide_subtitle')
|
||||
->label('Subtitle')
|
||||
->maxLength(100)
|
||||
->required(),
|
||||
TextInput::make('text_slide_header')
|
||||
->label('Header')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
FileUpload::make('text_slide_image')
|
||||
->label('Text Slide Image (540x350)')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('text-slide-images')
|
||||
->required(),
|
||||
TextInput::make('text_slide_counter_number')
|
||||
->label('Counter Number')
|
||||
->numeric()
|
||||
->default(29)
|
||||
->required(),
|
||||
Repeater::make('text_slide_items')
|
||||
->label('Text Slide Items')
|
||||
->schema([
|
||||
FileUpload::make('icon')
|
||||
->label('Icon (SVG)')
|
||||
->directory('text-slide-icons')
|
||||
->acceptedFileTypes(['image/svg+xml'])
|
||||
->maxSize(1024) // 1MB
|
||||
->required(),
|
||||
TextInput::make('link')
|
||||
->label('Link')
|
||||
->required()
|
||||
->url()
|
||||
->maxLength(255),
|
||||
TextInput::make('text')
|
||||
->label('Text')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
])
|
||||
->columns(3)
|
||||
->minItems(1)
|
||||
->maxItems(10)
|
||||
->defaultItems(6)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
@@ -137,12 +271,12 @@ class HomePageSettings extends SettingsPage
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('CMS');
|
||||
return __('Home');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Home');
|
||||
return __('Home Page Settings');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
@@ -159,4 +293,14 @@ class HomePageSettings extends SettingsPage
|
||||
{
|
||||
return 'Manage the homepage hero section, background video, and call-to-action content.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
56
app/Filament/Pages/ManageCtaSettings.php
Normal file
56
app/Filament/Pages/ManageCtaSettings.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\CtaSettings;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
|
||||
class ManageCtaSettings extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-megaphone';
|
||||
|
||||
protected static string $settings = CtaSettings::class;
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Call To Action';
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('title')
|
||||
->label('Call To Action Title')
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('button_text')
|
||||
->label('Button Text')
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('button_url')
|
||||
->label('Button URL')
|
||||
->required()
|
||||
->url(),
|
||||
FileUpload::make('background_image')
|
||||
->label('Background Image 1320x408')
|
||||
->directory('settings')
|
||||
->image()
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
122
app/Filament/Pages/ManagePortfolio.php
Normal file
122
app/Filament/Pages/ManagePortfolio.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\PortfolioSettings;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManagePortfolio extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-briefcase';
|
||||
|
||||
protected static string $settings = PortfolioSettings::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make('Portfolio Section Content')
|
||||
->description('Manage the main content for the portfolio section.')
|
||||
->icon('heroicon-o-document-text')
|
||||
->schema([
|
||||
TextInput::make('portfolio_header')
|
||||
->label('Header')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('portfolio_button_text')
|
||||
->label('Button Text')
|
||||
->required()
|
||||
->maxLength(50),
|
||||
TextInput::make('portfolio_button_url')
|
||||
->label('Button URL')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
])->columns(2),
|
||||
]),
|
||||
Section::make('Portfolio Items')
|
||||
->description('Manage individual portfolio items.')
|
||||
->icon('heroicon-o-photo')
|
||||
->schema([
|
||||
Repeater::make('portfolio_items')
|
||||
->label('Portfolio Items')
|
||||
->schema([
|
||||
FileUpload::make('image')
|
||||
->label('Image (700x525)')
|
||||
->image()
|
||||
->maxSize(2048)
|
||||
->disk('public')
|
||||
->directory('portfolio-images')
|
||||
->required(),
|
||||
TextInput::make('category')
|
||||
->label('Category')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('link')
|
||||
->label('Link')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
])
|
||||
->columns(2)
|
||||
->minItems(1)
|
||||
->maxItems(8)
|
||||
->defaultItems(4)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Home');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Portfolio');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return 'Portfolio';
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return 'Edit portfolio section content from here';
|
||||
}
|
||||
|
||||
public function getSubheading(): string|Htmlable|null
|
||||
{
|
||||
return 'Manage the portfolio section content, including items, categories, and titles.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\SiteSettings;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
@@ -10,6 +11,8 @@ use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManageSite extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Settings';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-globe-alt';
|
||||
|
||||
protected static string $settings = SiteSettings::class;
|
||||
@@ -38,10 +41,12 @@ class ManageSite extends SettingsPage
|
||||
->maxLength(100),
|
||||
Forms\Components\TextInput::make('tagline')
|
||||
->label('Site Tagline')
|
||||
->required()
|
||||
->helperText('A short phrase describing your site')
|
||||
->maxLength(150),
|
||||
Forms\Components\Textarea::make('description')
|
||||
->label('Site Description')
|
||||
->required()
|
||||
->helperText('A detailed description of your website')
|
||||
->rows(3)
|
||||
->maxLength(500),
|
||||
@@ -65,13 +70,16 @@ class ManageSite extends SettingsPage
|
||||
->maxLength(100),
|
||||
Forms\Components\TextInput::make('company_phone')
|
||||
->label('Company Phone')
|
||||
->required()
|
||||
->maxLength(20),
|
||||
Forms\Components\TextInput::make('company_phone_2')
|
||||
->label('Company Additional Phone')
|
||||
->required()
|
||||
->maxLength(20),
|
||||
])->columns(2),
|
||||
Forms\Components\Textarea::make('company_address')
|
||||
->label('Company Address')
|
||||
->required()
|
||||
->rows(2)
|
||||
->maxLength(200),
|
||||
]),
|
||||
@@ -94,17 +102,20 @@ class ManageSite extends SettingsPage
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('copyright_text')
|
||||
->label('Copyright Text')
|
||||
->required()
|
||||
->maxLength(200),
|
||||
|
||||
Forms\Components\Grid::make()->schema([
|
||||
Forms\Components\TextInput::make('terms_url')
|
||||
->label('Terms & Conditions URL')
|
||||
->required()
|
||||
->maxLength(100)
|
||||
->prefix(function (Forms\Get $get) {
|
||||
return url('/');
|
||||
}),
|
||||
Forms\Components\TextInput::make('privacy_url')
|
||||
->label('Privacy Policy URL')
|
||||
->required()
|
||||
->maxLength(100)
|
||||
->prefix(function (Forms\Get $get) {
|
||||
return url('/');
|
||||
@@ -120,10 +131,12 @@ class ManageSite extends SettingsPage
|
||||
Forms\Components\Grid::make()->schema([
|
||||
Forms\Components\Textarea::make('custom_404_message')
|
||||
->label('404 Not Found Message')
|
||||
->required()
|
||||
->rows(2)
|
||||
->maxLength(500),
|
||||
Forms\Components\Textarea::make('custom_500_message')
|
||||
->label('500 Server Error Message')
|
||||
->required()
|
||||
->rows(2)
|
||||
->maxLength(500),
|
||||
])->columns(2),
|
||||
@@ -156,4 +169,14 @@ class ManageSite extends SettingsPage
|
||||
{
|
||||
return 'Manage your website\'s general configuration';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\SiteSocialSettings;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
@@ -10,7 +11,7 @@ use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManageSiteSocialSettings extends SettingsPage
|
||||
{
|
||||
protected static ?int $navigationSort = 4;
|
||||
protected static ?string $navigationGroup = 'Settings';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-share';
|
||||
|
||||
@@ -28,18 +29,22 @@ class ManageSiteSocialSettings extends SettingsPage
|
||||
Forms\Components\Grid::make()->schema([
|
||||
Forms\Components\TextInput::make('facebook_url')
|
||||
->label('Facebook URL')
|
||||
->required()
|
||||
->prefix('https://')
|
||||
->helperText('e.g., facebook.com/yourpage'),
|
||||
Forms\Components\TextInput::make('twitter_url')
|
||||
->label('Twitter/X URL')
|
||||
->required()
|
||||
->prefix('https://')
|
||||
->helperText('e.g., twitter.com/yourusername'),
|
||||
Forms\Components\TextInput::make('instagram_url')
|
||||
->label('Instagram URL')
|
||||
->required()
|
||||
->prefix('https://')
|
||||
->helperText('e.g., instagram.com/yourusername'),
|
||||
Forms\Components\TextInput::make('linkedin_url')
|
||||
->label('LinkedIn URL')
|
||||
->required()
|
||||
->prefix('https://')
|
||||
->helperText('e.g., linkedin.com/company/yourcompany'),
|
||||
])->columns(2),
|
||||
@@ -73,4 +78,14 @@ class ManageSiteSocialSettings extends SettingsPage
|
||||
{
|
||||
return 'Manage your social media profiles and sharing options';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
390
app/Filament/Pages/ManageSolutions.php
Normal file
390
app/Filament/Pages/ManageSolutions.php
Normal file
@@ -0,0 +1,390 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\SolutionSettings;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManageSolutions extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-wrench-screwdriver';
|
||||
|
||||
protected static string $settings = SolutionSettings::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make('Solutions Section')
|
||||
->description('Manage the content for the solutions section on the homepage.')
|
||||
->icon('heroicon-o-puzzle-piece')
|
||||
->schema([
|
||||
TextInput::make('solutions_subtitle')
|
||||
->label('Subtitle')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('solutions_header')
|
||||
->label('Header')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
FileUpload::make('solutions_image')
|
||||
->label('Image 1060x453')
|
||||
->image()
|
||||
->directory('solutions')
|
||||
->required(),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('solutions_button_text')
|
||||
->label('Button Text')
|
||||
->required()
|
||||
->maxLength(50),
|
||||
TextInput::make('solutions_button_url')
|
||||
->label('Button URL')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
])->columns(2),
|
||||
]),
|
||||
Section::make('Solution Items')
|
||||
->description('Manage individual solution items.')
|
||||
->icon('heroicon-o-cube')
|
||||
->schema([
|
||||
Repeater::make('solution_items')
|
||||
->label('Solution Items')
|
||||
->schema([
|
||||
Select::make('icon_class')
|
||||
->label('Icon Class')
|
||||
->searchable()
|
||||
->helperText('e.g., flaticon-it-department. Refer to Flaticon for available icons.')
|
||||
->required()
|
||||
->options(self::getIconOptions()),
|
||||
TextInput::make('title')
|
||||
->label('Title')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('link')
|
||||
->label('Link')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
])
|
||||
->columns(3)
|
||||
->minItems(1)
|
||||
->maxItems(6)
|
||||
->defaultItems(3)
|
||||
->grid(2)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
private static function getIconOptions(): array
|
||||
{
|
||||
return [
|
||||
'microsoft-word' => 'microsoft-word',
|
||||
'text-box' => 'text-box',
|
||||
'document-1' => 'document-1',
|
||||
'layers-1' => 'layers-1',
|
||||
'folder-1' => 'folder-1',
|
||||
'contract' => 'contract',
|
||||
'layer' => 'layer',
|
||||
'download-pdf' => 'download-pdf',
|
||||
'pdf' => 'pdf',
|
||||
'cloud-computing' => 'cloud-computing',
|
||||
'downloads' => 'downloads',
|
||||
'layers' => 'layers',
|
||||
'document' => 'document',
|
||||
'light-bulb-1' => 'light-bulb-1',
|
||||
'idea-2' => 'idea-2',
|
||||
'light-bulb' => 'light-bulb',
|
||||
'idea-1' => 'idea-1',
|
||||
'solution-2' => 'solution-2',
|
||||
'lightbulb' => 'lightbulb',
|
||||
'menus' => 'menus',
|
||||
'support-1' => 'support-1',
|
||||
'swipe-left' => 'swipe-left',
|
||||
'development' => 'development',
|
||||
'domain' => 'domain',
|
||||
'pets' => 'pets',
|
||||
'diagram' => 'diagram',
|
||||
'targeting' => 'targeting',
|
||||
'business-intelligence' => 'business-intelligence',
|
||||
'menu-6' => 'menu-6',
|
||||
'high-quality' => 'high-quality',
|
||||
'campaign' => 'campaign',
|
||||
'brain' => 'brain',
|
||||
'software-application' => 'software-application',
|
||||
'apps' => 'apps',
|
||||
'wrench-1' => 'wrench-1',
|
||||
'social-media-marketing-1' => 'social-media-marketing-1',
|
||||
'category-1' => 'category-1',
|
||||
'trophy-3' => 'trophy-3',
|
||||
'email-marketing' => 'email-marketing',
|
||||
'setting' => 'setting',
|
||||
'more' => 'more',
|
||||
'menu-5' => 'menu-5',
|
||||
'menu-4' => 'menu-4',
|
||||
'medical' => 'medical',
|
||||
'sparkle' => 'sparkle',
|
||||
'menu-3' => 'menu-3',
|
||||
'technology-2' => 'technology-2',
|
||||
'process' => 'process',
|
||||
'hearth-1' => 'hearth-1',
|
||||
'hearth' => 'hearth',
|
||||
'technology-1' => 'technology-1',
|
||||
'category' => 'category',
|
||||
'customer-care' => 'customer-care',
|
||||
'folder' => 'folder',
|
||||
'portfolio-1' => 'portfolio-1',
|
||||
'report' => 'report',
|
||||
'thinking' => 'thinking',
|
||||
'fingerprint' => 'fingerprint',
|
||||
'clock-2' => 'clock-2',
|
||||
'award' => 'award',
|
||||
'paper-plane' => 'paper-plane',
|
||||
'repair' => 'repair',
|
||||
'email-5' => 'email-5',
|
||||
'strategy' => 'strategy',
|
||||
'portfolio' => 'portfolio',
|
||||
'web-design' => 'web-design',
|
||||
'email-4' => 'email-4',
|
||||
'down-arrow-1' => 'down-arrow-1',
|
||||
'location-2' => 'location-2',
|
||||
'phone-call-2' => 'phone-call-2',
|
||||
'telephone-call' => 'telephone-call',
|
||||
'teamwork' => 'teamwork',
|
||||
'up-arrow-1' => 'up-arrow-1',
|
||||
'menu-2' => 'menu-2',
|
||||
'developing' => 'developing',
|
||||
'money-bag' => 'money-bag',
|
||||
'thumbs-up' => 'thumbs-up',
|
||||
'profits' => 'profits',
|
||||
'location-1' => 'location-1',
|
||||
'help-1' => 'help-1',
|
||||
'online-chat' => 'online-chat',
|
||||
'worker' => 'worker',
|
||||
'smart-home' => 'smart-home',
|
||||
'customer-service-1' => 'customer-service-1',
|
||||
'internet' => 'internet',
|
||||
'cash-flow' => 'cash-flow',
|
||||
'monitor' => 'monitor',
|
||||
'search-1' => 'search-1',
|
||||
'wrench' => 'wrench',
|
||||
'coin' => 'coin',
|
||||
'cash' => 'cash',
|
||||
'analyst' => 'analyst',
|
||||
'dashboard-1' => 'dashboard-1',
|
||||
'digital' => 'digital',
|
||||
'searching' => 'searching',
|
||||
'email-3' => 'email-3',
|
||||
'star-1' => 'star-1',
|
||||
'touch' => 'touch',
|
||||
'medal' => 'medal',
|
||||
'world-wide-web-1' => 'world-wide-web-1',
|
||||
'phone' => 'phone',
|
||||
'social-media' => 'social-media',
|
||||
'24-7' => '24-7',
|
||||
'hard-work' => 'hard-work',
|
||||
'star' => 'star',
|
||||
'plus' => 'plus',
|
||||
'minus-2' => 'minus-2',
|
||||
'menu-1' => 'menu-1',
|
||||
'cloud' => 'cloud',
|
||||
'handshake' => 'handshake',
|
||||
'people' => 'people',
|
||||
'ai' => 'ai',
|
||||
'save-money' => 'save-money',
|
||||
'shopping-online' => 'shopping-online',
|
||||
'profit-1' => 'profit-1',
|
||||
'blockchain' => 'blockchain',
|
||||
'sales' => 'sales',
|
||||
'back-in-time' => 'back-in-time',
|
||||
'clock-1' => 'clock-1',
|
||||
'user-3' => 'user-3',
|
||||
'user-2' => 'user-2',
|
||||
'pawprint' => 'pawprint',
|
||||
'payment-method' => 'payment-method',
|
||||
'world-wide-web' => 'world-wide-web',
|
||||
'minus-1' => 'minus-1',
|
||||
'add-1' => 'add-1',
|
||||
'management' => 'management',
|
||||
'help' => 'help',
|
||||
'chip' => 'chip',
|
||||
'artificial-intelligence' => 'artificial-intelligence',
|
||||
'group' => 'group',
|
||||
'money-1' => 'money-1',
|
||||
'conversation' => 'conversation',
|
||||
'email-2' => 'email-2',
|
||||
'rating' => 'rating',
|
||||
'placeholder' => 'placeholder',
|
||||
'trophy-2' => 'trophy-2',
|
||||
'cpu' => 'cpu',
|
||||
'home' => 'home',
|
||||
'right-arrow-1' => 'right-arrow-1',
|
||||
'like' => 'like',
|
||||
'mail' => 'mail',
|
||||
'briefcase' => 'briefcase',
|
||||
'money' => 'money',
|
||||
'up-arrow' => 'up-arrow',
|
||||
'trophy-1' => 'trophy-1',
|
||||
'user-1' => 'user-1',
|
||||
'question' => 'question',
|
||||
'team-1' => 'team-1',
|
||||
'user' => 'user',
|
||||
'email-1' => 'email-1',
|
||||
'price-tag-1' => 'price-tag-1',
|
||||
'tag' => 'tag',
|
||||
'loupe' => 'loupe',
|
||||
'right-arrow' => 'right-arrow',
|
||||
'left-arrow-1' => 'left-arrow-1',
|
||||
'down-arrow' => 'down-arrow',
|
||||
'price-tag' => 'price-tag',
|
||||
'stars' => 'stars',
|
||||
'search' => 'search',
|
||||
'phone-call-1' => 'phone-call-1',
|
||||
'award-symbol' => 'award-symbol',
|
||||
'christmas-stars' => 'christmas-stars',
|
||||
'minus' => 'minus',
|
||||
'add' => 'add',
|
||||
'cancel-1' => 'cancel-1',
|
||||
'checked' => 'checked',
|
||||
'cyber-security' => 'cyber-security',
|
||||
'data-protection' => 'data-protection',
|
||||
'hosting' => 'hosting',
|
||||
'brand-awareness' => 'brand-awareness',
|
||||
'ux-design' => 'ux-design',
|
||||
'influencer' => 'influencer',
|
||||
'online-advertising' => 'online-advertising',
|
||||
'web-management' => 'web-management',
|
||||
'seo-1' => 'seo-1',
|
||||
'computer' => 'computer',
|
||||
'software-development' => 'software-development',
|
||||
'coding-1' => 'coding-1',
|
||||
'coding' => 'coding',
|
||||
'app-development' => 'app-development',
|
||||
'content-marketing' => 'content-marketing',
|
||||
'social-media-marketing' => 'social-media-marketing',
|
||||
'analysis-1' => 'analysis-1',
|
||||
'twitter' => 'twitter',
|
||||
'repairing' => 'repairing',
|
||||
'data-visualization' => 'data-visualization',
|
||||
'information-technology' => 'information-technology',
|
||||
'statistics-1' => 'statistics-1',
|
||||
'exploration' => 'exploration',
|
||||
'project-1' => 'project-1',
|
||||
'cross-mark' => 'cross-mark',
|
||||
'search-analysis' => 'search-analysis',
|
||||
'system' => 'system',
|
||||
'hashtag-1' => 'hashtag-1',
|
||||
'hashtag' => 'hashtag',
|
||||
'it-department' => 'it-department',
|
||||
'creative' => 'creative',
|
||||
'online-analytical' => 'online-analytical',
|
||||
'secure-data' => 'secure-data',
|
||||
'slash' => 'slash',
|
||||
'creative-thinking' => 'creative-thinking',
|
||||
'right-up' => 'right-up',
|
||||
'dashboard' => 'dashboard',
|
||||
'profit' => 'profit',
|
||||
'project' => 'project',
|
||||
'phone-call' => 'phone-call',
|
||||
'seo' => 'seo',
|
||||
'prototype' => 'prototype',
|
||||
'creative-process' => 'creative-process',
|
||||
'growth' => 'growth',
|
||||
'technical-support' => 'technical-support',
|
||||
'technology' => 'technology',
|
||||
'solution-1' => 'solution-1',
|
||||
'creative-tools' => 'creative-tools',
|
||||
'data-science' => 'data-science',
|
||||
'costumer' => 'costumer',
|
||||
'cooperation' => 'cooperation',
|
||||
'next' => 'next',
|
||||
'back' => 'back',
|
||||
'brand' => 'brand',
|
||||
'right-arrows' => 'right-arrows',
|
||||
'idea' => 'idea',
|
||||
'design-thinking' => 'design-thinking',
|
||||
'check' => 'check',
|
||||
'cross' => 'cross',
|
||||
'right' => 'right',
|
||||
'link' => 'link',
|
||||
'server' => 'server',
|
||||
'analysis' => 'analysis',
|
||||
'support' => 'support',
|
||||
'project-management' => 'project-management',
|
||||
'networking' => 'networking',
|
||||
'team' => 'team',
|
||||
'check-mark' => 'check-mark',
|
||||
'consultation' => 'consultation',
|
||||
'solution' => 'solution',
|
||||
'success' => 'success',
|
||||
'customer-review' => 'customer-review',
|
||||
'select' => 'select',
|
||||
'statistics' => 'statistics',
|
||||
'machine-learning' => 'machine-learning',
|
||||
'vector' => 'vector',
|
||||
'trophy' => 'trophy',
|
||||
'data' => 'data',
|
||||
'clock' => 'clock',
|
||||
'cancel' => 'cancel',
|
||||
'customer-service' => 'customer-service',
|
||||
'digital-marketing' => 'digital-marketing',
|
||||
'email' => 'email',
|
||||
'stats' => 'stats',
|
||||
'menu' => 'menu',
|
||||
'location' => 'location',
|
||||
'tick' => 'tick',
|
||||
'left-arrow' => 'left-arrow',
|
||||
'dots-menu' => 'dots-menu',
|
||||
];
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Home');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Manage Solutions');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return 'Solutions';
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return 'Edit solutions text, icons, and links from here';
|
||||
}
|
||||
|
||||
public function getSubheading(): string|Htmlable|null
|
||||
{
|
||||
return 'Manage the solutions section content, including individual solution items.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
127
app/Filament/Pages/ManageSuccess.php
Normal file
127
app/Filament/Pages/ManageSuccess.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\UserRole;
|
||||
use App\Settings\SuccessSettings;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\SettingsPage;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ManageSuccess extends SettingsPage
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-check-circle';
|
||||
|
||||
protected static string $settings = SuccessSettings::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Section::make('Success Section Content')
|
||||
->description('Manage the main content for the success section.')
|
||||
->icon('heroicon-o-document-text')
|
||||
->schema([
|
||||
TextInput::make('success_subtitle')
|
||||
->label('Subtitle')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('success_header')
|
||||
->label('Header')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('success_paragraph')
|
||||
->label('Paragraph')
|
||||
->required()
|
||||
->rows(3)
|
||||
->maxLength(65535),
|
||||
Grid::make()->schema([
|
||||
TextInput::make('success_button_text')
|
||||
->label('Button Text')
|
||||
->required()
|
||||
->maxLength(50),
|
||||
TextInput::make('success_button_url')
|
||||
->label('Button URL')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->url(),
|
||||
])->columns(2),
|
||||
FileUpload::make('success_image')
|
||||
->label('Image')
|
||||
->directory('cms')
|
||||
->image()
|
||||
->required(),
|
||||
]),
|
||||
Section::make('Skill Items')
|
||||
->description('Manage the skill items with their names and percentages.')
|
||||
->icon('heroicon-o-adjustments-vertical')
|
||||
->schema([
|
||||
Repeater::make('skill_items')
|
||||
->label('Skill Items')
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label('Skill Name')
|
||||
->required()
|
||||
->maxLength(100),
|
||||
TextInput::make('percentage')
|
||||
->label('Percentage')
|
||||
->numeric()
|
||||
->required()
|
||||
->minValue(0)
|
||||
->maxValue(100),
|
||||
])
|
||||
->columns(2)
|
||||
->minItems(1)
|
||||
->maxItems(5)
|
||||
->defaultItems(2)
|
||||
->reorderable()
|
||||
->collapsible(),
|
||||
]),
|
||||
])
|
||||
->columns(1)
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('Home');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('Success Section');
|
||||
}
|
||||
|
||||
public function getTitle(): string|Htmlable
|
||||
{
|
||||
return 'Success Section';
|
||||
}
|
||||
|
||||
public function getHeading(): string|Htmlable
|
||||
{
|
||||
return 'Edit success section content from here';
|
||||
}
|
||||
|
||||
public function getSubheading(): string|Htmlable|null
|
||||
{
|
||||
return 'Manage the success section content, including text, button, and skill bars.';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth()->user()->canManageSettings();
|
||||
}
|
||||
|
||||
public static function canView(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
113
app/Filament/Resources/ApplicationResource.php
Normal file
113
app/Filament/Resources/ApplicationResource.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\ApplicationResource\Pages;
|
||||
use App\Models\Application;
|
||||
use App\Models\Career;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ApplicationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Application::class;
|
||||
|
||||
protected static ?string $navigationGroup = 'Careers';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Select::make('career_id')
|
||||
->label('Career')
|
||||
->options(Career::all()->pluck('title', 'id'))
|
||||
->searchable()
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\DatePicker::make('birthdate')
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('email')
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\TextInput::make('phone_number')
|
||||
->maxLength(255),
|
||||
Forms\Components\FileUpload::make('resume_file')
|
||||
->required()
|
||||
->disk('public')
|
||||
->directory('resumes')
|
||||
->enableDownload()
|
||||
->enableOpen(),
|
||||
Forms\Components\RichEditor::make('cover_letter')
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('career.title')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('email')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('phone_number')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('birthdate')
|
||||
->date()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListApplications::route('/'),
|
||||
'create' => Pages\CreateApplication::route('/create'),
|
||||
'edit' => Pages\EditApplication::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ApplicationResource\Pages;
|
||||
|
||||
use App\Filament\Resources\ApplicationResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateApplication extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ApplicationResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ApplicationResource\Pages;
|
||||
|
||||
use App\Filament\Resources\ApplicationResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditApplication extends EditRecord
|
||||
{
|
||||
protected static string $resource = ApplicationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ApplicationResource\Pages;
|
||||
|
||||
use App\Filament\Resources\ApplicationResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListApplications extends ListRecords
|
||||
{
|
||||
protected static string $resource = ApplicationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
125
app/Filament/Resources/AuthorResource.php
Normal file
125
app/Filament/Resources/AuthorResource.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\AuthorResource\Pages;
|
||||
use App\Models\Author;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class AuthorResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Author::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-users';
|
||||
|
||||
protected static ?string $navigationGroup = 'News & Stories';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Card::make()
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
FileUpload::make('profile_image')
|
||||
->label('Profile Image 400x400')
|
||||
->image()
|
||||
->directory('authors')
|
||||
->nullable(),
|
||||
RichEditor::make('description')
|
||||
->nullable()
|
||||
->columnSpanFull(),
|
||||
])->columns(1),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
ImageColumn::make('profile_image')
|
||||
->square()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListAuthors::route('/'),
|
||||
'create' => Pages\CreateAuthor::route('/create'),
|
||||
'edit' => Pages\EditAuthor::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->can('view-authors');
|
||||
}
|
||||
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return auth()->user()->can('view-authors');
|
||||
}
|
||||
|
||||
public static function canEdit(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('view-authors');
|
||||
}
|
||||
|
||||
public static function canDelete(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('view-authors');
|
||||
}
|
||||
|
||||
public static function canDeleteAny(): bool
|
||||
{
|
||||
return auth()->user()->can('view-authors');
|
||||
}
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()->withoutGlobalScopes();
|
||||
}
|
||||
}
|
||||
11
app/Filament/Resources/AuthorResource/Pages/CreateAuthor.php
Normal file
11
app/Filament/Resources/AuthorResource/Pages/CreateAuthor.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\AuthorResource\Pages;
|
||||
|
||||
use App\Filament\Resources\AuthorResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateAuthor extends CreateRecord
|
||||
{
|
||||
protected static string $resource = AuthorResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/AuthorResource/Pages/EditAuthor.php
Normal file
19
app/Filament/Resources/AuthorResource/Pages/EditAuthor.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\AuthorResource\Pages;
|
||||
|
||||
use App\Filament\Resources\AuthorResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditAuthor extends EditRecord
|
||||
{
|
||||
protected static string $resource = AuthorResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Filament/Resources/AuthorResource/Pages/ListAuthors.php
Normal file
19
app/Filament/Resources/AuthorResource/Pages/ListAuthors.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\AuthorResource\Pages;
|
||||
|
||||
use App\Filament\Resources\AuthorResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListAuthors extends ListRecords
|
||||
{
|
||||
protected static string $resource = AuthorResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,8 @@
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\BrandResource\Pages;
|
||||
use App\Filament\Resources\BrandResource\RelationManagers;
|
||||
use App\Models\Brand;
|
||||
use Filament\Forms;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
@@ -16,14 +15,14 @@ use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Columns\ToggleColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class BrandResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Brand::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
protected static ?string $navigationIcon = 'heroicon-o-tag';
|
||||
|
||||
protected static ?string $navigationGroup = 'Home';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
@@ -36,12 +35,12 @@ class BrandResource extends Resource
|
||||
FileUpload::make('image')
|
||||
->image()
|
||||
->imageEditor()
|
||||
->rules(['required', 'image',]),
|
||||
->rules(['required', 'image']),
|
||||
|
||||
Toggle::make('active')
|
||||
->label('Is active')
|
||||
->onColor('success')
|
||||
->offColor('danger')
|
||||
->offColor('danger'),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -81,4 +80,9 @@ class BrandResource extends Resource
|
||||
'index' => Pages\ManageBrands::route('/'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
126
app/Filament/Resources/CareerResource.php
Normal file
126
app/Filament/Resources/CareerResource.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\CareerResource\Pages;
|
||||
use App\Filament\Resources\CareerResource\RelationManagers;
|
||||
use App\Models\Career;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CareerResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Career::class;
|
||||
|
||||
protected static ?string $navigationGroup = 'Careers';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-briefcase';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('location')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Textarea::make('title_description')
|
||||
->label('Description (show on modal)')
|
||||
->required()
|
||||
->maxLength(65535)
|
||||
->columnSpan('full'),
|
||||
|
||||
TextInput::make('salary_per_month')
|
||||
->required()
|
||||
->numeric()
|
||||
->label('Salary per month')
|
||||
->maxLength(255),
|
||||
Forms\Components\Select::make('salary_currency')
|
||||
->options(getCurrencies())
|
||||
->required()
|
||||
->label('Salary currency'),
|
||||
Repeater::make('bullets')
|
||||
->schema([
|
||||
TextInput::make('bullet')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
])
|
||||
->minItems(1)
|
||||
->defaultItems(1)
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('title_description')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('salary_per_month')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('salary_currency')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('location')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('salary')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
RelationManagers\ApplicationsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListCareers::route('/'),
|
||||
'create' => Pages\CreateCareer::route('/create'),
|
||||
'edit' => Pages\EditCareer::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
11
app/Filament/Resources/CareerResource/Pages/CreateCareer.php
Normal file
11
app/Filament/Resources/CareerResource/Pages/CreateCareer.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CareerResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CareerResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateCareer extends CreateRecord
|
||||
{
|
||||
protected static string $resource = CareerResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/CareerResource/Pages/EditCareer.php
Normal file
19
app/Filament/Resources/CareerResource/Pages/EditCareer.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CareerResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CareerResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditCareer extends EditRecord
|
||||
{
|
||||
protected static string $resource = CareerResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Filament/Resources/CareerResource/Pages/ListCareers.php
Normal file
19
app/Filament/Resources/CareerResource/Pages/ListCareers.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CareerResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CareerResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListCareers extends ListRecords
|
||||
{
|
||||
protected static string $resource = CareerResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CareerResource\RelationManagers;
|
||||
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ApplicationsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'applications';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\DatePicker::make('birthdate')
|
||||
->required(),
|
||||
Forms\Components\FileUpload::make('resume_file')
|
||||
->required()
|
||||
->acceptedFileTypes(['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'])
|
||||
->disk('public') // or your preferred disk
|
||||
->directory('resumes'),
|
||||
Forms\Components\TextInput::make('email')
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\TextInput::make('phone_number')
|
||||
->required()
|
||||
->maxLength(20),
|
||||
Forms\Components\Textarea::make('cover_letter')
|
||||
->maxLength(65535)
|
||||
->nullable()
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('name')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('email')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('phone_number')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
102
app/Filament/Resources/CommentResource.php
Normal file
102
app/Filament/Resources/CommentResource.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\CommentResource\Pages;
|
||||
use App\Models\Comment;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CommentResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Comment::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-chat-bubble-bottom-center-text';
|
||||
|
||||
protected static ?string $navigationGroup = 'News & Stories';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Card::make()
|
||||
->schema([
|
||||
Select::make('news_id')
|
||||
->relationship('news', 'title')
|
||||
->required(),
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
RichEditor::make('message')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
TextInput::make('author_name')
|
||||
->label('Author Name (Optional)')
|
||||
->maxLength(255),
|
||||
])
|
||||
->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('news.title')
|
||||
->label('News Article')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('author_name')
|
||||
->label('Author')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListComments::route('/'),
|
||||
'create' => Pages\CreateComment::route('/create'),
|
||||
'edit' => Pages\EditComment::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CommentResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CommentResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateComment extends CreateRecord
|
||||
{
|
||||
protected static string $resource = CommentResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/CommentResource/Pages/EditComment.php
Normal file
19
app/Filament/Resources/CommentResource/Pages/EditComment.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CommentResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CommentResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditComment extends EditRecord
|
||||
{
|
||||
protected static string $resource = CommentResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\CommentResource\Pages;
|
||||
|
||||
use App\Filament\Resources\CommentResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListComments extends ListRecords
|
||||
{
|
||||
protected static string $resource = CommentResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
129
app/Filament/Resources/InternshipResource.php
Normal file
129
app/Filament/Resources/InternshipResource.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\InternshipResource\Pages;
|
||||
use App\Filament\Resources\InternshipResource\RelationManagers;
|
||||
use App\Models\Internship;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class InternshipResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Internship::class;
|
||||
|
||||
protected static ?string $navigationGroup = 'Careers';
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-academic-cap';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('location')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Textarea::make('title_description')
|
||||
->label('Description (show on modal)')
|
||||
->required()
|
||||
->maxLength(65535)
|
||||
->columnSpan('full'),
|
||||
|
||||
TextInput::make('salary_per_month')
|
||||
->required()
|
||||
->numeric()
|
||||
->label('Salary per month')
|
||||
->maxLength(255),
|
||||
Forms\Components\Select::make('salary_currency')
|
||||
->options(getCurrencies())
|
||||
->required()
|
||||
->label('Salary currency')
|
||||
->searchable()
|
||||
->default('USD'),
|
||||
|
||||
Repeater::make('bullets')
|
||||
->schema([
|
||||
TextInput::make('bullet')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
])
|
||||
->minItems(1)
|
||||
->defaultItems(1)
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('title_description')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('salary_per_month')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('salary_currency')
|
||||
->searchable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('location')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('salary')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
RelationManagers\ApplicationsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListInternships::route('/'),
|
||||
'create' => Pages\CreateInternship::route('/create'),
|
||||
'edit' => Pages\EditInternship::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\InternshipResource\Pages;
|
||||
|
||||
use App\Filament\Resources\InternshipResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateInternship extends CreateRecord
|
||||
{
|
||||
protected static string $resource = InternshipResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\InternshipResource\Pages;
|
||||
|
||||
use App\Filament\Resources\InternshipResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditInternship extends EditRecord
|
||||
{
|
||||
protected static string $resource = InternshipResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\InternshipResource\Pages;
|
||||
|
||||
use App\Filament\Resources\InternshipResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListInternships extends ListRecords
|
||||
{
|
||||
protected static string $resource = InternshipResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\InternshipResource\RelationManagers;
|
||||
|
||||
use App\Models\InternshipApplication;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table; // Added this use statement
|
||||
|
||||
class ApplicationsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'applications';
|
||||
|
||||
// Add this line to define the inverse relationship
|
||||
protected static ?string $model = InternshipApplication::class;
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\DatePicker::make('birthdate')
|
||||
->required(),
|
||||
Forms\Components\FileUpload::make('resume_file')
|
||||
->required()
|
||||
->acceptedFileTypes(['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'])
|
||||
->disk('public') // or your preferred disk
|
||||
->directory('resumes'),
|
||||
Forms\Components\TextInput::make('email')
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Forms\Components\TextInput::make('phone_number')
|
||||
->required()
|
||||
->maxLength(20),
|
||||
Forms\Components\Textarea::make('cover_letter')
|
||||
->maxLength(65535)
|
||||
->nullable()
|
||||
->columnSpan('full'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('name')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('email')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('phone_number')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
157
app/Filament/Resources/NewsResource.php
Normal file
157
app/Filament/Resources/NewsResource.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\NewsResource\Pages;
|
||||
use App\Filament\Resources\NewsResource\RelationManagers\CommentsRelationManager;
|
||||
use App\Models\News;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NewsResource extends Resource
|
||||
{
|
||||
protected static ?string $model = News::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-newspaper';
|
||||
|
||||
protected static ?string $navigationGroup = 'News & Stories';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Card::make()
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->reactive()
|
||||
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
|
||||
TextInput::make('slug')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->disabled()
|
||||
->dehydrated()
|
||||
->unique(News::class, 'slug', ignoreRecord: true),
|
||||
FileUpload::make('image')
|
||||
->label('Image 1100x660')
|
||||
->image()
|
||||
->directory('news')
|
||||
->nullable()
|
||||
->columnSpanFull(),
|
||||
Select::make('author_id')
|
||||
->relationship('author', 'name')
|
||||
->searchable()
|
||||
->preload()
|
||||
->required(),
|
||||
RichEditor::make('content')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
DateTimePicker::make('published_at')
|
||||
->required()
|
||||
->default(now()),
|
||||
])
|
||||
->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
ImageColumn::make('image')
|
||||
->square()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('slug')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('author.name')
|
||||
->label('Author Name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('published_at')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
CommentsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ManageNews::route('/'),
|
||||
'create' => Pages\CreateNews::route('/create'),
|
||||
'edit' => Pages\EditNews::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canEdit(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canDelete(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canDeleteAny(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()->withoutGlobalScopes();
|
||||
}
|
||||
}
|
||||
11
app/Filament/Resources/NewsResource/Pages/CreateNews.php
Normal file
11
app/Filament/Resources/NewsResource/Pages/CreateNews.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\NewsResource\Pages;
|
||||
|
||||
use App\Filament\Resources\NewsResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateNews extends CreateRecord
|
||||
{
|
||||
protected static string $resource = NewsResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/NewsResource/Pages/EditNews.php
Normal file
19
app/Filament/Resources/NewsResource/Pages/EditNews.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\NewsResource\Pages;
|
||||
|
||||
use App\Filament\Resources\NewsResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditNews extends EditRecord
|
||||
{
|
||||
protected static string $resource = NewsResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Filament/Resources/NewsResource/Pages/ManageNews.php
Normal file
19
app/Filament/Resources/NewsResource/Pages/ManageNews.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\NewsResource\Pages;
|
||||
|
||||
use App\Filament\Resources\NewsResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ManageNews extends ListRecords
|
||||
{
|
||||
protected static string $resource = NewsResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\NewsResource\RelationManagers;
|
||||
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CommentsRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'comments';
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
RichEditor::make('message')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
TextInput::make('author_name')
|
||||
->label('Author Name (Optional)')
|
||||
->maxLength(255),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('title')
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('author_name')
|
||||
->label('Author')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
138
app/Filament/Resources/SolutionResource.php
Normal file
138
app/Filament/Resources/SolutionResource.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\SolutionResource\Pages;
|
||||
use App\Models\Solution;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SolutionResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Solution::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-light-bulb';
|
||||
|
||||
protected static ?string $navigationGroup = 'Our Solutions';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->reactive()
|
||||
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null)
|
||||
->debounce('1000ms'),
|
||||
|
||||
Forms\Components\TextInput::make('slug')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Forms\Components\TextInput::make('title_description')
|
||||
->maxLength(255)
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
|
||||
Forms\Components\Repeater::make('bullets')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('bullet')
|
||||
->label('Bullet Point')
|
||||
->required(),
|
||||
])
|
||||
->columns(1)
|
||||
->columnSpanFull()
|
||||
->createItemButtonLabel('Add Bullet Point')
|
||||
->defaultItems(1),
|
||||
Forms\Components\Repeater::make('downloads')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('title')
|
||||
->label('Download Title')
|
||||
->required(false),
|
||||
Forms\Components\FileUpload::make('file')
|
||||
->label('Download File')
|
||||
->required(false)
|
||||
->disk('public')
|
||||
->directory('solution-downloads'),
|
||||
])
|
||||
->columns(1)
|
||||
->columnSpanFull()
|
||||
->createItemButtonLabel('Add Download Item')
|
||||
->defaultItems(1),
|
||||
Forms\Components\Repeater::make('faqs')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('question')
|
||||
->label('Question')
|
||||
->required(),
|
||||
Forms\Components\RichEditor::make('answer')
|
||||
->label('Answer')
|
||||
->required(),
|
||||
])
|
||||
->columns(1)
|
||||
->columnSpanFull()
|
||||
->createItemButtonLabel('Add FAQ')
|
||||
->defaultItems(1),
|
||||
Forms\Components\RichEditor::make('description')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('slug')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListSolutions::route('/'),
|
||||
'create' => Pages\CreateSolution::route('/create'),
|
||||
'edit' => Pages\EditSolution::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SolutionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SolutionResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateSolution extends CreateRecord
|
||||
{
|
||||
protected static string $resource = SolutionResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SolutionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SolutionResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditSolution extends EditRecord
|
||||
{
|
||||
protected static string $resource = SolutionResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SolutionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SolutionResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListSolutions extends ListRecords
|
||||
{
|
||||
protected static string $resource = SolutionResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
146
app/Filament/Resources/SuccessResource.php
Normal file
146
app/Filament/Resources/SuccessResource.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\SuccessResource\Pages;
|
||||
use App\Models\Success;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SuccessResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Success::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-bookmark-square';
|
||||
|
||||
protected static ?string $navigationGroup = 'News & Stories';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Card::make()
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->reactive()
|
||||
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
|
||||
TextInput::make('slug')
|
||||
->required()
|
||||
->maxLength(255)
|
||||
->disabled()
|
||||
->dehydrated()
|
||||
->unique(Success::class, 'slug', ignoreRecord: true),
|
||||
FileUpload::make('image')
|
||||
->label('Image 1100x660')
|
||||
->image()
|
||||
->directory('success')
|
||||
->nullable()
|
||||
->columnSpanFull(),
|
||||
RichEditor::make('content')
|
||||
->required()
|
||||
->columnSpanFull(),
|
||||
DateTimePicker::make('published_at')
|
||||
->required()
|
||||
->default(now()),
|
||||
])
|
||||
->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
ImageColumn::make('image')
|
||||
->square()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('title')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('slug')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('published_at')
|
||||
->dateTime()
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListSuccesses::route('/'),
|
||||
'create' => Pages\CreateSuccess::route('/create'),
|
||||
'edit' => Pages\EditSuccess::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canCreate(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canEdit(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canDelete(mixed $record): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function canDeleteAny(): bool
|
||||
{
|
||||
return auth()->user()->can('manage-news-and-success');
|
||||
}
|
||||
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()->withoutGlobalScopes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SuccessResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SuccessResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateSuccess extends CreateRecord
|
||||
{
|
||||
protected static string $resource = SuccessResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/SuccessResource/Pages/EditSuccess.php
Normal file
19
app/Filament/Resources/SuccessResource/Pages/EditSuccess.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SuccessResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SuccessResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditSuccess extends EditRecord
|
||||
{
|
||||
protected static string $resource = SuccessResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\SuccessResource\Pages;
|
||||
|
||||
use App\Filament\Resources\SuccessResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListSuccesses extends ListRecords
|
||||
{
|
||||
protected static string $resource = SuccessResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
94
app/Filament/Resources/TeamMemberResource.php
Normal file
94
app/Filament/Resources/TeamMemberResource.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\TeamMemberResource\Pages;
|
||||
use App\Models\TeamMember;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class TeamMemberResource extends Resource
|
||||
{
|
||||
protected static ?string $model = TeamMember::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-users';
|
||||
|
||||
protected static ?string $navigationGroup = 'About US';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('description')
|
||||
->required()
|
||||
->rows(5)
|
||||
->maxLength(65535),
|
||||
FileUpload::make('image')
|
||||
->image()
|
||||
->directory('team-members')
|
||||
->maxSize(2048) // 2MB
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('title')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
ImageColumn::make('image'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListTeamMembers::route('/'),
|
||||
'create' => Pages\CreateTeamMember::route('/create'),
|
||||
'edit' => Pages\EditTeamMember::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function canViewAny(): bool
|
||||
{
|
||||
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TeamMemberResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TeamMemberResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateTeamMember extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TeamMemberResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TeamMemberResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TeamMemberResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditTeamMember extends EditRecord
|
||||
{
|
||||
protected static string $resource = TeamMemberResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\TeamMemberResource\Pages;
|
||||
|
||||
use App\Filament\Resources\TeamMemberResource;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListTeamMembers extends ListRecords
|
||||
{
|
||||
protected static string $resource = TeamMemberResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -16,3 +16,165 @@ function logDB(): void
|
||||
Log::info($query->sql, $query->bindings, $query->time);
|
||||
});
|
||||
}
|
||||
|
||||
function getCurrencies(): array
|
||||
{
|
||||
return [
|
||||
'AED' => 'UAE dirham',
|
||||
'AFN' => 'Afghan afghani',
|
||||
'ALL' => 'Albanian lek',
|
||||
'AMD' => 'Armenian dram',
|
||||
'ANG' => 'Netherlands Antillean gulden',
|
||||
'AOA' => 'Angolan kwanza',
|
||||
'ARS' => 'Argentine peso',
|
||||
'AUD' => 'Australian dollar',
|
||||
'AWG' => 'Aruban florin',
|
||||
'AZN' => 'Azerbaijani manat',
|
||||
'BAM' => 'Bosnia and Herzegovina konvertibilna marka',
|
||||
'BBD' => 'Barbadian dollar',
|
||||
'BDT' => 'Bangladeshi taka',
|
||||
'BGN' => 'Bulgarian lev',
|
||||
'BHD' => 'Bahraini dinar',
|
||||
'BIF' => 'Burundi franc',
|
||||
'BMD' => 'Bermudian dollar',
|
||||
'BND' => 'Brunei dollar',
|
||||
'BOB' => 'Bolivian boliviano',
|
||||
'BRL' => 'Brazilian real',
|
||||
'BSD' => 'Bahamian dollar',
|
||||
'BTN' => 'Bhutanese ngultrum',
|
||||
'BWP' => 'Botswana pula',
|
||||
'BYR' => 'Belarusian ruble',
|
||||
'BZD' => 'Belize dollar',
|
||||
'CAD' => 'Canadian dollar',
|
||||
'CDF' => 'Congolese franc',
|
||||
'CHF' => 'Swiss franc',
|
||||
'CLP' => 'Chilean peso',
|
||||
'CNY' => 'Chinese/Yuan renminbi',
|
||||
'COP' => 'Colombian peso',
|
||||
'CRC' => 'Costa Rican colon',
|
||||
'CUC' => 'Cuban peso',
|
||||
'CVE' => 'Cape Verdean escudo',
|
||||
'CZK' => 'Czech koruna',
|
||||
'DJF' => 'Djiboutian franc',
|
||||
'DKK' => 'Danish krone',
|
||||
'DOP' => 'Dominican peso',
|
||||
'DZD' => 'Algerian dinar',
|
||||
'EEK' => 'Estonian kroon',
|
||||
'EGP' => 'Egyptian pound',
|
||||
'ERN' => 'Eritrean nakfa',
|
||||
'ETB' => 'Ethiopian birr',
|
||||
'EUR' => 'European Euro',
|
||||
'FJD' => 'Fijian dollar',
|
||||
'FKP' => 'Falkland Islands pound',
|
||||
'GBP' => 'British pound',
|
||||
'GEL' => 'Georgian lari',
|
||||
'GHS' => 'Ghanaian cedi',
|
||||
'GIP' => 'Gibraltar pound',
|
||||
'GMD' => 'Gambian dalasi',
|
||||
'GNF' => 'Guinean franc',
|
||||
'GQE' => 'Central African CFA franc',
|
||||
'GTQ' => 'Guatemalan quetzal',
|
||||
'GYD' => 'Guyanese dollar',
|
||||
'HKD' => 'Hong Kong dollar',
|
||||
'HNL' => 'Honduran lempira',
|
||||
'HRK' => 'Croatian kuna',
|
||||
'HTG' => 'Haitian gourde',
|
||||
'HUF' => 'Hungarian forint',
|
||||
'IDR' => 'Indonesian rupiah',
|
||||
'ILS' => 'Israeli new sheqel',
|
||||
'INR' => 'Indian rupee',
|
||||
'IQD' => 'Iraqi dinar',
|
||||
'IRR' => 'Iranian rial',
|
||||
'ISK' => 'Icelandic króna',
|
||||
'JMD' => 'Jamaican dollar',
|
||||
'JOD' => 'Jordanian dinar',
|
||||
'JPY' => 'Japanese yen',
|
||||
'KES' => 'Kenyan shilling',
|
||||
'KGS' => 'Kyrgyzstani som',
|
||||
'KHR' => 'Cambodian riel',
|
||||
'KMF' => 'Comorian franc',
|
||||
'KPW' => 'North Korean won',
|
||||
'KRW' => 'South Korean won',
|
||||
'KWD' => 'Kuwaiti dinar',
|
||||
'KYD' => 'Cayman Islands dollar',
|
||||
'KZT' => 'Kazakhstani tenge',
|
||||
'LAK' => 'Lao kip',
|
||||
'LBP' => 'Lebanese lira',
|
||||
'LKR' => 'Sri Lankan rupee',
|
||||
'LRD' => 'Liberian dollar',
|
||||
'LSL' => 'Lesotho loti',
|
||||
'LTL' => 'Lithuanian litas',
|
||||
'LVL' => 'Latvian lats',
|
||||
'LYD' => 'Libyan dinar',
|
||||
'MAD' => 'Moroccan dirham',
|
||||
'MDL' => 'Moldovan leu',
|
||||
'MGA' => 'Malagasy ariary',
|
||||
'MKD' => 'Macedonian denar',
|
||||
'MMK' => 'Myanma kyat',
|
||||
'MNT' => 'Mongolian tugrik',
|
||||
'MOP' => 'Macanese pataca',
|
||||
'MRO' => 'Mauritanian ouguiya',
|
||||
'MUR' => 'Mauritian rupee',
|
||||
'MVR' => 'Maldivian rufiyaa',
|
||||
'MWK' => 'Malawian kwacha',
|
||||
'MXN' => 'Mexican peso',
|
||||
'MYR' => 'Malaysian ringgit',
|
||||
'MZM' => 'Mozambican metical',
|
||||
'NAD' => 'Namibian dollar',
|
||||
'NGN' => 'Nigerian naira',
|
||||
'NIO' => 'Nicaraguan córdoba',
|
||||
'NOK' => 'Norwegian krone',
|
||||
'NPR' => 'Nepalese rupee',
|
||||
'NZD' => 'New Zealand dollar',
|
||||
'OMR' => 'Omani rial',
|
||||
'PAB' => 'Panamanian balboa',
|
||||
'PEN' => 'Peruvian nuevo sol',
|
||||
'PGK' => 'Papua New Guinean kina',
|
||||
'PHP' => 'Philippine peso',
|
||||
'PKR' => 'Pakistani rupee',
|
||||
'PLN' => 'Polish zloty',
|
||||
'PYG' => 'Paraguayan guarani',
|
||||
'QAR' => 'Qatari riyal',
|
||||
'RON' => 'Romanian leu',
|
||||
'RSD' => 'Serbian dinar',
|
||||
'RUB' => 'Russian ruble',
|
||||
'SAR' => 'Saudi riyal',
|
||||
'SBD' => 'Solomon Islands dollar',
|
||||
'SCR' => 'Seychellois rupee',
|
||||
'SDG' => 'Sudanese pound',
|
||||
'SEK' => 'Swedish krona',
|
||||
'SGD' => 'Singapore dollar',
|
||||
'SHP' => 'Saint Helena pound',
|
||||
'SLL' => 'Sierra Leonean leone',
|
||||
'SOS' => 'Somali shilling',
|
||||
'SRD' => 'Surinamese dollar',
|
||||
'SYP' => 'Syrian pound',
|
||||
'SZL' => 'Swazi lilangeni',
|
||||
'THB' => 'Thai baht',
|
||||
'TJS' => 'Tajikistani somoni',
|
||||
'TMT' => 'Turkmen manat',
|
||||
'TND' => 'Tunisian dinar',
|
||||
'TRY' => 'Turkish new lira',
|
||||
'TTD' => 'Trinidad and Tobago dollar',
|
||||
'TWD' => 'New Taiwan dollar',
|
||||
'TZS' => 'Tanzanian shilling',
|
||||
'UAH' => 'Ukrainian hryvnia',
|
||||
'UGX' => 'Ugandan shilling',
|
||||
'USD' => 'United States dollar',
|
||||
'UYU' => 'Uruguayan peso',
|
||||
'UZS' => 'Uzbekistani som',
|
||||
'VEB' => 'Venezuelan bolivar',
|
||||
'VND' => 'Vietnamese dong',
|
||||
'VUV' => 'Vanuatu vatu',
|
||||
'WST' => 'Samoan tala',
|
||||
'XAF' => 'Central African CFA franc',
|
||||
'XCD' => 'East Caribbean dollar',
|
||||
'XDR' => 'Special Drawing Rights',
|
||||
'XOF' => 'West African CFA franc',
|
||||
'XPF' => 'CFP franc',
|
||||
'YER' => 'Yemeni rial',
|
||||
'ZAR' => 'South African rand',
|
||||
'ZMK' => 'Zambian kwacha',
|
||||
'ZWR' => 'Zimbabwean dollar',
|
||||
];
|
||||
}
|
||||
|
||||
38
app/Http/Controllers/ApplicationController.php
Normal file
38
app/Http/Controllers/ApplicationController.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Application;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApplicationController extends Controller
|
||||
{
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'career_id' => 'required|exists:careers,id',
|
||||
'name' => 'required|string|max:255',
|
||||
'birthdate' => 'required|date',
|
||||
'resume_file' => 'required|file|mimes:pdf,doc,docx|max:2048',
|
||||
'email' => 'required|email|max:255',
|
||||
'phone_number' => 'required|string',
|
||||
'cover_letter' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$resumePath = $request->file('resume_file')->store('resumes');
|
||||
|
||||
Application::create([
|
||||
'career_id' => $validatedData['career_id'],
|
||||
'name' => $validatedData['name'],
|
||||
'birthdate' => $validatedData['birthdate'],
|
||||
'resume_file' => $resumePath,
|
||||
'email' => $validatedData['email'],
|
||||
'phone_number' => $validatedData['phone_number'],
|
||||
'cover_letter' => $validatedData['cover_letter'] ?? null,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Your application has been submitted successfully!',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BrandController extends Controller
|
||||
{
|
||||
//
|
||||
|
||||
@@ -3,18 +3,14 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Career;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CareersPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('web.pages.careers.index');
|
||||
}
|
||||
$careers = Career::query()->get();
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
dd($request->all());
|
||||
return view('web.pages.careers.index', compact('careers'));
|
||||
}
|
||||
|
||||
public function show(Career $career)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\News;
|
||||
use App\Settings\HomeSettings;
|
||||
|
||||
class HomePageController extends Controller
|
||||
@@ -11,7 +12,8 @@ class HomePageController extends Controller
|
||||
{
|
||||
$brands = Brand::query()->get(['id', 'image']);
|
||||
$homeSettings = app(HomeSettings::class);
|
||||
$allNews = News::query()->latest()->take(3)->get();
|
||||
|
||||
return view('web.pages.home.index', compact('homeSettings', 'brands'));
|
||||
return view('web.pages.home.index', compact('homeSettings', 'brands', 'allNews'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,46 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Internship;
|
||||
use App\Models\InternshipApplication;
|
||||
use Illuminate\Http\Request; // Changed from App\Models\Application
|
||||
|
||||
class InternshipsPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('web.pages.internships.index');
|
||||
$internships = Internship::query()->get();
|
||||
|
||||
return view('web.pages.internships.index', compact('internships'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
dd($request->all());
|
||||
$validatedData = $request->validate([
|
||||
'internship_id' => 'required|exists:internships,id',
|
||||
'name' => 'required|string|max:255',
|
||||
'birthdate' => 'required|date',
|
||||
'resume_file' => 'required|file|mimes:pdf,doc,docx|max:2048',
|
||||
'email' => 'required|email|max:255',
|
||||
'phone_number' => 'required|string',
|
||||
'cover_letter' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$resumePath = $request->file('resume_file')->store('resumes');
|
||||
|
||||
InternshipApplication::create([ // Changed to InternshipApplication::create
|
||||
'internship_id' => $validatedData['internship_id'],
|
||||
'name' => $validatedData['name'],
|
||||
'birthdate' => $validatedData['birthdate'],
|
||||
'resume_file' => $resumePath,
|
||||
'email' => $validatedData['email'],
|
||||
'phone_number' => $validatedData['phone_number'],
|
||||
'cover_letter' => $validatedData['cover_letter'] ?? null,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Your application has been submitted successfully!',
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Internship $internship)
|
||||
|
||||
@@ -3,16 +3,35 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\News;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class NewsPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('web.pages.news.index');
|
||||
$allNews = News::query()->with('author')->latest()->get();
|
||||
|
||||
return view('web.pages.news.index', compact('allNews'));
|
||||
}
|
||||
|
||||
public function show(News $news)
|
||||
public function show($news)
|
||||
{
|
||||
return view('web.pages.news.show', compact('news'));
|
||||
$news = News::where('slug', $news)->with('author', 'comments')->first();
|
||||
$recentNews = News::query()->with('author')->latest()->limit(3)->get();
|
||||
|
||||
return view('web.pages.news.show', compact('news', 'recentNews'));
|
||||
}
|
||||
|
||||
public function storeComment(Request $request, News $news)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'message' => 'required|string',
|
||||
'author_name' => 'nullable|string|max:255',
|
||||
]);
|
||||
|
||||
$news->comments()->create($validated);
|
||||
|
||||
return back()->with('success', 'Comment added successfully!');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@ class OurSolutionPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('web.pages.our-solutions.index');
|
||||
}
|
||||
public function show(Solution $solution)
|
||||
$solutions = Solution::query()->latest()->get();
|
||||
|
||||
return view('web.pages.our-solutions.index', compact('solutions'));
|
||||
}
|
||||
|
||||
public function show(Solution $solution)
|
||||
{
|
||||
return view('web.pages.our-solutions.show', compact('solution'));
|
||||
}
|
||||
|
||||
24
app/Http/Controllers/Web/SuccessPageController.php
Normal file
24
app/Http/Controllers/Web/SuccessPageController.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Success;
|
||||
|
||||
class SuccessPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$allSuccesses = Success::query()->latest()->get();
|
||||
|
||||
return view('web.pages.success.index', compact('allSuccesses'));
|
||||
}
|
||||
|
||||
public function show($success)
|
||||
{
|
||||
$success = Success::where('slug', $success)->firstOrFail();
|
||||
$recentSuccesses = Success::query()->latest()->limit(3)->get();
|
||||
|
||||
return view('web.pages.success.show', compact('success', 'recentSuccesses'));
|
||||
}
|
||||
}
|
||||
33
app/Http/Middleware/SetLocale.php
Normal file
33
app/Http/Middleware/SetLocale.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SetLocale
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$locale = $request->query('lang');
|
||||
|
||||
if ($locale && in_array($locale, config('app.available_locales'))) {
|
||||
App::setLocale($locale);
|
||||
Session::put('locale', $locale);
|
||||
} elseif (Session::has('locale')) {
|
||||
App::setLocale(Session::get('locale'));
|
||||
} else {
|
||||
App::setLocale(config('app.fallback_locale', 'en'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
24
app/Models/Application.php
Normal file
24
app/Models/Application.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Application extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'career_id',
|
||||
'name',
|
||||
'birthdate',
|
||||
'resume_file',
|
||||
'email',
|
||||
'phone_number',
|
||||
'cover_letter',
|
||||
];
|
||||
|
||||
public function career(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Career::class);
|
||||
}
|
||||
}
|
||||
23
app/Models/Author.php
Normal file
23
app/Models/Author.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Author extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'profile_image',
|
||||
];
|
||||
|
||||
public function news(): HasMany
|
||||
{
|
||||
return $this->hasMany(News::class);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Storage;
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $image
|
||||
* @property boolean $active
|
||||
* @property bool $active
|
||||
* @property \Illuminate\Support\Facades\Date $created_at
|
||||
* @property \Illuminate\Support\Facades\Date $updated_at
|
||||
*/
|
||||
@@ -17,6 +17,7 @@ class Brand extends Model
|
||||
{
|
||||
/**
|
||||
* Casts
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
@@ -40,6 +41,6 @@ class Brand extends Model
|
||||
*/
|
||||
public function imageUrl(): string
|
||||
{
|
||||
return url('/storage/' . $this->image);
|
||||
return url('/storage/'.$this->image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,25 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Career extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'description',
|
||||
'title_description',
|
||||
'salary_per_month',
|
||||
'bullets',
|
||||
'location',
|
||||
'salary',
|
||||
'salary_currency',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'bullets' => 'array',
|
||||
];
|
||||
|
||||
public function applications(): HasMany
|
||||
{
|
||||
return $this->hasMany(Application::class);
|
||||
}
|
||||
}
|
||||
|
||||
24
app/Models/Comment.php
Normal file
24
app/Models/Comment.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'message',
|
||||
'author_name',
|
||||
'news_id',
|
||||
];
|
||||
|
||||
public function news(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(News::class);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,25 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Internship extends Model
|
||||
{
|
||||
//
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'title_description',
|
||||
'salary_per_month',
|
||||
'bullets',
|
||||
'location',
|
||||
'salary_currency',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'bullets' => 'array',
|
||||
];
|
||||
|
||||
public function applications(): HasMany
|
||||
{
|
||||
return $this->hasMany(InternshipApplication::class);
|
||||
}
|
||||
}
|
||||
|
||||
24
app/Models/InternshipApplication.php
Normal file
24
app/Models/InternshipApplication.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class InternshipApplication extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'internship_id',
|
||||
'name',
|
||||
'birthdate',
|
||||
'resume_file',
|
||||
'email',
|
||||
'phone_number',
|
||||
'cover_letter',
|
||||
];
|
||||
|
||||
public function internship(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Internship::class);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class News extends Model
|
||||
{
|
||||
@@ -13,6 +15,18 @@ class News extends Model
|
||||
'title',
|
||||
'slug',
|
||||
'content',
|
||||
'image',
|
||||
'published_at',
|
||||
'author_id',
|
||||
];
|
||||
}
|
||||
|
||||
public function comments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function author(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Author::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,15 @@ class Solution extends Model
|
||||
'title',
|
||||
'description',
|
||||
'slug',
|
||||
'title_description',
|
||||
'bullets',
|
||||
'downloads',
|
||||
'faqs',
|
||||
];
|
||||
}
|
||||
|
||||
protected $casts = [
|
||||
'bullets' => 'array',
|
||||
'downloads' => 'array',
|
||||
'faqs' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -15,4 +15,4 @@ class Story extends Model
|
||||
'content',
|
||||
'published_at',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
19
app/Models/Success.php
Normal file
19
app/Models/Success.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Success extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'slug',
|
||||
'content',
|
||||
'image',
|
||||
'published_at',
|
||||
];
|
||||
}
|
||||
10
app/Models/TeamMember.php
Normal file
10
app/Models/TeamMember.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TeamMember extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
enum UserRole: string
|
||||
{
|
||||
case ADMIN = 'admin';
|
||||
case MANAGER = 'manager';
|
||||
case NEWS_WRITER = 'news_writer';
|
||||
}
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
@@ -21,6 +28,7 @@ class User extends Authenticatable
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -43,6 +51,12 @@ class User extends Authenticatable
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'role' => UserRole::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function canManageSettings(): bool
|
||||
{
|
||||
return $this->role === UserRole::ADMIN || $this->role === UserRole::MANAGER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\Solution;
|
||||
use App\Settings\SiteSettings;
|
||||
use App\Settings\SiteSocialSettings;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Settings\HomeSettings;
|
||||
use Illuminate\Support\Facades\View as ViewFacade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\View\View;
|
||||
@@ -29,6 +28,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
Model::unguard();
|
||||
|
||||
$this->addSettingsToViews();
|
||||
$this->addSolutionsToViews();
|
||||
|
||||
// logDB();
|
||||
}
|
||||
@@ -43,4 +43,14 @@ class AppServiceProvider extends ServiceProvider
|
||||
$view->with('socialMedia', app(SiteSocialSettings::class));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add solutions to views
|
||||
*/
|
||||
public function addSolutionsToViews(): void
|
||||
{
|
||||
ViewFacade::composer(['web.layouts.navigation.header'], function (View $view) {
|
||||
$view->with('solutions', Solution::query()->latest()->get());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use App\Filament\Pages\HomePageSettings;
|
||||
use App\Filament\Pages\ManageCtaSettings;
|
||||
use App\Filament\Resources\ApplicationResource;
|
||||
use App\Models\User;
|
||||
use App\Models\UserRole;
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\AuthenticateSession;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||
use Filament\Pages;
|
||||
@@ -15,8 +19,11 @@ use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
use Filament\SpatieLaravelTranslatablePlugin;
|
||||
|
||||
class PanelPanelProvider extends PanelProvider
|
||||
{
|
||||
@@ -27,18 +34,30 @@ class PanelPanelProvider extends PanelProvider
|
||||
->id('panel')
|
||||
->path('panel')
|
||||
->login()
|
||||
->profile()
|
||||
->colors([
|
||||
'primary' => Color::Amber,
|
||||
])
|
||||
->navigationGroups([
|
||||
'Home',
|
||||
'About US',
|
||||
'Our Solutions',
|
||||
'News & Stories',
|
||||
'Careers',
|
||||
'Contact',
|
||||
'Settings',
|
||||
'Activities',
|
||||
])
|
||||
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
|
||||
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
|
||||
->pages([
|
||||
Pages\Dashboard::class,
|
||||
HomePageSettings::class,
|
||||
ManageCtaSettings::class,
|
||||
])
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
Widgets\AccountWidget::class,
|
||||
Widgets\FilamentInfoWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
@@ -56,6 +75,34 @@ class PanelPanelProvider extends PanelProvider
|
||||
])
|
||||
->resources([
|
||||
config('filament-logger.activity_resource'),
|
||||
]);
|
||||
ApplicationResource::class,
|
||||
])
|
||||
->plugin(
|
||||
SpatieLaravelTranslatablePlugin::make()
|
||||
->defaultLocales(['en', 'ru', 'tk'])
|
||||
);
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
Gate::before(function (User $user, string $ability) {
|
||||
if ($user->role === UserRole::ADMIN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
Gate::define('view-activity-logs', function (User $user) {
|
||||
return $user->role === UserRole::ADMIN;
|
||||
});
|
||||
|
||||
Gate::define('manage-news-and-success', function (User $user) {
|
||||
return $user->role === UserRole::NEWS_WRITER || $user->role === UserRole::ADMIN || $user->role === UserRole::MANAGER;
|
||||
});
|
||||
|
||||
Gate::define('view-authors', function (User $user) {
|
||||
return $user->role === UserRole::NEWS_WRITER || $user->role === UserRole::ADMIN || $user->role === UserRole::MANAGER;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
57
app/Settings/AboutSettings.php
Normal file
57
app/Settings/AboutSettings.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class AboutSettings extends Settings
|
||||
{
|
||||
// Our Story Section
|
||||
public string $our_story_title;
|
||||
|
||||
public string $our_story_subtitle;
|
||||
|
||||
public string $our_story_paragraph_one;
|
||||
|
||||
public string $our_story_paragraph_two;
|
||||
|
||||
public string $our_story_paragraph_three;
|
||||
|
||||
public string $our_story_button_text;
|
||||
|
||||
public string $our_story_button_url;
|
||||
|
||||
public string $our_story_video_poster;
|
||||
|
||||
public string $our_story_video_source;
|
||||
|
||||
// Our Journey Section
|
||||
public string $our_journey_title;
|
||||
|
||||
public string $our_journey_subtitle;
|
||||
|
||||
public array $our_journey_milestones; // [{year: 2010, title: "Start Company", description: "...", image: "..."}]
|
||||
|
||||
// Company Structure Section
|
||||
public string $company_structure_title;
|
||||
|
||||
public string $company_structure_subtitle;
|
||||
|
||||
public string $company_structure_director_name;
|
||||
|
||||
public string $company_structure_advisor_name;
|
||||
|
||||
public array $company_structure_departments; // [{name: "HSE", person: "Michael Brown"}]
|
||||
|
||||
// Our Facilities Section
|
||||
public string $our_facilities_title;
|
||||
|
||||
public string $our_facilities_subtitle;
|
||||
|
||||
public array $our_facilities_locations; // [{name: "Headquarters", location: "...", description: "...", image: "...", tags: ["R&D Labs"]}]
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cms_aboutpage';
|
||||
}
|
||||
}
|
||||
27
app/Settings/ContactSettings.php
Normal file
27
app/Settings/ContactSettings.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class ContactSettings extends Settings
|
||||
{
|
||||
public string $contact_subtitle = 'Default Contact Subtitle';
|
||||
|
||||
public string $contact_header = 'Default Contact Header';
|
||||
|
||||
public string $contact_paragraph = 'This is a default paragraph for the contact page. Please update it from the Filament panel.';
|
||||
|
||||
public string $phone_number = '+1234567890';
|
||||
|
||||
public string $email_address = 'info@example.com';
|
||||
|
||||
public string $location_address = '123 Main St, Anytown, USA';
|
||||
|
||||
public string $map_embed_url = '';
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'contact';
|
||||
}
|
||||
}
|
||||
21
app/Settings/CtaSettings.php
Normal file
21
app/Settings/CtaSettings.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class CtaSettings extends Settings
|
||||
{
|
||||
public string $title;
|
||||
|
||||
public string $button_text;
|
||||
|
||||
public string $button_url;
|
||||
|
||||
public string $background_image;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cta';
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,30 @@ class HomeSettings extends Settings
|
||||
|
||||
public string $about_image_two;
|
||||
|
||||
public string $industry_subtitle;
|
||||
|
||||
public string $industry_header;
|
||||
|
||||
public string $industry_paragraph;
|
||||
|
||||
public string $industry_button_text;
|
||||
|
||||
public string $industry_button_url;
|
||||
|
||||
public string $industry_image_one;
|
||||
|
||||
public array $industry_items;
|
||||
|
||||
public string $text_slide_subtitle;
|
||||
|
||||
public string $text_slide_header;
|
||||
|
||||
public string $text_slide_image;
|
||||
|
||||
public int $text_slide_counter_number;
|
||||
|
||||
public array $text_slide_items;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cms_homepage';
|
||||
|
||||
21
app/Settings/PortfolioSettings.php
Normal file
21
app/Settings/PortfolioSettings.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class PortfolioSettings extends Settings
|
||||
{
|
||||
public string $portfolio_header;
|
||||
|
||||
public string $portfolio_button_text;
|
||||
|
||||
public string $portfolio_button_url;
|
||||
|
||||
public array $portfolio_items;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cms_portfolio';
|
||||
}
|
||||
}
|
||||
25
app/Settings/SolutionSettings.php
Normal file
25
app/Settings/SolutionSettings.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class SolutionSettings extends Settings
|
||||
{
|
||||
public string $solutions_subtitle;
|
||||
|
||||
public string $solutions_header;
|
||||
|
||||
public string $solutions_button_text;
|
||||
|
||||
public string $solutions_button_url;
|
||||
|
||||
public ?string $solutions_image;
|
||||
|
||||
public array $solution_items;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cms_solutions';
|
||||
}
|
||||
}
|
||||
27
app/Settings/SuccessSettings.php
Normal file
27
app/Settings/SuccessSettings.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Settings;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class SuccessSettings extends Settings
|
||||
{
|
||||
public string $success_subtitle;
|
||||
|
||||
public string $success_header;
|
||||
|
||||
public string $success_paragraph;
|
||||
|
||||
public string $success_button_text;
|
||||
|
||||
public string $success_button_url;
|
||||
|
||||
public array $skill_items;
|
||||
|
||||
public string $success_image;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'cms_success';
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,9 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
//
|
||||
$middleware->web(append: [
|
||||
\App\Http\Middleware\SetLocale::class,
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
//
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
"php": "^8.2",
|
||||
"filament/filament": "^3.3",
|
||||
"filament/spatie-laravel-settings-plugin": "^3.2",
|
||||
"filament/spatie-laravel-translatable-plugin": "^3.2",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"spatie/laravel-translatable": "^6.11",
|
||||
"z3d0x/filament-logger": "^0.8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -58,6 +60,10 @@
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
||||
],
|
||||
"network": [
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve --host=0.0.0.0\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
|
||||
],
|
||||
"test": [
|
||||
"@php artisan config:clear --ansi",
|
||||
"@php artisan test"
|
||||
|
||||
661
composer.lock
generated
661
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -84,6 +84,19 @@ return [
|
||||
|
||||
'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Available Locales
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The application locales that are available for your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'available_locales' => [
|
||||
'en', 'ru', 'tk'
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Encryption Key
|
||||
|
||||
101
config/filament.php
Normal file
101
config/filament.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Broadcasting
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By uncommenting the Laravel Echo configuration, you may connect Filament
|
||||
| to any Pusher-compatible websockets server.
|
||||
|
|
||||
| This will allow your users to receive real-time notifications.
|
||||
|
|
||||
*/
|
||||
|
||||
'broadcasting' => [
|
||||
|
||||
// 'echo' => [
|
||||
// 'broadcaster' => 'pusher',
|
||||
// 'key' => env('VITE_PUSHER_APP_KEY'),
|
||||
// 'cluster' => env('VITE_PUSHER_APP_CLUSTER'),
|
||||
// 'wsHost' => env('VITE_PUSHER_HOST'),
|
||||
// 'wsPort' => env('VITE_PUSHER_PORT'),
|
||||
// 'wssPort' => env('VITE_PUSHER_PORT'),
|
||||
// 'authEndpoint' => '/broadcasting/auth',
|
||||
// 'disableStats' => true,
|
||||
// 'encrypted' => true,
|
||||
// 'forceTLS' => true,
|
||||
// ],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Filesystem Disk
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the storage disk Filament will use to store files. You may use
|
||||
| any of the disks defined in the `config/filesystems.php`.
|
||||
|
|
||||
*/
|
||||
|
||||
'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DISK', 'public'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Assets Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the directory where Filament's assets will be published to. It
|
||||
| is relative to the `public` directory of your Laravel application.
|
||||
|
|
||||
| After changing the path, you should run `php artisan filament:assets`.
|
||||
|
|
||||
*/
|
||||
|
||||
'assets_path' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the directory that Filament will use to store cache files that
|
||||
| are used to optimize the registration of components.
|
||||
|
|
||||
| After changing the path, you should run `php artisan filament:cache-components`.
|
||||
|
|
||||
*/
|
||||
|
||||
'cache_path' => base_path('bootstrap/cache/filament'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Livewire Loading Delay
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This sets the delay before loading indicators appear.
|
||||
|
|
||||
| Setting this to 'none' makes indicators appear immediately, which can be
|
||||
| desirable for high-latency connections. Setting it to 'default' applies
|
||||
| Livewire's standard 200ms delay.
|
||||
|
|
||||
*/
|
||||
|
||||
'livewire_loading_delay' => 'default',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| System Route Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the prefix used for the system routes that Filament registers,
|
||||
| such as the routes for downloading exports and failed import rows.
|
||||
|
|
||||
*/
|
||||
|
||||
'system_route_prefix' => 'filament',
|
||||
|
||||
];
|
||||
160
config/livewire.php
Normal file
160
config/livewire.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Class Namespace
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| This value sets the root class namespace for Livewire component classes in
|
||||
| your application. This value will change where component auto-discovery
|
||||
| finds components. It's also referenced by the file creation commands.
|
||||
|
|
||||
*/
|
||||
|
||||
'class_namespace' => 'App\\Livewire',
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| View Path
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| This value is used to specify where Livewire component Blade templates are
|
||||
| stored when running file creation commands like `artisan make:livewire`.
|
||||
| It is also used if you choose to omit a component's render() method.
|
||||
|
|
||||
*/
|
||||
|
||||
'view_path' => resource_path('views/livewire'),
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Layout
|
||||
|---------------------------------------------------------------------------
|
||||
| The view that will be used as the layout when rendering a single component
|
||||
| as an entire page via `Route::get('/post/create', CreatePost::class);`.
|
||||
| In this case, the view returned by CreatePost will render into $slot.
|
||||
|
|
||||
*/
|
||||
|
||||
'layout' => 'components.layouts.app',
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Lazy Loading Placeholder
|
||||
|---------------------------------------------------------------------------
|
||||
| Livewire allows you to lazy load components that would otherwise slow down
|
||||
| the initial page load. Every component can have a custom placeholder or
|
||||
| you can define the default placeholder view for all components below.
|
||||
|
|
||||
*/
|
||||
|
||||
'lazy_placeholder' => null,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Temporary File Uploads
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| Livewire handles file uploads by storing uploads in a temporary directory
|
||||
| before the file is stored permanently. All file uploads are directed to
|
||||
| a global endpoint for temporary storage. You may configure this below:
|
||||
|
|
||||
*/
|
||||
|
||||
'temporary_file_upload' => [
|
||||
'disk' => null, // Example: 'local', 's3' | Default: 'default'
|
||||
'rules' => ['required', 'file', 'max:100000'], // Example: ['file', 'mimes:png,jpg'] | Default: ['required', 'file', 'max:12288'] (12MB)
|
||||
'directory' => null, // Example: 'tmp' | Default: 'livewire-tmp'
|
||||
'middleware' => null, // Example: 'throttle:5,1' | Default: 'throttle:60,1'
|
||||
'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs...
|
||||
'png', 'gif', 'bmp', 'svg', 'wav', 'mp4',
|
||||
'mov', 'avi', 'wmv', 'mp3', 'm4a',
|
||||
'jpg', 'jpeg', 'mpga', 'webp', 'wma',
|
||||
],
|
||||
'max_upload_time' => 20, // Max duration (in minutes) before an upload is invalidated...
|
||||
'cleanup' => true, // Should cleanup temporary uploads older than 24 hrs...
|
||||
],
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Render On Redirect
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines if Livewire will run a component's `render()` method
|
||||
| after a redirect has been triggered using something like `redirect(...)`
|
||||
| Setting this to true will render the view once more before redirecting
|
||||
|
|
||||
*/
|
||||
|
||||
'render_on_redirect' => false,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Eloquent Model Binding
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| Previous versions of Livewire supported binding directly to eloquent model
|
||||
| properties using wire:model by default. However, this behavior has been
|
||||
| deemed too "magical" and has therefore been put under a feature flag.
|
||||
|
|
||||
*/
|
||||
|
||||
'legacy_model_binding' => false,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Auto-inject Frontend Assets
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| By default, Livewire automatically injects its JavaScript and CSS into the
|
||||
| <head> and <body> of pages containing Livewire components. By disabling
|
||||
| this behavior, you need to use @livewireStyles and @livewireScripts.
|
||||
|
|
||||
*/
|
||||
|
||||
'inject_assets' => true,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Navigate (SPA mode)
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| By adding `wire:navigate` to links in your Livewire application, Livewire
|
||||
| will prevent the default link handling and instead request those pages
|
||||
| via AJAX, creating an SPA-like effect. Configure this behavior here.
|
||||
|
|
||||
*/
|
||||
|
||||
'navigate' => [
|
||||
'show_progress_bar' => true,
|
||||
'progress_bar_color' => '#2299dd',
|
||||
],
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| HTML Morph Markers
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| Livewire intelligently "morphs" existing HTML into the newly rendered HTML
|
||||
| after each update. To make this process more reliable, Livewire injects
|
||||
| "markers" into the rendered Blade surrounding @if, @class & @foreach.
|
||||
|
|
||||
*/
|
||||
|
||||
'inject_morph_markers' => true,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| Pagination Theme
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| When enabling Livewire's pagination feature by using the `WithPagination`
|
||||
| trait, Livewire will use Tailwind templates to render pagination views
|
||||
| on the page. If you want Bootstrap CSS, you can specify: "bootstrap"
|
||||
|
|
||||
*/
|
||||
|
||||
'pagination_theme' => 'tailwind',
|
||||
];
|
||||
@@ -14,6 +14,7 @@ return [
|
||||
GeneralSettings::class,
|
||||
SiteSettings::class,
|
||||
HomeSettings::class,
|
||||
\App\Settings\ContactSettings::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
25
database/factories/NewsFactory.php
Normal file
25
database/factories/NewsFactory.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\News;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NewsFactory extends Factory
|
||||
{
|
||||
protected $model = News::class;
|
||||
|
||||
public function definition()
|
||||
{
|
||||
$title = $this->faker->sentence(6);
|
||||
|
||||
return [
|
||||
'title' => $title,
|
||||
'slug' => Str::slug($title),
|
||||
'content' => $this->faker->paragraphs(3, true),
|
||||
'image' => 'news/'.$this->faker->image('public/storage/news', 640, 480, null, false),
|
||||
'published_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('solutions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->text('description');
|
||||
$table->string('slug')->unique();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('news', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('slug')->unique();
|
||||
$table->longText('content');
|
||||
$table->string('image')->nullable();
|
||||
$table->timestamp('published_at');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ return new class extends Migration
|
||||
Schema::create('careers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->text('description');
|
||||
$table->text('title_description')->nullable();
|
||||
$table->string('salary_per_month')->nullable();
|
||||
$table->json('bullets')->nullable();
|
||||
$table->string('location');
|
||||
$table->string('salary')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->string('author')->after('image')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->dropColumn('author');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('comments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->text('message');
|
||||
$table->string('author_name')->nullable();
|
||||
$table->foreignId('news_id')->constrained()->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('comments');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
return new class extends SettingsMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->add('cta.title', 'Join Our Community and Access Exclusive Insights Today');
|
||||
$this->migrator->add('cta.button_text', 'Free Consultation');
|
||||
$this->migrator->add('cta.button_url', 'request-quote.html');
|
||||
$this->migrator->add('cta.background_image', '');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('solutions', function (Blueprint $table) {
|
||||
$table->string('title_description')->nullable()->after('description');
|
||||
$table->json('bullets')->nullable()->after('title_description');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('solutions', function (Blueprint $table) {
|
||||
$table->dropColumn(['title_description', 'bullets']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->longText('author_description')->nullable()->after('author');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->dropColumn('author_description');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('authors', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->longText('description')->nullable();
|
||||
$table->string('profile_image')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('authors');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->foreignId('author_id')->nullable()->constrained()->onDelete('set null');
|
||||
$table->dropColumn('author');
|
||||
$table->dropColumn('author_description');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('news', function (Blueprint $table) {
|
||||
$table->dropForeign(['author_id']);
|
||||
$table->dropColumn('author_id');
|
||||
$table->string('author')->nullable();
|
||||
$table->string('author_description')->nullable();
|
||||
});
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user