Compare commits

...

19 Commits

Author SHA1 Message Date
bc56a1824f Add Filament Spatie Laravel Translatable Plugin and update dependencies in composer files
- Added the `filament/spatie-laravel-translatable-plugin` to `composer.json` for enhanced localization support.
- Updated `composer.lock` to reflect the addition of the new plugin and updated versions for several dependencies, including `doctrine/dbal`, `phpstan/phpstan`, and `phpunit/phpunit`.
- Modified `PanelPanelProvider.php` to integrate the translatable plugin with default locales for improved internationalization.
2025-07-29 18:30:32 +05:00
6405150dd2 Remove language files for English, Russian, and Turkmen, streamlining localization resources as part of the ongoing internationalization efforts. 2025-07-29 18:24:17 +05:00
1a3f82b22c Implement language switcher functionality and enhance localization support: add available locales configuration, update SetLocale middleware to handle language selection via query parameters, and integrate language switcher buttons in the settings layout. Additionally, update various views to utilize translation functions for improved internationalization, ensuring consistent language support across the application. 2025-07-29 17:04:13 +05:00
0b6cbc8d9e ok 2025-07-29 16:44:00 +05:00
834822e182 Remove welcome.blade.php and update various views to use translation functions for improved localization support. Changes include updating labels, titles, and alerts across multiple pages to utilize the __('') function, enhancing the application's internationalization capabilities. 2025-07-29 16:39:27 +05:00
e927a912e1 lang 2025-07-29 16:17:32 +05:00
643ccd6d9e Add role-based access control to various settings pages: implement canAccess method in AboutPageSettings, ContactPageSettings, HomePageSettings, ManageCtaSettings, ManagePortfolio, ManageSite, ManageSiteSocialSettings, ManageSolutions, ManageSuccess, and update User model to include canManageSettings method for enhanced security and user experience. 2025-07-29 15:54:16 +05:00
3e80ea4d5e Update .gitignore to include IntelephenseHelper.php, ensuring proper file management and preventing unnecessary tracking of this file. 2025-07-29 15:45:42 +05:00
fe42967a74 Add role-based access control to management pages: implement canView method in ManageCtaSettings, ManagePortfolio, ManageSolutions, and ManageSuccess classes to restrict access to ADMIN and MANAGER roles, enhancing security and user experience. 2025-07-29 15:45:22 +05:00
a1826ae53c Add user role management: introduce UserRole enum for role definitions, implement role-based access control in various resources and pages, and enhance authorization logic in the PanelProvider for improved security and user experience. 2025-07-29 15:33:36 +05:00
c7e01f404d Update navigation groups for various resources: change navigation group names for AboutPageSettings, ContactPageSettings, AuthorResource, BrandResource, CommentResource, InternshipResource, NewsResource, SolutionResource, SuccessResource, and TeamMemberResource to better reflect their content. Enhance panel navigation structure by adding new groups for improved organization. 2025-07-29 15:14:36 +05:00
0a3fdf347f Add downloads and FAQs functionality to SolutionResource: implement repeaters for downloads and FAQs in the form, update Solution model to include new fields, and enhance the show view to display downloads and FAQs dynamically, improving content management and user experience. 2025-07-29 14:54:13 +05:00
e97a80bfdb Enhance SolutionResource form functionality: add debounce to slug generation for improved user experience during input, and adjust layout in show.blade.php by reducing column width for better content presentation. 2025-07-29 14:48:23 +05:00
dd167d9aaa Enhance pricing section layout: update _pricing.scss to use flexbox for better alignment and spacing. Modify breadcrumb links in show.blade.php for correct asset paths and simplify the layout by removing the sidebar, allowing for a more streamlined content presentation. 2025-07-29 14:41:26 +05:00
8f36f7d715 wip 2025-07-29 14:31:47 +05:00
453e8caa82 Refactor About page settings: replace management section with a video upload feature, update view to display static management information, and clean up related settings for improved content management and user experience. 2025-07-29 14:28:03 +05:00
76397637f0 Integrate dynamic settings into About page: update content sections to utilize AboutSettings for titles, subtitles, paragraphs, and media sources, enhancing content management and user experience. 2025-07-29 14:16:10 +05:00
8e770941fa Refactor resource files: remove unused imports and clean up code across various resource and controller files for improved readability and maintainability. Update currency list formatting in helpers for consistency. 2025-07-29 13:29:23 +05:00
c37f5fadf1 Add contact settings integration: update contact page to utilize dynamic settings for subtitle, header, paragraph, contact details, and map embed URL, enhancing content management and user experience. 2025-07-29 13:22:44 +05:00
90 changed files with 2607 additions and 1386 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ yarn-error.log
/.vscode
/.zed
**/.DS_Store
IntelephenseHelper.php

View 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;
}
}

View 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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\HomeSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
@@ -292,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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\CtaSettings;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
@@ -42,4 +43,14 @@ class ManageCtaSettings extends SettingsPage
->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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\PortfolioSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
@@ -108,4 +109,14 @@ class ManagePortfolio extends SettingsPage
{
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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\SiteSettings;
use Filament\Forms;
use Filament\Forms\Form;
@@ -168,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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\SiteSocialSettings;
use Filament\Forms;
use Filament\Forms\Form;
@@ -77,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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\SolutionSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
@@ -376,4 +377,14 @@ class ManageSolutions extends SettingsPage
{
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;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Filament\Pages;
use App\Models\UserRole;
use App\Settings\SuccessSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
@@ -113,4 +114,14 @@ class ManageSuccess extends SettingsPage
{
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;
}
}

View File

@@ -3,16 +3,14 @@
namespace App\Filament\Resources;
use App\Filament\Resources\ApplicationResource\Pages;
use App\Filament\Resources\ApplicationResource\RelationManagers;
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;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class ApplicationResource extends Resource
{
@@ -107,4 +105,9 @@ class ApplicationResource extends Resource
'edit' => Pages\EditApplication::route('/{record}/edit'),
];
}
}
public static function canViewAny(): bool
{
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
}
}

View File

@@ -3,10 +3,9 @@
namespace App\Filament\Resources\ApplicationResource\Pages;
use App\Filament\Resources\ApplicationResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateApplication extends CreateRecord
{
protected static string $resource = ApplicationResource::class;
}
}

View File

@@ -16,4 +16,4 @@ class EditApplication extends EditRecord
Actions\DeleteAction::make(),
];
}
}
}

View File

@@ -16,4 +16,4 @@ class ListApplications extends ListRecords
Actions\CreateAction::make(),
];
}
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources;
use App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource\RelationManagers;
use App\Models\Author;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
@@ -15,7 +14,6 @@ use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class AuthorResource extends Resource
{
@@ -23,10 +21,9 @@ class AuthorResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-users';
protected static ?string $navigationGroup = 'News';
protected static ?string $navigationGroup = 'News & Stories';
public static function form(Form $form):
Form
public static function form(Form $form): Form
{
return $form
->schema([
@@ -95,4 +92,34 @@ class AuthorResource extends Resource
'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();
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAuthor extends CreateRecord

View File

@@ -4,6 +4,7 @@ namespace App\Filament\Resources;
use App\Filament\Resources\BrandResource\Pages;
use App\Models\Brand;
use App\Models\UserRole;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
@@ -21,7 +22,7 @@ class BrandResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-tag';
protected static ?string $navigationGroup = 'Brands';
protected static ?string $navigationGroup = 'Home';
public static function form(Form $form): Form
{
@@ -79,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;
}
}

View File

@@ -5,16 +5,15 @@ 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;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
class CareerResource extends Resource
{
@@ -119,4 +118,9 @@ class CareerResource extends Resource
'edit' => Pages\EditCareer::route('/{record}/edit'),
];
}
public static function canViewAny(): bool
{
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources\CareerResource\Pages;
use App\Filament\Resources\CareerResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCareer extends CreateRecord

View File

@@ -7,8 +7,6 @@ use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class ApplicationsRelationManager extends RelationManager
{

View File

@@ -4,6 +4,7 @@ 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;
@@ -19,7 +20,7 @@ class CommentResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-chat-bubble-bottom-center-text';
protected static ?string $navigationGroup = 'News';
protected static ?string $navigationGroup = 'News & Stories';
public static function form(Form $form): Form
{
@@ -93,4 +94,9 @@ class CommentResource extends Resource
'edit' => Pages\EditComment::route('/{record}/edit'),
];
}
public static function canViewAny(): bool
{
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
}
}

View File

@@ -5,22 +5,21 @@ 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;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
class InternshipResource extends Resource
{
protected static ?string $model = Internship::class;
protected static ?string $navigationGroup = 'Internships';
protected static ?string $navigationGroup = 'Careers';
protected static ?string $navigationIcon = 'heroicon-o-academic-cap';
@@ -53,7 +52,7 @@ class InternshipResource extends Resource
->label('Salary currency')
->searchable()
->default('USD'),
Repeater::make('bullets')
->schema([
TextInput::make('bullet')
@@ -122,4 +121,9 @@ class InternshipResource extends Resource
'edit' => Pages\EditInternship::route('/{record}/edit'),
];
}
}
public static function canViewAny(): bool
{
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
}
}

View File

@@ -3,10 +3,9 @@
namespace App\Filament\Resources\InternshipResource\Pages;
use App\Filament\Resources\InternshipResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateInternship extends CreateRecord
{
protected static string $resource = InternshipResource::class;
}
}

View File

@@ -16,4 +16,4 @@ class EditInternship extends EditRecord
Actions\DeleteAction::make(),
];
}
}
}

View File

@@ -16,4 +16,4 @@ class ListInternships extends ListRecords
Actions\CreateAction::make(),
];
}
}
}

View File

@@ -2,14 +2,12 @@
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;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use App\Models\InternshipApplication; // Added this use statement
use Filament\Tables\Table; // Added this use statement
class ApplicationsRelationManager extends RelationManager
{
@@ -80,4 +78,4 @@ class ApplicationsRelationManager extends RelationManager
]),
]);
}
}
}

View File

@@ -16,6 +16,7 @@ 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
@@ -24,7 +25,7 @@ class NewsResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-newspaper';
protected static ?string $navigationGroup = 'News';
protected static ?string $navigationGroup = 'News & Stories';
public static function form(Form $form): Form
{
@@ -123,4 +124,34 @@ class NewsResource extends Resource
'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();
}
}

View File

@@ -4,6 +4,7 @@ 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;
@@ -17,7 +18,7 @@ class SolutionResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-light-bulb';
protected static ?string $navigationGroup = 'Solutions';
protected static ?string $navigationGroup = 'Our Solutions';
public static function form(Form $form): Form
{
@@ -27,13 +28,14 @@ class SolutionResource extends Resource
->required()
->maxLength(255)
->reactive()
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
Forms\Components\TextInput::make('slug')
->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')
Forms\Components\TextInput::make('title_description')
->maxLength(255)
->required()
->columnSpanFull(),
@@ -48,10 +50,38 @@ class SolutionResource extends Resource
->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(),
]);
}
@@ -100,4 +130,9 @@ class SolutionResource extends Resource
'edit' => Pages\EditSolution::route('/{record}/edit'),
];
}
public static function canViewAny(): bool
{
return auth()->user()->role === UserRole::ADMIN || auth()->user()->role === UserRole::MANAGER;
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources;
use App\Filament\Resources\SuccessResource\Pages;
use App\Filament\Resources\SuccessResource\RelationManagers;
use App\Models\Success;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
@@ -15,6 +14,7 @@ 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
@@ -23,7 +23,7 @@ class SuccessResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-bookmark-square';
protected static ?string $navigationGroup = 'Success Stories';
protected static ?string $navigationGroup = 'News & Stories';
public static function form(Form $form): Form
{
@@ -113,4 +113,34 @@ class SuccessResource extends Resource
'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();
}
}

View File

@@ -3,7 +3,6 @@
namespace App\Filament\Resources\SuccessResource\Pages;
use App\Filament\Resources\SuccessResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateSuccess extends CreateRecord

View 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;
}
}

View File

@@ -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;
}

View File

@@ -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(),
];
}
}

View File

@@ -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(),
];
}
}

View File

@@ -20,161 +20,161 @@ function logDB(): void
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",
'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',
];
}

View File

@@ -2,8 +2,8 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Application;
use Illuminate\Http\Request;
class ApplicationController extends Controller
{

View File

@@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Models\Career;
use Illuminate\Http\Request;
class CareersPageController extends Controller
{

View File

@@ -3,8 +3,8 @@
namespace App\Http\Controllers;
use App\Models\Internship;
use Illuminate\Http\Request;
use App\Models\InternshipApplication; // Changed from App\Models\Application
use App\Models\InternshipApplication;
use Illuminate\Http\Request; // Changed from App\Models\Application
class InternshipsPageController extends Controller
{

View File

@@ -4,7 +4,6 @@ namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Success;
use Illuminate\Http\Request;
class SuccessPageController extends Controller
{

View 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);
}
}

View File

@@ -4,7 +4,6 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Career;
class Application extends Model
{

View File

@@ -4,7 +4,6 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Application;
class Career extends Model
{

View File

@@ -4,7 +4,6 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\InternshipApplication;
class Internship extends Model
{

View File

@@ -21,4 +21,4 @@ class InternshipApplication extends Model
{
return $this->belongsTo(Internship::class);
}
}
}

View File

@@ -15,9 +15,13 @@ class Solution extends Model
'slug',
'title_description',
'bullets',
'downloads',
'faqs',
];
protected $casts = [
'bullets' => 'array',
'downloads' => 'array',
'faqs' => 'array',
];
}

10
app/Models/TeamMember.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TeamMember extends Model
{
//
}

View File

@@ -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;
}
}

View File

@@ -5,6 +5,8 @@ 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\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
@@ -19,7 +21,9 @@ 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
{
@@ -30,9 +34,20 @@ 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([
@@ -43,7 +58,6 @@ class PanelPanelProvider extends PanelProvider
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
@@ -62,6 +76,33 @@ 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;
});
}
}

View 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';
}
}

View 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';
}
}

View File

@@ -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) {
//

View File

@@ -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": {

661
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -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
View 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',
];

View File

@@ -14,6 +14,7 @@ return [
GeneralSettings::class,
SiteSettings::class,
HomeSettings::class,
\App\Settings\ContactSettings::class,
],
/*

View File

@@ -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('team_members', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('title');
$table->text('description');
$table->string('image'); // Store path to image
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('team_members');
}
};

View File

@@ -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('solutions', function (Blueprint $table) {
$table->json('downloads')->nullable()->after('bullets');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('solutions', function (Blueprint $table) {
$table->dropColumn('downloads');
});
}
};

View File

@@ -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('solutions', function (Blueprint $table) {
$table->json('faqs')->nullable()->after('downloads');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('solutions', function (Blueprint $table) {
$table->dropColumn('faqs');
});
}
};

View File

@@ -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('users', function (Blueprint $table) {
$table->string('role')->default('news_writer')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('role');
});
}
};

View File

@@ -2,7 +2,6 @@
namespace Database\Seeders;
use App\Models\News;
use Illuminate\Database\Seeder;
class NewsTableSeeder extends Seeder
@@ -10,8 +9,5 @@ class NewsTableSeeder extends Seeder
/**
* Run the database seeds.
*/
public function run(): void
{
}
public function run(): void {}
}

View File

@@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\User;
use App\Models\UserRole;
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
@@ -16,6 +17,7 @@ class UsersTableSeeder extends Seeder
'name' => 'nurmuhammet',
'email' => 'nurmuhammet@mail.com',
'password' => bcrypt('payload10'),
'role' => UserRole::ADMIN,
]);
}
}

View File

@@ -0,0 +1,17 @@
<?php
use Spatie\LaravelSettings\Migrations\SettingsMigration;
return new class extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('contact.contact_subtitle', 'Default Contact Subtitle');
$this->migrator->add('contact.contact_header', 'Default Contact Header');
$this->migrator->add('contact.contact_paragraph', 'This is a default paragraph for the contact page. Please update it from the Filament panel.');
$this->migrator->add('contact.email_address', 'info@example.com');
$this->migrator->add('contact.phone_number', '+1234567890');
$this->migrator->add('contact.location_address', '123 Main St, Anytown, USA');
$this->migrator->add('contact.map_embed_url', '');
}
};

View File

@@ -0,0 +1,82 @@
<?php
use Spatie\LaravelSettings\Migrations\SettingsMigration;
return new class extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('cms_aboutpage.our_story_title', 'Our Story');
$this->migrator->add('cms_aboutpage.our_story_subtitle', 'A journey of passion, innovation, and dedication that shaped who we are today.');
$this->migrator->add('cms_aboutpage.our_story_paragraph_one', 'Founded in 2015, our company began with a simple mission: to revolutionize how businesses approach their challenges. What started as a small team of three passionate individuals has grown into a global organization serving clients across multiple industries.');
$this->migrator->add('cms_aboutpage.our_story_paragraph_two', 'Through years of dedication and innovation, we\'ve established ourselves as industry leaders, known for our commitment to excellence and customer satisfaction.');
$this->migrator->add('cms_aboutpage.our_story_paragraph_three', 'Today, we\'re proud to have a diverse team of experts working together to deliver exceptional solutions that make a real difference for our clients.');
$this->migrator->add('cms_aboutpage.our_story_button_text', 'Learn more about our journey');
$this->migrator->add('cms_aboutpage.our_story_button_url', '#');
$this->migrator->add('cms_aboutpage.our_story_video_poster', 'placeholder.svg'); // Placeholder, change as needed
$this->migrator->add('cms_aboutpage.our_story_video_source', '#'); // Placeholder, change as needed
$this->migrator->add('cms_aboutpage.our_journey_title', 'Our Journey');
$this->migrator->add('cms_aboutpage.our_journey_subtitle', 'Explore our company\'s history and milestones through the years. Click on any date to learn more about our journey.');
$this->migrator->add('cms_aboutpage.our_journey_milestones', [
['year' => 2010, 'title' => 'Start Company', 'description' => 'Launching a new company is an exciting journey that requires careful planning and execution. Let\'s begin!', 'image' => 'portfolio/portfolio-2.jpg'],
['year' => 2014, 'title' => 'Opening Office', 'description' => 'Opening a new office represents growth and opportunity. Join us as we expand our operations!', 'image' => 'portfolio/portfolio-3.jpg'],
['year' => 2018, 'title' => 'Project Management', 'description' => 'Effective project management ensures timely delivery and quality results. Our expert team is here to help!', 'image' => 'portfolio/portfolio-5.jpg'],
['year' => 2021, 'title' => 'Open Research Team', 'description' => 'Our open research team is dedicated to innovation and collaboration, driving impactful solutions for clients.', 'image' => 'portfolio/portfolio-8.jpg'],
['year' => 2024, 'title' => 'Winning Award', 'description' => 'Winning awards showcases our commitment to excellence and innovation. Thank you for believing', 'image' => 'portfolio/portfolio-6.jpg'],
]);
$this->migrator->add('cms_aboutpage.company_structure_title', 'Company Structure');
$this->migrator->add('cms_aboutpage.company_structure_subtitle', 'Our organizational hierarchy designed for efficiency');
$this->migrator->add('cms_aboutpage.company_structure_director_name', 'John Smith');
$this->migrator->add('cms_aboutpage.company_structure_advisor_name', 'Sarah Johnson');
$this->migrator->add('cms_aboutpage.company_structure_departments', [
['name' => 'HSE', 'person' => 'Michael Brown'],
['name' => 'Personnel', 'person' => 'Emily Davis'],
['name' => 'Operations', 'person' => 'Robert Wilson'],
['name' => 'Finance', 'person' => 'Jennifer Lee'],
]);
$this->migrator->add('cms_aboutpage.our_management_title', 'Our Management');
$this->migrator->add('cms_aboutpage.our_management_subtitle', 'Meet the leadership team driving our vision forward');
$this->migrator->add('cms_aboutpage.our_management_team', [
['name' => 'John Smith', 'title' => 'Chief Executive Officer', 'description' => 'With over 20 years of industry experience, John leads our company with vision and strategic insight.', 'image' => 'placeholder.svg'],
['name' => 'Sarah Johnson', 'title' => 'Chief Technical Officer', 'description' => 'Sarah brings technical excellence and innovation to every aspect of our products and services.', 'image' => 'placeholder.svg'],
['name' => 'Michael Brown', 'title' => 'Head of Operations', 'description' => 'Michael ensures smooth operation across all our facilities and project deployments.', 'image' => 'placeholder.svg'],
]);
$this->migrator->add('cms_aboutpage.our_facilities_title', 'Our Facilities');
$this->migrator->add('cms_aboutpage.our_facilities_subtitle', 'State-of-the-art locations where innovation happens');
$this->migrator->add('cms_aboutpage.our_facilities_locations', [
['name' => 'Headquarters', 'location' => 'San Francisco, California', 'description' => 'Our global headquarters houses our executive team and primary R&D facilities with state-of-the-art equipment and collaborative spaces.', 'image' => 'placeholder.svg', 'tags' => ['R&D Labs', 'Executive Offices', 'Conference Center', 'Innovation Hub']],
['name' => 'Manufacturing Center', 'location' => 'Austin, Texas', 'description' => 'Our primary manufacturing facility implements cutting-edge production techniques with a focus on sustainability and efficiency.', 'image' => 'placeholder.svg', 'tags' => ['Production Lines', 'Quality Control', 'Warehouse', 'Distribution Center']],
]);
}
public function down(): void
{
$this->migrator->delete('cms_aboutpage.our_story_title');
$this->migrator->delete('cms_aboutpage.our_story_subtitle');
$this->migrator->delete('cms_aboutpage.our_story_paragraph_one');
$this->migrator->delete('cms_aboutpage.our_story_paragraph_two');
$this->migrator->delete('cms_aboutpage.our_story_paragraph_three');
$this->migrator->delete('cms_aboutpage.our_story_button_text');
$this->migrator->delete('cms_aboutpage.our_story_button_url');
$this->migrator->delete('cms_aboutpage.our_story_video_poster');
$this->migrator->delete('cms_aboutpage.our_story_video_source');
$this->migrator->delete('cms_aboutpage.our_journey_title');
$this->migrator->delete('cms_aboutpage.our_journey_subtitle');
$this->migrator->delete('cms_aboutpage.our_journey_milestones');
$this->migrator->delete('cms_aboutpage.company_structure_title');
$this->migrator->delete('cms_aboutpage.company_structure_subtitle');
$this->migrator->delete('cms_aboutpage.company_structure_director_name');
$this->migrator->delete('cms_aboutpage.company_structure_advisor_name');
$this->migrator->delete('cms_aboutpage.company_structure_departments');
$this->migrator->delete('cms_aboutpage.our_management_title');
$this->migrator->delete('cms_aboutpage.our_management_subtitle');
$this->migrator->delete('cms_aboutpage.our_management_team');
$this->migrator->delete('cms_aboutpage.our_facilities_title');
$this->migrator->delete('cms_aboutpage.our_facilities_subtitle');
$this->migrator->delete('cms_aboutpage.our_facilities_locations');
}
};

64
lang/en.json Normal file
View File

@@ -0,0 +1,64 @@
{
"Home": "Home",
"About Us": "About Us",
"Our solutions": "Our solutions",
"News & Stories": "News & Stories",
"News": "News",
"Success Stories": "Success Stories",
"Careers": "Careers",
"Career Opportunities": "Career Opportunities",
"Internships": "Internships",
"Contact": "Contact",
"Get Started": "Get Started",
"Apply for": "Apply for",
"Close": "Close",
"Name": "Name",
"Birthdate": "Birthdate",
"Email": "Email",
"Phone Number": "Phone Number",
"Resume (PDF, DOC, DOCX)": "Resume (PDF, DOC, DOCX)",
"Cover Letter (Optional)": "Cover Letter (Optional)",
"Submit Application": "Submit Application",
"Location": "Location",
"Salary": "Salary",
"Per monthly": "Per monthly",
"Error": "Error",
"An error occurred. Please try again.": "An error occurred. Please try again.",
"Gujurly Inžener logo": "Gujurly Inžener logo",
"Gujurly Inžener": "Gujurly Inžener",
"Address": "Address",
"Quick links": "Quick links",
"Support": "Support",
"Terms & Conditions": "Terms & Conditions",
"Privacy Policy": "Privacy Policy",
"|": "|",
"Mode": "Mode",
"Light": "Light",
"Dark": "Dark",
"Language": "Language",
"Read Our News": "Read Our News",
"Read More": "Read More",
"No news found...": "No news found...",
"Comments": "Comments",
"No comments yet": "No comments yet",
"Post Comment": "Post Comment",
"Required fields are marked": "Required fields are marked",
"Full Name": "Full Name",
"Title": "Title",
"Type your comments....": "Type your comments....",
"Submit Comment": "Submit Comment",
"Recent Blog": "Recent Blog",
"Phone": "Phone",
"Email Address": "Email Address",
"Location:": "Location:",
"Salary:": "Salary:",
"Description": "Description",
"Responsibilities and Qualifications": "Responsibilities and Qualifications",
"Apply for this Career": "Apply for this Career",
"For general application, send your resume at": "For general application, send your resume at",
"Apply Now": "Apply Now",
"No careers found...": "No careers found...",
"Search Here": "Search Here",
"Recent Success Stories": "Recent Success Stories",
"No internships found...": "No internships found..."
}

20
lang/en/auth.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'These credentials do not match our records.',
'password' => 'The provided password is incorrect.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
];

19
lang/en/pagination.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
];

22
lang/en/passwords.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| outcome such as failure due to an invalid password / reset token.
|
*/
'reset' => 'Your password has been reset.',
'sent' => 'We have emailed your password reset link.',
'throttled' => 'Please wait before retrying.',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that email address.",
];

198
lang/en/validation.php Normal file
View File

@@ -0,0 +1,198 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'The :attribute field must be accepted.',
'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
'active_url' => 'The :attribute field must be a valid URL.',
'after' => 'The :attribute field must be a date after :date.',
'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
'alpha' => 'The :attribute field must only contain letters.',
'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
'alpha_num' => 'The :attribute field must only contain letters and numbers.',
'any_of' => 'The :attribute field is invalid.',
'array' => 'The :attribute field must be an array.',
'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
'before' => 'The :attribute field must be a date before :date.',
'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
'between' => [
'array' => 'The :attribute field must have between :min and :max items.',
'file' => 'The :attribute field must be between :min and :max kilobytes.',
'numeric' => 'The :attribute field must be between :min and :max.',
'string' => 'The :attribute field must be between :min and :max characters.',
],
'boolean' => 'The :attribute field must be true or false.',
'can' => 'The :attribute field contains an unauthorized value.',
'confirmed' => 'The :attribute field confirmation does not match.',
'contains' => 'The :attribute field is missing a required value.',
'current_password' => 'The password is incorrect.',
'date' => 'The :attribute field must be a valid date.',
'date_equals' => 'The :attribute field must be a date equal to :date.',
'date_format' => 'The :attribute field must match the format :format.',
'decimal' => 'The :attribute field must have :decimal decimal places.',
'declined' => 'The :attribute field must be declined.',
'declined_if' => 'The :attribute field must be declined when :other is :value.',
'different' => 'The :attribute field and :other must be different.',
'digits' => 'The :attribute field must be :digits digits.',
'digits_between' => 'The :attribute field must be between :min and :max digits.',
'dimensions' => 'The :attribute field has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',
'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',
'email' => 'The :attribute field must be a valid email address.',
'ends_with' => 'The :attribute field must end with one of the following: :values.',
'enum' => 'The selected :attribute is invalid.',
'exists' => 'The selected :attribute is invalid.',
'extensions' => 'The :attribute field must have one of the following extensions: :values.',
'file' => 'The :attribute field must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'array' => 'The :attribute field must have more than :value items.',
'file' => 'The :attribute field must be greater than :value kilobytes.',
'numeric' => 'The :attribute field must be greater than :value.',
'string' => 'The :attribute field must be greater than :value characters.',
],
'gte' => [
'array' => 'The :attribute field must have :value items or more.',
'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',
'numeric' => 'The :attribute field must be greater than or equal to :value.',
'string' => 'The :attribute field must be greater than or equal to :value characters.',
],
'hex_color' => 'The :attribute field must be a valid hexadecimal color.',
'image' => 'The :attribute field must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field must exist in :other.',
'in_array_keys' => 'The :attribute field must contain at least one of the following keys: :values.',
'integer' => 'The :attribute field must be an integer.',
'ip' => 'The :attribute field must be a valid IP address.',
'ipv4' => 'The :attribute field must be a valid IPv4 address.',
'ipv6' => 'The :attribute field must be a valid IPv6 address.',
'json' => 'The :attribute field must be a valid JSON string.',
'list' => 'The :attribute field must be a list.',
'lowercase' => 'The :attribute field must be lowercase.',
'lt' => [
'array' => 'The :attribute field must have less than :value items.',
'file' => 'The :attribute field must be less than :value kilobytes.',
'numeric' => 'The :attribute field must be less than :value.',
'string' => 'The :attribute field must be less than :value characters.',
],
'lte' => [
'array' => 'The :attribute field must not have more than :value items.',
'file' => 'The :attribute field must be less than or equal to :value kilobytes.',
'numeric' => 'The :attribute field must be less than or equal to :value.',
'string' => 'The :attribute field must be less than or equal to :value characters.',
],
'mac_address' => 'The :attribute field must be a valid MAC address.',
'max' => [
'array' => 'The :attribute field must not have more than :max items.',
'file' => 'The :attribute field must not be greater than :max kilobytes.',
'numeric' => 'The :attribute field must not be greater than :max.',
'string' => 'The :attribute field must not be greater than :max characters.',
],
'max_digits' => 'The :attribute field must not have more than :max digits.',
'mimes' => 'The :attribute field must be a file of type: :values.',
'mimetypes' => 'The :attribute field must be a file of type: :values.',
'min' => [
'array' => 'The :attribute field must have at least :min items.',
'file' => 'The :attribute field must be at least :min kilobytes.',
'numeric' => 'The :attribute field must be at least :min.',
'string' => 'The :attribute field must be at least :min characters.',
],
'min_digits' => 'The :attribute field must have at least :min digits.',
'missing' => 'The :attribute field must be missing.',
'missing_if' => 'The :attribute field must be missing when :other is :value.',
'missing_unless' => 'The :attribute field must be missing unless :other is :value.',
'missing_with' => 'The :attribute field must be missing when :values is present.',
'missing_with_all' => 'The :attribute field must be missing when :values are present.',
'multiple_of' => 'The :attribute field must be a multiple of :value.',
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute field format is invalid.',
'numeric' => 'The :attribute field must be a number.',
'password' => [
'letters' => 'The :attribute field must contain at least one letter.',
'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',
'numbers' => 'The :attribute field must contain at least one number.',
'symbols' => 'The :attribute field must contain at least one symbol.',
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
],
'present' => 'The :attribute field must be present.',
'present_if' => 'The :attribute field must be present when :other is :value.',
'present_unless' => 'The :attribute field must be present unless :other is :value.',
'present_with' => 'The :attribute field must be present when :values is present.',
'present_with_all' => 'The :attribute field must be present when :values are present.',
'prohibited' => 'The :attribute field is prohibited.',
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
'prohibited_if_accepted' => 'The :attribute field is prohibited when :other is accepted.',
'prohibited_if_declined' => 'The :attribute field is prohibited when :other is declined.',
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
'prohibits' => 'The :attribute field prohibits :other from being present.',
'regex' => 'The :attribute field format is invalid.',
'required' => 'The :attribute field is required.',
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
'required_if_declined' => 'The :attribute field is required when :other is declined.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute field must match :other.',
'size' => [
'array' => 'The :attribute field must contain :size items.',
'file' => 'The :attribute field must be :size kilobytes.',
'numeric' => 'The :attribute field must be :size.',
'string' => 'The :attribute field must be :size characters.',
],
'starts_with' => 'The :attribute field must start with one of the following: :values.',
'string' => 'The :attribute field must be a string.',
'timezone' => 'The :attribute field must be a valid timezone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'uppercase' => 'The :attribute field must be uppercase.',
'url' => 'The :attribute field must be a valid URL.',
'ulid' => 'The :attribute field must be a valid ULID.',
'uuid' => 'The :attribute field must be a valid UUID.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];

64
lang/ru.json Normal file
View File

@@ -0,0 +1,64 @@
{
"Home": "Главная",
"About Us": "О нас",
"Our solutions": "Наши решения",
"News & Stories": "Новости и Истории",
"News": "Новости",
"Success Stories": "Истории успеха",
"Careers": "Карьера",
"Career Opportunities": "Карьерные возможности",
"Internships": "Стажировки",
"Contact": "Контакты",
"Get Started": "Начать",
"Apply for": "Подать заявку на",
"Close": "Закрыть",
"Name": "Имя",
"Birthdate": "Дата рождения",
"Email": "Электронная почта",
"Phone Number": "Номер телефона",
"Resume (PDF, DOC, DOCX)": "Резюме (PDF, DOC, DOCX)",
"Cover Letter (Optional)": "Сопроводительное письмо (необязательно)",
"Submit Application": "Отправить заявку",
"Location": "Местоположение",
"Salary": "Зарплата",
"Per monthly": "В месяц",
"Error": "Ошибка",
"An error occurred. Please try again.": "Произошла ошибка. Пожалуйста, попробуйте еще раз.",
"Gujurly Inžener logo": "Логотип Gujurly Inžener",
"Gujurly Inžener": "Gujurly Inžener",
"Address": "Адрес",
"Quick links": "Быстрые ссылки",
"Support": "Поддержка",
"Terms & Conditions": "Условия и положения",
"Privacy Policy": "Политика конфиденциальности",
"|": "|",
"Mode": "Режим",
"Light": "Светлый",
"Dark": "Темный",
"Language": "Язык",
"Read Our News": "Читайте наши новости",
"Read More": "Читать далее",
"No news found...": "Новости не найдены...",
"Comments": "Комментарии",
"No comments yet": "Пока нет комментариев",
"Post Comment": "Оставить комментарий",
"Required fields are marked": "Обязательные поля помечены",
"Full Name": "Полное имя",
"Title": "Заголовок",
"Type your comments....": "Напишите свои комментарии....",
"Submit Comment": "Отправить комментарий",
"Recent Blog": "Недавний блог",
"Phone": "Телефон",
"Email Address": "Адрес электронной почты",
"Location:": "Местоположение:",
"Salary:": "Зарплата:",
"Description": "Описание",
"Responsibilities and Qualifications": "Обязанности и квалификация",
"Apply for this Career": "Подать заявку на эту карьеру",
"For general application, send your resume at": "Для общего заявления отправьте свое резюме по адресу",
"Apply Now": "Подать сейчас",
"No careers found...": "Вакансии не найдены...",
"Search Here": "Искать здесь",
"Recent Success Stories": "Недавние истории успеха",
"No internships found...": "Стажировки не найдены..."
}

64
lang/tk.json Normal file
View File

@@ -0,0 +1,64 @@
{
"Home": "Baş sahypa",
"About Us": "Biz barada",
"Our solutions": "Biziň çözgütlerimiz",
"News & Stories": "Täzelikler we Hekaýalar",
"News": "Täzelikler",
"Success Stories": "Üstünlik hekaýalary",
"Careers": "Kariýera",
"Career Opportunities": "Kariýera mümkinçilikleri",
"Internships": "Hünär öwrenmek",
"Contact": "Habarlaşmak",
"Get Started": "Başlamak",
"Apply for": "Üçin ýüz tutmak",
"Close": "Ýapmak",
"Name": "Ady",
"Birthdate": "Doglan senesi",
"Email": "Elektron poçta",
"Phone Number": "Telefon belgisi",
"Resume (PDF, DOC, DOCX)": "Rezüme (PDF, DOC, DOCX)",
"Cover Letter (Optional)": "Goşmaça hat (islege görä)",
"Submit Application": "Arza ibermek",
"Location": "Ýerleşýän ýeri",
"Salary": "Aýlyk",
"Per monthly": "Aýda",
"Error": "Ýalňyşlyk",
"An error occurred. Please try again.": "Ýalňyşlyk ýüze çykdy. Haýyş edýäris, täzeden synanyşyň.",
"Gujurly Inžener logo": "Gujurly Inžener nyşany",
"Gujurly Inžener": "Gujurly Inžener",
"Address": "Salgy",
"Quick links": "Çalt baglanyşyklar",
"Support": "Goldaw",
"Terms & Conditions": "Şertler we Düzgünler",
"Privacy Policy": "Gizlinlik syýasaty",
"|": "|",
"Mode": "Režim",
"Light": "Ýagty",
"Dark": "Garaňky",
"Language": "Dil",
"Read Our News": "Täzeliklerimizi okaň",
"Read More": "Doly okaň",
"No news found...": "Täzelik tapylmady...",
"Comments": "Teswirler",
"No comments yet": "Heniz teswir ýok",
"Post Comment": "Teswir goýmak",
"Required fields are marked": "Zerur meýdanlar bellendi",
"Full Name": "Doly ady",
"Title": "Ady",
"Type your comments....": "Teswirleriňizi ýazyň....",
"Submit Comment": "Teswir ibermek",
"Recent Blog": "Soňky blog",
"Phone": "Telefon",
"Email Address": "Elektron poçta salgysy",
"Location:": "Ýerleşýän ýeri:",
"Salary:": "Aýlyk:",
"Description": "Beýany",
"Responsibilities and Qualifications": "Jogapkärçilikler we Hünärler",
"Apply for this Career": "Bu kariýera ýüz tutuň",
"For general application, send your resume at": "Umumy arza üçin rezyumeňizi şu salga iberiň",
"Apply Now": "Häzir ýüz tutuň",
"No careers found...": "Kariýera tapylmady...",
"Search Here": "Şu ýerde gözle",
"Recent Success Stories": "Soňky üstünlik hekaýalary",
"No internships found...": "Hünär öwrenmek tapylmady..."
}

View File

@@ -4373,7 +4373,7 @@ p {
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--color-1);
color: var(--text-white);
border-radius: 50%;
margin-right: -40px;
font-size: 20px;

View File

@@ -492,6 +492,15 @@
}
});
// Language Switcher
$('#language-switcher button').on('click', function (e) {
$(this).addClass('active').siblings().removeClass('active');
var lang = $(this).attr('data-lang');
var currentUrl = new URL(window.location.href);
currentUrl.searchParams.set('lang', lang);
window.location.href = currentUrl.toString();
});
///============= * Custom Cursor =============\\\
var ball = document.getElementById("cursor-ball");
var cursorText = document.getElementById("cursor-text");

View File

@@ -6,6 +6,8 @@
padding: 40px;
border: 1px solid var(--border-color-2);
border-radius: 10px;
display: flex;
flex-direction: column;
&-price {
span {
font-size: 18px;
@@ -25,6 +27,7 @@
margin-top: 35px;
padding-top: 30px;
border-top: 1px solid var(--border-color-2);
flex-grow: 1;
ul {
padding: 0;
margin: 0;

View File

@@ -2,8 +2,8 @@
<div class="modal-dialog modal-lg">
<div class="modal-content rounded-3">
<div class="modal-header">
<h5 class="modal-title" id="applicationModalLabel">Apply for <span id="jobTitle"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<h5 class="modal-title" id="applicationModalLabel">{{ __('Apply for') }} <span id="jobTitle"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{ __('Close') }}"></button>
</div>
<div class="modal-body">
<h6 id="jobLocation"></h6>
@@ -18,33 +18,33 @@
@endif
<div class="row">
<div class="col-md-6 mb-3">
<label for="name" class="form-label">Name <span> *</span></label>
<label for="name" class="form-label">{{ __('Name') }} <span> *</span></label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="col-md-6 mb-3">
<label for="birthdate" class="form-label">Birthdate <span> *</span></label>
<label for="birthdate" class="form-label">{{ __('Birthdate') }} <span> *</span></label>
<input type="date" class="form-control" id="birthdate" name="birthdate" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="email" class="form-label">Email <span> *</span></label>
<label for="email" class="form-label">{{ __('Email') }} <span> *</span></label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="col-md-6 mb-3">
<label for="phone_number" class="form-label">Phone Number <span> *</span></label>
<label for="phone_number" class="form-label">{{ __('Phone Number') }} <span> *</span></label>
<input type="text" class="form-control" id="phone_number" name="phone_number" required>
</div>
</div>
<div class="mb-3">
<label for="resume_file" class="form-label">Resume (PDF, DOC, DOCX) <span> *</span></label>
<label for="resume_file" class="form-label">{{ __('Resume (PDF, DOC, DOCX)') }} <span> *</span></label>
<input type="file" class="form-control" id="resume_file" name="resume_file" accept=".pdf,.doc,.docx" required>
</div>
<div class="mb-3">
<label for="cover_letter" class="form-label">Cover Letter (Optional)</label>
<label for="cover_letter" class="form-label">{{ __('Cover Letter (Optional)') }}</label>
<textarea class="form-control" id="cover_letter" name="cover_letter" rows="5"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit Application</button>
<button type="submit" class="btn btn-primary">{{ __('Submit Application') }}</button>
</form>
</div>
</div>
@@ -70,8 +70,8 @@
// Set dynamic values
modalTitle.textContent = button.getAttribute('data-' + jobType + '-title');
modalLocation.textContent = 'Location: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = 'Salary: ' + button.getAttribute('data-' + jobType + '-salary') + ' / Per monthly';
modalLocation.textContent = '{{ __('Location') }}: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = '{{ __('Salary') }}: ' + button.getAttribute('data-' + jobType + '-salary') + ' / {{ __('Per monthly') }}';
modalDescription.textContent = button.getAttribute('data-' + jobType + '-description');
jobIdInput.value = jobId;
@@ -108,12 +108,12 @@
modal.hide();
form.reset();
} else {
alert('Error: ' + data.message);
alert('{{ __('Error') }}: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred. Please try again.');
console.error('{{ __('Error') }}:', error);
alert('{{ __('An error occurred. Please try again.') }}');
});
});
}

View File

@@ -5,7 +5,7 @@
@include('web.layouts.meta-tags')
<!-- Title of Site -->
<title>@isset($title) {{ "{$title} |" }} @endisset {{ $settings->name }}</title>
<title>@isset($title) {{ "{$title} " . __('|') . " " }} @endisset {{ $settings->name }}</title>
<!-- Favicons -->
@include('web.layouts.favicons')

View File

@@ -8,8 +8,8 @@
<div class="col-lg-4 col-sm-6">
<div class="footer__four-widget mr-40">
<a href="/" class="logo align-items-center d-flex gap-2">
<img src="/web/assets/img/logo-small.png" style="height: 35px;" alt="Gujurly Inžener logo">
<span style="font-size: 2em;color: var(--text-heading-color);">Gujurly Inžener</span>
<img src="/web/assets/img/logo-small.png" style="height: 35px;" alt="{{ __('Gujurly Inžener logo') }}">
<span style="font-size: 2em;color: var(--text-heading-color);">{{ __('Gujurly Inžener') }}</span>
</a>
<h5>{{ $settings->footer_company_header }}</h5>
</div>
@@ -32,7 +32,7 @@
<li><a href="{{ route('about-us.index') }}">{{ __('About Us') }}</a></li>
<li><a href="{{ route('our-solutions.index') }}">{{ __('Our solutions') }}</a></li>
<li><a href="{{ route('career.index') }}">{{ __('Career Opportunities') }}</a></li>
<li><a href="{{ route('success.index') }}">{{ __('Success stories') }}</a></li>
<li><a href="{{ route('success.index') }}">{{ __('Success Stories') }}</a></li>
</ul>
</div>
</div>
@@ -43,7 +43,7 @@
<div class="footer-widget-menu">
<ul>
<li><a href="{{ route('terms') }}">{{ __('Terms & Conditions') }}</a></li>
<li><a href="{{ route('privacy') }}">{{ __('Privacy policy') }}</a></li>
<li><a href="{{ route('privacy') }}">{{ __('Privacy Policy') }}</a></li>
</ul>
</div>
</div>

View File

@@ -8,8 +8,16 @@
<div class="switch__tab-area-item">
<h5>{{ __('Mode') }}</h5>
<div class="switch__tab-area-item-button type-dark-mode">
<button class="active" data-mode="light">{{ __('light') }}</button>
<button data-mode="dark-mode">{{ __('dark') }}</button>
<button class="active" data-mode="light">{{ __('Light') }}</button>
<button data-mode="dark-mode">{{ __('Dark') }}</button>
</div>
</div>
<div class="switch__tab-area-item">
<h5>{{ __('Language') }}</h5>
<div class="switch__tab-area-item-button type-language" id="language-switcher">
<button class="{{ app()->getLocale() == 'en' ? 'active' : '' }}" data-lang="en">EN</button>
<button class="{{ app()->getLocale() == 'ru' ? 'active' : '' }}" data-lang="ru">RU</button>
<button class="{{ app()->getLocale() == 'tk' ? 'active' : '' }}" data-lang="tk">TK</button>
</div>
</div>
</div>

View File

@@ -285,21 +285,20 @@ body {
</style>
@endpush
@push('footer-js')
<script src="/web/cs/js/timeline.js"></script>
@endpush
@section('content')
@php
$aboutSettings = app(App\Settings\AboutSettings::class);
@endphp
<!-- Breadcrumb Area Start -->
<div class="breadcrumb__area" style="background-image: url('/web/assets/img/page/breadcrumb.jpg');">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>About Us</h2>
<h2>{{ __('About Us') }}</h2>
<ul>
<li><a href="index.html">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>About Us</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('About Us') }}</li>
</ul>
</div>
</div>
@@ -314,19 +313,18 @@ body {
<div class="container px-4 md:px-6 mx-auto">
<section class="mb-24">
<div class="text-center max-w-3xl mx-auto mb-10">
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">Our Story</h2>
<p class="text-lg text-gray-600 md:text-xl">A journey of passion, innovation, and dedication that shaped who we are today.</p>
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">{{ $aboutSettings->our_story_title }}</h2>
<p class="text-lg text-gray-600 md:text-xl">{{ $aboutSettings->our_story_subtitle }}</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-10 items-center">
<div class="order-2 lg:order-1">
<p class="text-gray-700 mb-4">
Founded in 2015, our company began with a simple mission: to revolutionize how businesses approach their challenges. What started as a small team of three passionate individuals has grown into a global
organization serving clients across multiple industries.
{{ $aboutSettings->our_story_paragraph_one }}
</p>
<p class="text-gray-700 mb-4">Through years of dedication and innovation, we've established ourselves as industry leaders, known for our commitment to excellence and customer satisfaction.</p>
<p class="text-gray-700 mb-6">Today, we're proud to have a diverse team of experts working together to deliver exceptional solutions that make a real difference for our clients.</p>
<p class="text-gray-700 mb-4">{{ $aboutSettings->our_story_paragraph_two }}</p>
<p class="text-gray-700 mb-6">{{ $aboutSettings->our_story_paragraph_three }}</p>
<button class="flex items-center text-sm font-medium text-teal-600 hover:text-teal-800 transition-colors">
Learn more about our journey
<a href="{{ $aboutSettings->our_story_button_url }}">{{ $aboutSettings->our_story_button_text }}</a>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -345,9 +343,9 @@ body {
</div>
<div class="order-1 lg:order-2 bg-white rounded-xl shadow-lg overflow-hidden">
<div class="aspect-video relative">
<video class="w-full h-full object-cover" controls="" poster="/placeholder.svg?height=720&amp;width=1280">
<source type="video/mp4" src="#" />
Your browser does not support the video tag.
<video class="w-full h-full object-cover" controls="" poster="{{ asset('storage/' . $aboutSettings->our_story_video_poster) }}">
<source type="video/mp4" src="{{ asset('storage/' . $aboutSettings->our_story_video_source) }}" />
{{ __('Your browser does not support the video tag.') }}
</video>
</div>
</div>
@@ -355,60 +353,58 @@ body {
<div class="container">
<section class="header">
<h1>Our Journey</h1>
<p>Explore our company's history and milestones through the years. Click on any date to learn more about our journey.</p>
<h1>{{ $aboutSettings->our_journey_title }}</h1>
<p>{{ $aboutSettings->our_journey_subtitle }}</p>
</section>
<div class="timeline-container">
<!-- Timeline dates will be generated here -->
<div class="timeline-dates">
<div class="timeline-line"></div>
<div id="dates-container" class="dates-container"></div>
</div>
<!-- Content area -->
<div class="content-area">
<div id="content-container" class="content-container">
<!-- Content will be inserted here -->
<!-- Our History Area Start -->
<div class="history__area">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="company__history-area">
@foreach ($aboutSettings->our_journey_milestones as $milestone)
<div class="company__history-area-item">
<div class="company__history-area-item-date">
<span>{{ $milestone['year'] }}</span>
</div>
<!-- Navigation buttons -->
<div class="navigation-controls">
<button id="prev-btn" class="nav-button" aria-label="Previous milestone">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="m15 18-6-6 6-6"/>
</svg>
<span class="sr-only">Previous</span>
</button>
<button id="next-btn" class="nav-button" aria-label="Next milestone">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
<path d="m9 18 6-6-6-6"/>
</svg>
<span class="sr-only">Next</span>
</button>
<div class="company__history-area-item-inner wow fadeInUp" data-wow-delay=".4s">
<div class="company__history-area-item-inner-image">
<img src="{{ asset('storage/' . $milestone['image']) }}" alt="{{ $milestone['title'] }}">
</div>
<div class="company__history-area-item-inner-content">
<h4>{{ $milestone['title'] }}</h4>
<p>{{ $milestone['description'] }}</p>
</div>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
<!-- Our History Area End -->
</div>
</section>
<section class="mb-24">
<div class="text-center max-w-3xl mx-auto mb-12">
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">Company Structure</h2>
<p class="text-lg text-gray-600">Our organizational hierarchy designed for efficiency</p>
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">{{ $aboutSettings->company_structure_title }}</h2>
<p class="text-lg text-gray-600">{{ $aboutSettings->company_structure_subtitle }}</p>
</div>
<div class="bg-white rounded-xl shadow-lg p-8 md:p-10">
<div class="org-chart">
<div class="flex justify-center mb-16">
<div class="org-box org-box-director">
<h3 class="font-bold text-lg">Director</h3>
<p class="text-sm text-gray-500">John Smith</p>
<h3 class="font-bold text-lg">{{ __('Director') }}</h3>
<p class="text-sm text-gray-500">{{ $aboutSettings->company_structure_director_name }}</p>
</div>
</div>
<div class="flex justify-center mb-16 relative">
<div class="absolute top-[-60px] w-px h-[60px] bg-gray-300"></div>
<div class="org-box org-box-advisor">
<h3 class="font-bold text-lg">Technical Advisor</h3>
<p class="text-sm text-gray-500">Sarah Johnson</p>
<h3 class="font-bold text-lg">{{ __('Technical Advisor') }}</h3>
<p class="text-sm text-gray-500">{{ $aboutSettings->company_structure_advisor_name }}</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 relative">
@@ -418,111 +414,87 @@ body {
<div class="absolute top-[-30px] left-[35%] w-px h-[30px] bg-gray-300"></div>
<div class="absolute top-[-30px] left-[65%] w-px h-[30px] bg-gray-300"></div>
<div class="absolute top-[-30px] left-[90%] w-px h-[30px] bg-gray-300"></div>
<div class="org-box org-box-department">
<h3 class="font-bold">HSE</h3>
<p class="text-sm text-gray-500">Michael Brown</p>
</div>
<div class="org-box org-box-department">
<h3 class="font-bold">Personnel</h3>
<p class="text-sm text-gray-500">Emily Davis</p>
</div>
<div class="org-box org-box-department">
<h3 class="font-bold">Operations</h3>
<p class="text-sm text-gray-500">Robert Wilson</p>
</div>
<div class="org-box org-box-department">
<h3 class="font-bold">Finance</h3>
<p class="text-sm text-gray-500">Jennifer Lee</p>
</div>
@foreach ($aboutSettings->company_structure_departments as $department)
<div class="org-box org-box-department">
<h3 class="font-bold">{{ $department['name'] }}</h3>
<p class="text-sm text-gray-500">{{ $department['person'] }}</p>
</div>
@endforeach
</div>
</div>
</div>
</section>
<section class="mb-24">
<div class="text-center max-w-3xl mx-auto mb-12">
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">Our Management</h2>
<p class="text-lg text-gray-600">Meet the leadership team driving our vision forward</p>
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">{{ __('Our Management') }}</h2>
<p class="text-lg text-gray-600">{{ __('Meet the leadership team driving our vision forward') }}</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-56 w-full">
<img
alt="John Smith"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="/placeholder.svg?height=600&amp;width=600"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
@foreach (App\Models\TeamMember::all() as $member)
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-56 w-full">
<img
alt="{{ $member->name }}"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="{{ asset('storage/' . $member->image) }}"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<h3 class="text-xl font-bold">{{ $member->name }}</h3>
<p class="text-teal-600 text-sm font-medium mb-3">{{ $member->title }}</p>
<p class="text-gray-600 text-sm mb-4">{{ $member->description }}</p>
</div>
</div>
<div class="p-6">
<h3 class="text-xl font-bold">John Smith</h3>
<p class="text-teal-600 text-sm font-medium mb-3">Chief Executive Officer</p>
<p class="text-gray-600 text-sm mb-4">With over 20 years of industry experience, John leads our company with vision and strategic insight.</p>
</div>
</div>
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-56 w-full">
<img
alt="Sarah Johnson"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="/placeholder.svg?height=600&amp;width=600"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<h3 class="text-xl font-bold">Sarah Johnson</h3>
<p class="text-teal-600 text-sm font-medium mb-3">Chief Technical Officer</p>
<p class="text-gray-600 text-sm mb-4">Sarah brings technical excellence and innovation to every aspect of our products and services.</p>
</div>
</div>
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-56 w-full">
<img
alt="Michael Brown"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="/placeholder.svg?height=600&amp;width=600"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<h3 class="text-xl font-bold">Michael Brown</h3>
<p class="text-teal-600 text-sm font-medium mb-3">Head of Operations</p>
<p class="text-gray-600 text-sm mb-4">Michael ensures smooth operation across all our facilities and project deployments.</p>
</div>
</div>
@endforeach
</div>
</section>
<section>
<div class="text-center max-w-3xl mx-auto mb-12">
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">Our Facilities</h2>
<p class="text-lg text-gray-600">State-of-the-art locations where innovation happens</p>
<h2 class="text-3xl md:text-4xl font-bold tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-500 to-purple-600">{{ $aboutSettings->our_facilities_title }}</h2>
<p class="text-lg text-gray-600">{{ $aboutSettings->our_facilities_subtitle }}</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-64 w-full">
<img
alt="Headquarters"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="/placeholder.svg?height=800&amp;width=1200"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<div class="flex justify-between items-start">
<div>
<h3 class="text-xl font-bold mb-2">Headquarters</h3>
<div class="flex items-center text-gray-600 mb-4">
@foreach ($aboutSettings->our_facilities_locations as $location)
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-64 w-full">
<img
alt="{{ $location['name'] }}"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="{{ asset('storage/' . $location['image']) }}"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<div class="flex justify-between items-start">
<div>
<h3 class="text-xl font-bold mb-2">{{ $location['name'] }}</h3>
<div class="flex items-center text-gray-600 mb-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-map-pin h-4 w-4 mr-1"
>
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path>
<circle cx="12" cy="10" r="3"></circle>
</svg>
<span class="text-sm">{{ $location['location'] }}</span>
</div>
</div>
<div class="bg-teal-50 p-2 rounded-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -533,117 +505,31 @@ body {
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-map-pin h-4 w-4 mr-1"
class="lucide lucide-building h-6 w-6 text-teal-600"
>
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path>
<circle cx="12" cy="10" r="3"></circle>
<rect width="16" height="20" x="4" y="2" rx="2" ry="2"></rect>
<path d="M9 22v-4h6v4"></path>
<path d="M8 6h.01"></path>
<path d="M16 6h.01"></path>
<path d="M12 6h.01"></path>
<path d="M12 10h.01"></path>
<path d="M12 14h.01"></path>
<path d="M16 10h.01"></path>
<path d="M16 14h.01"></path>
<path d="M8 10h.01"></path>
<path d="M8 14h.01"></path>
</svg>
<span class="text-sm">San Francisco, California</span>
</div>
</div>
<div class="bg-teal-50 p-2 rounded-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-building h-6 w-6 text-teal-600"
>
<rect width="16" height="20" x="4" y="2" rx="2" ry="2"></rect>
<path d="M9 22v-4h6v4"></path>
<path d="M8 6h.01"></path>
<path d="M16 6h.01"></path>
<path d="M12 6h.01"></path>
<path d="M12 10h.01"></path>
<path d="M12 14h.01"></path>
<path d="M16 10h.01"></path>
<path d="M16 14h.01"></path>
<path d="M8 10h.01"></path>
<path d="M8 14h.01"></path>
</svg>
<p class="text-gray-600 mb-4">{{ $location['description'] }}</p>
<div class="flex flex-wrap gap-2">
@foreach ($location['tags'] as $tag)
<span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">{{ $tag }}</span>
@endforeach
</div>
</div>
<p class="text-gray-600 mb-4">Our global headquarters houses our executive team and primary R&amp;D facilities with state-of-the-art equipment and collaborative spaces.</p>
<div class="flex flex-wrap gap-2">
<span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">R&amp;D Labs</span><span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Executive Offices</span>
<span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Conference Center</span><span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Innovation Hub</span>
</div>
</div>
</div>
<div class="bg-white rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 overflow-hidden">
<div class="relative h-64 w-full">
<img
alt="Manufacturing Center"
loading="lazy"
decoding="async"
data-nimg="fill"
class="object-cover"
src="/placeholder.svg?height=800&amp;width=1200"
style="position: absolute; height: 100%; width: 100%; inset: 0px; color: transparent;"
/>
</div>
<div class="p-6">
<div class="flex justify-between items-start">
<div>
<h3 class="text-xl font-bold mb-2">Manufacturing Center</h3>
<div class="flex items-center text-gray-600 mb-4">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-map-pin h-4 w-4 mr-1"
>
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path>
<circle cx="12" cy="10" r="3"></circle>
</svg>
<span class="text-sm">Austin, Texas</span>
</div>
</div>
<div class="bg-teal-50 p-2 rounded-lg">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-building h-6 w-6 text-teal-600"
>
<rect width="16" height="20" x="4" y="2" rx="2" ry="2"></rect>
<path d="M9 22v-4h6v4"></path>
<path d="M8 6h.01"></path>
<path d="M16 6h.01"></path>
<path d="M12 6h.01"></path>
<path d="M12 10h.01"></path>
<path d="M12 14h.01"></path>
<path d="M16 10h.01"></path>
<path d="M16 14h.01"></path>
<path d="M8 10h.01"></path>
<path d="M8 14h.01"></path>
</svg>
</div>
</div>
<p class="text-gray-600 mb-4">Our primary manufacturing facility implements cutting-edge production techniques with a focus on sustainability and efficiency.</p>
<div class="flex flex-wrap gap-2">
<span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Production Lines</span><span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Quality Control</span>
<span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Warehouse</span><span class="bg-gray-100 text-gray-700 text-xs px-2 py-1 rounded-full">Distribution Center</span>
</div>
</div>
</div>
@endforeach
</div>
</section>
</div>
@@ -651,203 +537,4 @@ body {
</div>
</div>
<!-- Mission Area Start -->
<div class="mission__area section-padding">
<div class="container">
<div class="row">
<div class="col-lg-6 lg-mb-25">
<div class="mission__area-left mr-40 xl-mr-0">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">Our Mission</span>
<h2 class="title_split_anim">Dedicated to Delivering Value and Excellence</h2>
</div>
</div>
<div class="col-lg-6">
<div class="mission__area-right">
<div class="row">
<div class="col-md-6 md-mb-25 wow fadeInUp" data-wow-delay=".6s">
<div class="experience__area-list-item">
<i class="flaticon-team"></i>
<div class="experience__area-list-item-content">
<h4>Project Planning</h4>
<p>Ensuring every detail is considered designing</p>
</div>
</div>
</div>
<div class="col-md-6 wow fadeInUp" data-wow-delay=".9s">
<div class="experience__area-list-item">
<i class="flaticon-technology"></i>
<div class="experience__area-list-item-content">
<h4>Labor Preparation</h4>
<p>We take pride in our quality craftsmanship</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Mission Area End -->
<!-- About Area Start -->
<div class="about__five section-padding pt-0">
<div class="container">
<div class="row al-center">
<div class="col-lg-5 lg-mb-25">
<div class="about__five-image wow img_left_animation">
<img src="/web/assets/img/about/about-4.jpg" alt="image">
</div>
</div>
<div class="col-lg-7">
<div class="about__five-right ml-70 xl-ml-0">
<div class="about__five-right-title">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">About Our Company</span>
<h2 class="title_split_anim">Trusted Partner in Construction and Design</h2>
</div>
<div class="features wow fadeInUp" data-wow-delay=".3s" style="background-image: url('/web/assets/img/portfolio/portfolio-8.jpg');">
<h3>Building Trust<br>Since 1989</h3>
</div>
<p class="wow fadeInUp" data-wow-delay=".6s">Our journey began with a commitment to excellence, and that commitment remains at the core of our operations today. Weve grown from a small local business into a trusted partner for both residential and commercial.</p>
<div class="item_bounce">
<a class="build_button mt-20" href="portfolio.html">See Projects<i class="flaticon-right-up"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- About Area End -->
<!-- Video Area Start -->
<div class="video__two" style="background-image: url('/web/assets/img/service/services-1.jpg');">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="video__two-icon item_bounce">
<div class="video video-pulse">
<a class="video-popup" href="https://youtube.com/watch?v=0WC-tD-njcA"><i class="fas fa-play"></i></a>
</div>
</div>
</div>
</div>
</div>
<div class="scroll__slider">
<div class="text-slide">
<div class="sliders text_scroll">
<ul>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Residential</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Architecture</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Community</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Healthcare</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Seaside Resort</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Modern</a></li>
</ul>
</div>
<div class="sliders text_scroll">
<ul>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Residential</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Architecture</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Community</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Healthcare</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Seaside Resort</a></li>
<li><img src="/web/assets/img/icon/star-dark.svg" alt="icon"><a href="portfolio-details">Modern</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- Video Area End -->
<!-- Certification Area Start -->
<div class="certification section-padding pt-0">
<div class="container">
<div class="row">
<div class="col-xl-4 col-lg-5 lg-mb-25">
<div class="certification-left section-padding pb-0">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">Industry Certifications</span>
<h2 class="title_split_anim">Our Key Achievements Over the Years</h2>
</div>
</div>
<div class="col-xl-8 col-lg-7">
<div class="certification-right">
<img class="wow img_top_animation" src="/web/assets/img/page/who-we-are.jpg" alt="image">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="counter__one-area mt-80">
<div class="certification-right-counter">
<h2><span class="counter">678</span>+</h2>
<span>Complete Projects</span>
</div>
<div class="certification-right-counter">
<h2><span class="counter">120</span>+</h2>
<span>Team Members</span>
</div>
<div class="certification-right-counter">
<h2><span class="counter">635</span>+</h2>
<span>Client Reviews</span>
</div>
<div class="certification-right-counter">
<h2><span class="counter">89</span>+</h2>
<span>Winning Awards</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Certification Area End -->
<!-- Team Area Start -->
<div class="team__area section-padding">
<div class="container">
<div class="row mb-35">
<div class="col-xl-12">
<div class="team__area-title t-center">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">Meet Our Experts</span>
<h2 class="title_split_anim">Dedicated Professionals</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-6 wow fadeInUp mt-25" data-wow-delay=".3s">
<div class="team__area-item">
<img class="img_full" src="/web/assets/img/team/team-1.jpg" alt="image">
<div class="team__area-item-content t-center pt-20">
<h5>Alan Dosan</h5>
<span>Lead Architect</span>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 wow fadeInUp mt-25" data-wow-delay=".6s">
<div class="team__area-item">
<img class="img_full" src="/web/assets/img/team/team-2.jpg" alt="image">
<div class="team__area-item-content t-center pt-20">
<h5>Sarah Johnson</h5>
<span>General Laborer</span>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 wow fadeInUp mt-25" data-wow-delay=".9s">
<div class="team__area-item">
<img class="img_full" src="/web/assets/img/team/team-3.jpg" alt="image">
<div class="team__area-item-content t-center pt-20">
<h5>Derya Kurtulus</h5>
<span>Safety Inspector</span>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 wow fadeInUp mt-25" data-wow-delay="1.2s">
<div class="team__area-item">
<img class="img_full" src="/web/assets/img/team/team-4.jpg" alt="image">
<div class="team__area-item-content t-center pt-20">
<h5>Steve Rhodes</h5>
<span>Civil Engineer</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Team Area End -->
@stop

View File

@@ -15,10 +15,10 @@
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>Careers</h2>
<h2>{{ __('Careers') }}</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Careers</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('Careers') }}</li>
</ul>
</div>
</div>
@@ -30,14 +30,17 @@
<div class="price__area section-padding">
<div class="container">
<div class="row">
<div class="col-xl-12 mb-25 text-center">
<h3 class="section-title">{{ __('For general application, send your resume at') }} career@gujurly.com</h3>
</div>
@forelse ($careers as $career)
<div class="col-xl-4 col-md-6 xl-mb-25 wow fadeInUp" data-wow-delay=".4s">
@forelse ($careers as $career)
<div class="price__area-item">
<div class="price__area-item-price">
<span>{{ $career->title }}</span>
<h3>{{ $career->location }}</h3>
<h2>{{ $career->salary_per_month }} {{ $career->salary_currency }}</h2>
<span>Per monthly</span>
<span>{{ __('Per monthly') }}</span>
</div>
<div class="price__area-item-list">
<ul>
@@ -47,13 +50,13 @@
</ul>
</div>
<div class="price__area-item-btn">
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $career->id }}" data-job-type="career" data-career-title="{{ $career->title }}" data-career-location="{{ $career->location }}" data-career-salary="{{ $career->salary_per_month }}" data-career-description="{{ $career->title_description }}">Apply Now<i class="flaticon-right-up"></i></button>
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $career->id }}" data-job-type="career" data-career-title="{{ $career->title }}" data-career-location="{{ $career->location }}" data-career-salary="{{ $career->salary_per_month }}" data-career-description="{{ $career->title_description }}">{{ __('Apply Now') }}<i class="flaticon-right-up"></i></button>
</div>
</div>
@empty
<span>No careers found...</span>
@endforelse
</div>
@empty
<span>{{ __('No careers found...') }}</span>
@endforelse
</div>
</div>
</div>
@@ -83,8 +86,8 @@
// Set dynamic values
modalTitle.textContent = button.getAttribute('data-' + jobType + '-title');
modalLocation.textContent = 'Location: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = 'Salary: ' + button.getAttribute('data-' + jobType + '-salary') + ' / Per monthly';
modalLocation.textContent = '{{ __('Location') }}: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = '{{ __('Salary') }}: ' + button.getAttribute('data-' + jobType + '-salary') + ' / {{ __('Per monthly') }}';
modalDescription.textContent = button.getAttribute('data-' + jobType + '-description');
jobIdInput.value = jobId;
@@ -121,12 +124,12 @@
modal.hide();
form.reset();
} else {
alert('Error: ' + data.message);
alert('{{ __('Error') }}: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred. Please try again.');
console.error('{{ __('Error') }}:', error);
alert('{{ __('An error occurred. Please try again.') }}');
});
});
}

View File

@@ -1,16 +1,19 @@
@extends('web.layouts.app')
@section('content')
@php
$contactSettings = app(\App\Settings\ContactSettings::class);
@endphp
<!-- Breadcrumb Area Start -->
<div class="breadcrumb__area" style="background-image: url('/web/assets/img/page/breadcrumb.jpg');">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>Contact Us</h2>
<h2>{{ __('Contact Us') }}</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Contact Us</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('Contact Us') }}</li>
</ul>
</div>
</div>
@@ -25,9 +28,9 @@
<div class="col-lg-5 lg-mb-25">
<div class="contact__area-left mr-40 xl-mr-0">
<div class="title">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">Contact Us</span>
<h2 class="title_split_anim mb-25">Get In Touch</h2>
<p class="wow fadeInUp" data-wow-delay=".4s">Were here to assist you! Please reach out with any questions, feedback, or project inquiries.</p>
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">{{ $contactSettings->contact_subtitle }}</span>
<h2 class="title_split_anim mb-25">{{ $contactSettings->contact_header }}</h2>
<p class="wow fadeInUp" data-wow-delay=".4s">{{ $contactSettings->contact_paragraph }}</p>
</div>
<div class="contact__area-left-contact wow fadeInUp" data-wow-delay=".7s">
<div class="contact__area-left-contact-item">
@@ -35,8 +38,8 @@
<i class="flaticon-phone"></i>
</div>
<div class="contact__area-left-contact-item-content">
<span>Phone:</span>
<h6><a href="tel:+123 (256) 568 58">+123 (256) 568 58</a></h6>
<span>{{ __('Phone') }}:</span>
<h6><a href="tel:{{ $contactSettings->phone_number }}">{{ $contactSettings->phone_number }}</a></h6>
</div>
</div>
<div class="contact__area-left-contact-item">
@@ -44,8 +47,8 @@
<i class="flaticon-email-3"></i>
</div>
<div class="contact__area-left-contact-item-content">
<span>Email Address:</span>
<h6><a href="mailto:needhelp@gmail.com">needhelp@gmail.com</a></h6>
<span>{{ __('Email Address') }}:</span>
<h6><a href="mailto:{{ $contactSettings->email_address }}">{{ $contactSettings->email_address }}</a></h6>
</div>
</div>
<div class="contact__area-left-contact-item">
@@ -53,8 +56,8 @@
<i class="flaticon-location-1"></i>
</div>
<div class="contact__area-left-contact-item-content">
<span>Location:</span>
<h6><a href="https://google.com/maps" target="_blank">2464 Royal Ln. Mesa, New Jersey 45463</a></h6>
<span>{{ __('Location') }}:</span>
<h6><a href="https://google.com/maps" target="_blank">{{ $contactSettings->location_address }}</a></h6>
</div>
</div>
</div>
@@ -62,32 +65,32 @@
</div>
<div class="col-lg-7 wow fadeInRight" data-wow-delay=".4s">
<div class="contact__area-form">
<h4>Send Message</h4>
<h4>{{ __('Send Message') }}</h4>
<form action="#">
<div class="row">
<div class="col-md-6 mb-25">
<div class="contact__form-area-item">
<input type="text" name="name" placeholder="Full Name" required="required">
<input type="text" name="name" placeholder="{{ __('Full Name') }}" required="required">
</div>
</div>
<div class="col-md-6 md-mb-25">
<div class="contact__form-area-item">
<input type="email" name="email" placeholder="Email Address" required="required">
<input type="email" name="email" placeholder="{{ __('Email Address') }}" required="required">
</div>
</div>
<div class="col-md-12 mb-25">
<div class="contact__form-area-item">
<input type="text" name="subject" placeholder="Subject">
<input type="text" name="subject" placeholder="{{ __('Subject') }}">
</div>
</div>
<div class="col-md-12 mb-25">
<div class="contact__form-area-item">
<textarea name="message" placeholder="Message"></textarea>
<textarea name="message" placeholder="{{ __('Message') }}"></textarea>
</div>
</div>
<div class="col-md-12">
<div class="contact__form-area-item">
<button class="build_button" type="submit">Submit Message <i class="flaticon-right-up"></i></button>
<button class="build_button" type="submit">{{ __('Submit Message') }} <i class="flaticon-right-up"></i></button>
</div>
</div>
</div>
@@ -104,7 +107,7 @@
<div class="row">
<div class="col-xl-12 wow fadeInUp" data-wow-delay=".4s">
<div class="map-area">
<iframe loading="lazy" src="https://maps.google.com/maps?q=London%20Eye%2C%20London%2C%20United%20Kingdom&amp;t=m&amp;z=10&amp;output=embed&amp;iwloc=near" title="London Eye, London, United Kingdom" aria-label="London Eye, London, United Kingdom"></iframe>
<iframe src="{{ $contactSettings->map_embed_url }}" loading="lazy" referrerpolicy="no-referrer-when-downgrade" title="Ashgabat, Turkmenistan" aria-label="Ashgabat, Turkmenistan"></iframe>
</div>
</div>
</div>

View File

@@ -146,14 +146,14 @@
</div>
<div class="row mt-70 wow fadeInUp" data-wow-delay=".5s">
<div class="col-xl-12">
<div class="swiper services_four_slide data_cursor" data-cursor-text="Drag">
<div class="swiper services_four_slide data_cursor" data-cursor-text="{{ __('Drag') }}">
<div class="swiper-wrapper">
@foreach($solutionSettings->solution_items as $item)
<div class="swiper-slide">
<div class="services__one-item">
<i class="{{ $item['icon_class'] }}"></i>
<h4><a href="{{ $item['link'] }}">{{ $item['title'] }}</a></h4>
<a class="more_btn" href="{{ $item['link'] }}">Read More<i class="flaticon-right-up"></i></a>
<a class="more_btn" href="{{ $item['link'] }}">{{ __('Read More') }}<i class="flaticon-right-up"></i></a>
</div>
</div>
@endforeach
@@ -315,8 +315,8 @@
<div class="row mb-30">
<div class="col-xl-12">
<div class="blog__four-title t-center">
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">News & Blog</span>
<h2 class="title_split_anim">News</h2>
<span class="subtitle wow fadeInLeft" data-wow-delay=".4s">{{ __('News & Blog') }}</span>
<h2 class="title_split_anim">{{ __('News') }}</h2>
</div>
</div>
</div>
@@ -334,8 +334,8 @@
<div class="blog__four-item-content">
<div class="meta">
<ul>
<li><a href="#"><i class="far fa-user"></i>{{ $news->author->name ?? 'Admin' }}</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>Comments ({{ $news->comments->count() }})</a></li>
<li><a href="#"><i class="far fa-user"></i>{{ $news->author->name ?? __('Admin') }}</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>{{ __('Comments') }} ({{ $news->comments->count() }})</a></li>
</ul>
</div>
<h4><a href="{{ route('news.show', $news->slug) }}">{{ $news->title }}</a></h4>

View File

@@ -15,10 +15,10 @@
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>Internships</h2>
<h2>{{ __('Internships') }}</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Internships</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('Internships') }}</li>
</ul>
</div>
</div>
@@ -30,14 +30,17 @@
<div class="price__area section-padding">
<div class="container">
<div class="row">
<div class="col-xl-12 mb-25 text-center">
<h3 class="section-title">{{ __('For general application, send your resume at') }} career@gujurly.com</h3>
</div>
@forelse ($internships as $internship)
<div class="col-xl-4 col-md-6 xl-mb-25 wow fadeInUp" data-wow-delay=".4s">
@forelse ($internships as $internship)
<div class="price__area-item">
<div class="price__area-item-price">
<span>{{ $internship->title }}</span>
<h3>{{ $internship->location }}</h3>
<h2>{{ $internship->salary_per_month }} {{ $internship->salary_currency }}</h2>
<span>Per monthly</span>
<span>{{ __('Per monthly') }}</span>
</div>
<div class="price__area-item-list">
<ul>
@@ -47,13 +50,13 @@
</ul>
</div>
<div class="price__area-item-btn">
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $internship->id }}" data-job-type="internship" data-internship-title="{{ $internship->title }}" data-internship-location="{{ $internship->location }}" data-internship-salary="{{ $internship->salary_per_month }}" data-internship-description="{{ $internship->title_description }}">Apply Now<i class="flaticon-right-up"></i></button>
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applyInternshipModal" data-job-id="{{ $internship->id }}" data-job-type="internship" data-internship-title="{{ $internship->title }}" data-internship-location="{{ $internship->location }}" data-internship-salary="{{ $internship->salary_per_month }}" data-internship-description="{{ $internship->title_description }}">{{ __('Apply Now') }}<i class="flaticon-right-up"></i></button>
</div>
</div>
@empty
<span>No internships found...</span>
@endforelse
</div>
@empty
<span>{{ __('No internships found...') }}</span>
@endforelse
</div>
</div>
</div>
@@ -83,8 +86,8 @@
// Set dynamic values
modalTitle.textContent = button.getAttribute('data-' + jobType + '-title');
modalLocation.textContent = 'Location: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = 'Salary: ' + button.getAttribute('data-' + jobType + '-salary') + ' / Per monthly';
modalLocation.textContent = '{{ __('Location') }}: ' + button.getAttribute('data-' + jobType + '-location');
modalSalary.textContent = '{{ __('Salary') }}: ' + button.getAttribute('data-' + jobType + '-salary') + ' / {{ __('Per monthly') }}';
modalDescription.textContent = button.getAttribute('data-' + jobType + '-description');
jobIdInput.value = jobId;
@@ -121,12 +124,12 @@
modal.hide();
form.reset();
} else {
alert('Error: ' + data.message);
alert('{{ __('Error') }}: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred. Please try again.');
console.error('{{ __('Error') }}:', error);
alert('{{ __('An error occurred. Please try again.') }}');
});
});
}

View File

@@ -7,10 +7,10 @@
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>News</h2>
<h2>{{ __('News') }}</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>News</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('News') }}</li>
</ul>
</div>
</div>
@@ -24,7 +24,7 @@
<div class="row">
<div class="col-xl-12">
<div class="section-title text-center pb-50">
<h2 class="pb-3">Read Our News</h2>
<h2 class="pb-3">{{ __('Read Our News') }}</h2>
</div>
</div>
</div>
@@ -40,13 +40,13 @@
</div>
<div class="blog__one-item-content">
<h4><a href="{{ route('news.show', $news->slug) }}">{{ $news->title }}</a></h4>
<a class="more_btn" href="{{ route('news.show', $news->slug) }}">Read More<i class="flaticon-right-up"></i></a>
<a class="more_btn" href="{{ route('news.show', $news->slug) }}">{{ __('Read More') }}<i class="flaticon-right-up"></i></a>
</div>
</div>
</div>
@empty
<div class="col-12">
<div class="alert alert-info">No news found...</div>
<div class="alert alert-info">{{ __('No news found...') }}</div>
</div>
@endforelse
</div>

View File

@@ -9,8 +9,8 @@
<div class="breadcrumb__area-content">
<h2>{{ $news->title }}</h2>
<ul>
<li><a href="{{ route('home') }}">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('news.index') }}">News</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('home') }}">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('news.index') }}">{{ __('News') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ $news->title }}</li>
</ul>
</div>
@@ -39,7 +39,7 @@
</div>
</div>
<div class="blog__details-area-comment mt-40">
<h3 class="mb-30">Comments ({{ $news->comments->count() }})</h3>
<h3 class="mb-30">{{ __('Comments') }} ({{ $news->comments->count() }})</h3>
@forelse ($news->comments as $comment)
<div class="blog__details-area-comment-item">
<div class="blog__details-area-comment-item-comment">
@@ -54,35 +54,35 @@
</div>
</div>
@empty
<p>No comments yet</p>
<p>{{ __('No comments yet') }}</p>
@endforelse
</div>
<div class="blog__details-area-contact mt-60">
<h3>Post Comment</h3>
<p>Required fields are marked</p>
<h3>{{ __('Post Comment') }}</h3>
<p>{{ __('Required fields are marked') }}</p>
<div class="blog__details-area-contact-form">
<form action="{{ route('comments.store', $news->slug) }}" method="POST">
@csrf
<div class="row">
<div class="col-sm-6 mt-25">
<div class="blog__details-area-contact-form-item contact-item">
<input type="text" name="author_name" placeholder="Full Name" required="required">
<input type="text" name="author_name" placeholder="{{ __('Full Name') }}" required="required">
</div>
</div>
<div class="col-sm-6 mt-25">
<div class="blog__details-area-contact-form-item contact-item">
<input type="text" name="title" placeholder="Title" required="required">
<input type="text" name="title" placeholder="{{ __('Title') }}" required="required">
</div>
</div>
<div class="col-sm-12 mt-25">
<div class="blog__details-area-contact-form-item contact-item">
<textarea name="message" placeholder="Type your comments...."></textarea>
<textarea name="message" placeholder="{{ __('Type your comments....') }}"></textarea>
<input type="hidden" name="news_id" value="{{ $news->id }}">
</div>
</div>
<div class="col-lg-12 mt-25">
<div class="blog__details-area-contact-form-item">
<button class="build_button" type="submit">Submit Comment<i class="flaticon-right-up"></i></button>
<button class="build_button" type="submit">{{ __('Submit Comment') }}<i class="flaticon-right-up"></i></button>
</div>
</div>
</div>
@@ -95,7 +95,7 @@
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Recent Blog</h4>
<h4>{{ __('Recent Blog') }}</h4>
<div class="all__sidebar-item-post dark_image">
@foreach($recentNews as $news)
<div class="post__item">

View File

@@ -2,14 +2,14 @@
@section('content')
<!-- Breadcrumb Area Start -->
<div class="breadcrumb__area" style="background-image: url('assets/img/page/breadcrumb.jpg');">
<div class="breadcrumb__area" style="background-image: url('/web/assets/img/page/breadcrumb.jpg');">
<div class="container">
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>Services Details</h2>
<ul>
<li><a href="index.html">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Services Details</li>
</ul>
</div>
@@ -23,77 +23,54 @@
<div class="container">
<div class="row">
<div class="col-lg-4">
<div class="all__sidebar">
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Our Solutions</h4>
<div class="all__sidebar-item-category">
<h4>Downloads</h4>
<div class="all__sidebar-item-download">
<ul>
<li><a href="services-details.html">Building Architecture<i class="flaticon-right-up"></i></a></li>
<li><a href="services-details.html">Interior Design<i class="flaticon-right-up"></i></a></li>
<li><a href="services-details.html">House Renovation<i class="flaticon-right-up"></i></a></li>
<li><a href="services-details.html">Flooring Installation<i class="flaticon-right-up"></i></a></li>
<li><a href="services-details.html">Foundation Repair<i class="flaticon-right-up"></i></a></li>
@if ($solution->downloads && count($solution->downloads) > 0)
@foreach ($solution->downloads as $download)
@if (isset($download['title']) && isset($download['file']))
<li><a href="{{ Storage::url($download['file']) }}">{{ $download['title'] }}<span class="fal fa-arrow-to-bottom"></span></a></li>
@endif
@endforeach
@else
<li>No downloads available...</li>
@endif
</ul>
</div>
</div>
<div class="all__sidebar-item-help mb-25" style="background-image: url('assets/img/page/cta-1.jpg');">
<h3>Ready for Your Next Construction?</h3>
<a class="build_button mt-20" href="contact.html">Get an Advice<i class="flaticon-right-up"></i></a>
</div>
<div class="all__sidebar-item">
<h4>Download</h4>
<div class="all__sidebar-item-download">
<ul>
<li><a href="#">Company Details<span class="fal fa-arrow-to-bottom"></span></a></li>
<li><a href="#">Our Brochures<span class="fal fa-arrow-to-bottom"></span></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="services__details-area">
<img src="assets/img/service/services-1.jpg" alt="image">
<h3 class="mt-25 mb-20">Construction Planning</h3>
<p class="mb-20">We pride ourselves on delivering high-quality construction services tailored to meet the unique needs of our clients. With years of experience in the industry, our team of skilled professionals is dedicated to bringing your vision to life. Whether you are looking to build a new structure, renovate an existing space, or need specialized construction services, we are here to help.</p>
<p class="mb-25">With years of industry experience, our team handles every aspect of the construction process, your project runs smoothly and efficiently. We prioritize open communication, timely delivery, and quality workmanship to exceed your expectations. Trust us to provide innovative solutions that.</p>
<h4 class="mb-20">Building with Unmatched Excellence</h4>
<p>Transform your existing space with our renovation and remodeling services. Whether you want to update your kitchen, bathroom, or entire home, we bring innovative solutions to enhance your living space. Our team has extensive experience in commercial construction, including office buildings, retail spaces, and industrial facilities. We work closely with you to ensure your project align.</p>
<div class="row mt-40 mb-40">
<div class="col-sm-6 sm-mb-25">
<img class="img_full" src="assets/img/portfolio/portfolio-5.jpg" alt="image">
</div>
<div class="col-sm-6">
<img class="img_full" src="assets/img/portfolio/portfolio-8.jpg" alt="image">
</div>
</div>
<p>We deliver exceptional construction services backed by years of experience. Our skilled team prioritizes quality, transparency, and client satisfaction. We utilize innovative techniques and sustainable practices, ensuring timely project completion. Trust us to bring your to life with unmatched craftsmanship</p>
<ul class="services__details-area-list">
<li><i class="flaticon-check-mark"></i>Our skilled professionals bring years of experience a</span></li>
<li><i class="flaticon-check-mark"></i>We are the leading construction company in the industry.</span></li>
<li><i class="flaticon-check-mark"></i>Our transparent pricing ensures no hidden fees or surprises.</span></li>
<li><i class="flaticon-check-mark"></i>We adhere to strict safety standards on all job sites.</span></li>
</ul>
<h3>Commonly Asked Questions</h3>
<h3 class="mt-25 mb-20">{{ $solution->title }}</h3>
<p class="mb-20">{{ $solution->title_description }}</p>
{!! $solution->description !!}
@if (count($solution->bullets) > 0)
<h4 class="mb-20 mt-40">Key Aspects of Our Solutions</h4>
<ul class="services__details-area-list">
@foreach ($solution->bullets as $bullet)
@if (isset($bullet['bullet']))
<li><i class="flaticon-check-mark"></i>{{ $bullet['bullet'] }}</li>
@endif
@endforeach
</ul>
@endif
<h3>Frequently Asked Questions</h3>
<div class="mt-30" id="accordionExample">
<div class="faq-item">
<h5 class="icon" data-bs-toggle="collapse" data-bs-target="#collapseOne">1. What services do you offer?</h5>
<div id="collapseOne" class="faq-item-body collapse show" data-bs-parent="#accordionExample">
<p>We offer a range of services including construction management, design-build solutions, renovations, and specialty contracting for both residential and commercial projects</p>
</div>
</div>
<div class="faq-item">
<h5 class="icon collapsed" data-bs-toggle="collapse" data-bs-target="#collapseTwo">2. Do you provide free estimates?</h5>
<div id="collapseTwo" class="faq-item-body collapse" data-bs-parent="#accordionExample">
<p>Yes, we offer free estimates for all potential projects. We assess your requirements and provide a detailed quote without any obligation</p>
</div>
</div>
<div class="faq-item">
<h5 class="icon collapsed" data-bs-toggle="collapse" data-bs-target="#collapseThree">3. Are you licensed and insured?</h5>
<div id="collapseThree" class="faq-item-body collapse" data-bs-parent="#accordionExample">
<p>Yes, we are fully licensed and insured to operate in our service areas. This ensures that your project is protected and complies with all local regulations</p>
</div>
</div>
@if ($solution->faqs && count($solution->faqs) > 0)
@foreach ($solution->faqs as $key => $faq)
<div class="faq-item">
<h5 class="icon {{ $key === 0 ? '' : 'collapsed' }}" data-bs-toggle="collapse" data-bs-target="#collapse{{ $key + 1 }}">{{ $key + 1 }}. {{ $faq['question'] }}</h5>
<div id="collapse{{ $key + 1 }}" class="faq-item-body collapse {{ $key === 0 ? 'show' : '' }}" data-bs-parent="#accordionExample">
<p>{!! $faq['answer'] !!}</p>
</div>
</div>
@endforeach
@else
<p>No FAQs available.</p>
@endif
</div>
</div>
</div>

View File

@@ -7,10 +7,10 @@
<div class="row">
<div class="col-xl-12">
<div class="breadcrumb__area-content">
<h2>Success Stories</h2>
<h2>{{ __('Success Stories') }}</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Success Stories</li>
<li><a href="/">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ __('Success Stories') }}</li>
</ul>
</div>
</div>
@@ -24,8 +24,8 @@
<div class="row">
<div class="col-xl-12">
<div class="section-title text-center pb-50">
<h2 class="pb-3">Our Success Stories</h2>
<p>Discover inspiring narratives of triumph, growth, and achievement through our curated collection of success stories. Each story is a testament to dedication and hard work.</p>
<h2 class="pb-3">{{ __('Our Success Stories') }}</h2>
<p>{{ __('Discover inspiring narratives of triumph, growth, and achievement through our curated collection of success stories. Each story is a testament to dedication and hard work.') }}</p>
</div>
</div>
@forelse ($allSuccesses as $success)
@@ -39,13 +39,13 @@
</div>
<div class="blog__one-item-content">
<h4><a href="{{ route('success.show', $success->slug) }}">{{ $success->title }}</a></h4>
<a class="more_btn" href="{{ route('success.show', $success->slug) }}">Read More<i class="flaticon-right-up"></i></a>
<a class="more_btn" href="{{ route('success.show', $success->slug) }}">{{ __('Read More') }}<i class="flaticon-right-up"></i></a>
</div>
</div>
</div>
@empty
<div class="col-12">
<div class="alert alert-info">No success stories found...</div>
<div class="alert alert-info">{{ __('No success stories found...') }}</div>
</div>
@endforelse
</div>

View File

@@ -9,8 +9,8 @@
<div class="breadcrumb__area-content">
<h2>{{ $success->title }}</h2>
<ul>
<li><a href="{{ route('home') }}">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('success.index') }}">Success Stories</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('home') }}">{{ __('Home') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li><a href="{{ route('success.index') }}">{{ __('Success Stories') }}</a><i class="fa-regular fa-angle-right"></i></li>
<li>{{ $success->title }}</li>
</ul>
</div>
@@ -34,7 +34,7 @@
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Recent Success Stories</h4>
<h4>{{ __('Recent Success Stories') }}</h4>
<div class="all__sidebar-item-post dark_image">
@foreach($recentSuccesses as $success)
<div class="post__item">

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
<?php
use App\Http\Controllers\AboutusPageController;
use App\Http\Controllers\ApplicationController;
use App\Http\Controllers\CareersPageController;
use App\Http\Controllers\ContactPageController;
use App\Http\Controllers\HomePageController;
@@ -8,10 +9,9 @@ use App\Http\Controllers\InternshipsPageController;
use App\Http\Controllers\LegalPageController;
use App\Http\Controllers\NewsPageController;
use App\Http\Controllers\OurSolutionPageController;
use App\Http\Controllers\StoryPageController;
use App\Http\Controllers\Web\SuccessPageController;
use App\Http\Controllers\ApplicationController;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
// Homepage...
Route::get('/', [HomePageController::class, 'index'])->name('home');
@@ -49,3 +49,10 @@ Route::post('contact', [ContactPageController::class, 'store'])->name('contact.s
// Legal pages...
Route::get('terms-and-conditions', [LegalPageController::class, 'terms'])->name('terms');
Route::get('privacy-and-policy', [LegalPageController::class, 'privacy'])->name('privacy');
// Language Switcher
Route::get('locale/{locale}', function ($locale) {
Session::put('locale', $locale);
return redirect()->back();
})->name('locale.switch');