Compare commits

..

9 Commits

Author SHA1 Message Date
a89e2a71d8 Enhance careers management features: update CareersPageController to fetch and display career listings with additional fields, modify Career model to include relationships and new attributes, and create a new view for the careers index with an application modal. Update database migration to reflect changes in the careers table structure and adjust routes for application submissions. 2025-07-29 00:23:08 +05:00
9b3ca3ff66 Update footer and header navigation links to reflect new route for success stories, and remove pagination section from news index view for cleaner layout. 2025-07-28 21:17:54 +05:00
41abdb6fc8 Update news index view: change page title from 'Blog 3 Columns' to 'News' and adjust breadcrumb navigation for improved clarity and consistency. 2025-07-28 21:07:27 +05:00
6b0c92d838 Refactor News management features: replace author text input with a searchable select component in NewsResource, update NewsPageController to fetch news with authors and recent articles, and enhance the news show view to display author details and comments more effectively. 2025-07-28 21:05:24 +05:00
1b4989b440 Enhance solution management features: add title_description and bullets fields to SolutionResource, update OurSolutionPageController to fetch solutions in descending order, and create new views for displaying solutions with detailed descriptions and bullet points. Adjust CSS for active button styling and update navigation to reflect title instead of name for solutions. 2025-07-28 20:33:38 +05:00
e2323c7949 Refactor file imports and clean up unused components in various resources: remove unnecessary imports in CommentResource, NewsResource, and SolutionResource, and ensure consistent formatting across files. Add missing newlines at the end of files for better code quality. 2025-07-28 20:10:34 +05:00
b23f537086 Update navigation groups for various resources: change ManageCtaSettings to 'Home', CommentResource and NewsResource to 'News', and add 'Brands' for BrandResource. Update navigation icon for SolutionResource to 'heroicon-o-light-bulb'. 2025-07-28 20:08:37 +05:00
7fdb99cc79 Refactor navigation settings across multiple pages: update navigation groups and labels for HomePageSettings, ManageCtaSettings, ManagePortfolio, ManageSolutions, ManageSuccess, and ManageSite. Introduce solutions data fetching in OurSolutionPageController and enhance header navigation with dynamic solutions list. Update database migration to include new fields for solutions. 2025-07-28 20:06:11 +05:00
74fc3b5e6a Implement news management features: add author field and comments functionality in NewsResource, enhance HomePageController to fetch latest news, and create dedicated views for news display and commenting. Update routes for comment submission and adjust homepage to showcase recent news articles. 2025-07-28 18:56:17 +05:00
73 changed files with 2366 additions and 373 deletions

View File

@@ -15,6 +15,8 @@ use Illuminate\Contracts\Support\Htmlable;
class HomePageSettings extends SettingsPage
{
protected static ?string $navigationGroup = 'Home';
protected static ?string $navigationIcon = 'heroicon-o-home';
protected static string $settings = HomeSettings::class;
@@ -269,12 +271,12 @@ class HomePageSettings extends SettingsPage
public static function getNavigationGroup(): ?string
{
return __('CMS');
return __('Home');
}
public static function getNavigationLabel(): string
{
return __('Home');
return __('Home Page Settings');
}
public function getTitle(): string|Htmlable

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Filament\Pages;
use App\Settings\CtaSettings;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Form;
use Filament\Pages\SettingsPage;
class ManageCtaSettings extends SettingsPage
{
protected static ?string $navigationGroup = 'Home';
protected static ?string $navigationIcon = 'heroicon-o-megaphone';
protected static string $settings = CtaSettings::class;
public static function getNavigationLabel(): string
{
return 'Call To Action';
}
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->label('Call To Action Title')
->required(),
Forms\Components\TextInput::make('button_text')
->label('Button Text')
->required(),
Forms\Components\TextInput::make('button_url')
->label('Button URL')
->required()
->url(),
FileUpload::make('background_image')
->label('Background Image 1320x408')
->directory('settings')
->image()
->columnSpan('full'),
]);
}
}

View File

@@ -14,6 +14,8 @@ use Illuminate\Contracts\Support\Htmlable;
class ManagePortfolio extends SettingsPage
{
protected static ?string $navigationGroup = 'Home';
protected static ?string $navigationIcon = 'heroicon-o-briefcase';
protected static string $settings = PortfolioSettings::class;
@@ -84,7 +86,7 @@ class ManagePortfolio extends SettingsPage
public static function getNavigationGroup(): ?string
{
return __('CMS');
return __('Home');
}
public static function getNavigationLabel(): string

View File

@@ -10,6 +10,8 @@ use Illuminate\Contracts\Support\Htmlable;
class ManageSite extends SettingsPage
{
protected static ?string $navigationGroup = 'Settings';
protected static ?string $navigationIcon = 'heroicon-o-globe-alt';
protected static string $settings = SiteSettings::class;

View File

@@ -10,7 +10,7 @@ use Illuminate\Contracts\Support\Htmlable;
class ManageSiteSocialSettings extends SettingsPage
{
protected static ?int $navigationSort = 4;
protected static ?string $navigationGroup = 'Settings';
protected static ?string $navigationIcon = 'heroicon-o-share';

View File

@@ -15,6 +15,8 @@ use Illuminate\Contracts\Support\Htmlable;
class ManageSolutions extends SettingsPage
{
protected static ?string $navigationGroup = 'Home';
protected static ?string $navigationIcon = 'heroicon-o-wrench-screwdriver';
protected static string $settings = SolutionSettings::class;
@@ -35,11 +37,11 @@ class ManageSolutions extends SettingsPage
->label('Header')
->required()
->maxLength(255),
FileUpload::make('solutions_image')
->label('Image 1060x453')
->image()
->directory('solutions')
->required(),
FileUpload::make('solutions_image')
->label('Image 1060x453')
->image()
->directory('solutions')
->required(),
Grid::make()->schema([
TextInput::make('solutions_button_text')
->label('Button Text')
@@ -91,273 +93,273 @@ class ManageSolutions extends SettingsPage
private static function getIconOptions(): array
{
return [
"microsoft-word" => "microsoft-word",
"text-box" => "text-box",
"document-1" => "document-1",
"layers-1" => "layers-1",
"folder-1" => "folder-1",
"contract" => "contract",
"layer" => "layer",
"download-pdf" => "download-pdf",
"pdf" => "pdf",
"cloud-computing" => "cloud-computing",
"downloads" => "downloads",
"layers" => "layers",
"document" => "document",
"light-bulb-1" => "light-bulb-1",
"idea-2" => "idea-2",
"light-bulb" => "light-bulb",
"idea-1" => "idea-1",
"solution-2" => "solution-2",
"lightbulb" => "lightbulb",
"menus" => "menus",
"support-1" => "support-1",
"swipe-left" => "swipe-left",
"development" => "development",
"domain" => "domain",
"pets" => "pets",
"diagram" => "diagram",
"targeting" => "targeting",
"business-intelligence" => "business-intelligence",
"menu-6" => "menu-6",
"high-quality" => "high-quality",
"campaign" => "campaign",
"brain" => "brain",
"software-application" => "software-application",
"apps" => "apps",
"wrench-1" => "wrench-1",
"social-media-marketing-1" => "social-media-marketing-1",
"category-1" => "category-1",
"trophy-3" => "trophy-3",
"email-marketing" => "email-marketing",
"setting" => "setting",
"more" => "more",
"menu-5" => "menu-5",
"menu-4" => "menu-4",
"medical" => "medical",
"sparkle" => "sparkle",
"menu-3" => "menu-3",
"technology-2" => "technology-2",
"process" => "process",
"hearth-1" => "hearth-1",
"hearth" => "hearth",
"technology-1" => "technology-1",
"category" => "category",
"customer-care" => "customer-care",
"folder" => "folder",
"portfolio-1" => "portfolio-1",
"report" => "report",
"thinking" => "thinking",
"fingerprint" => "fingerprint",
"clock-2" => "clock-2",
"award" => "award",
"paper-plane" => "paper-plane",
"repair" => "repair",
"email-5" => "email-5",
"strategy" => "strategy",
"portfolio" => "portfolio",
"web-design" => "web-design",
"email-4" => "email-4",
"down-arrow-1" => "down-arrow-1",
"location-2" => "location-2",
"phone-call-2" => "phone-call-2",
"telephone-call" => "telephone-call",
"teamwork" => "teamwork",
"up-arrow-1" => "up-arrow-1",
"menu-2" => "menu-2",
"developing" => "developing",
"money-bag" => "money-bag",
"thumbs-up" => "thumbs-up",
"profits" => "profits",
"location-1" => "location-1",
"help-1" => "help-1",
"online-chat" => "online-chat",
"worker" => "worker",
"smart-home" => "smart-home",
"customer-service-1" => "customer-service-1",
"internet" => "internet",
"cash-flow" => "cash-flow",
"monitor" => "monitor",
"search-1" => "search-1",
"wrench" => "wrench",
"coin" => "coin",
"cash" => "cash",
"analyst" => "analyst",
"dashboard-1" => "dashboard-1",
"digital" => "digital",
"searching" => "searching",
"email-3" => "email-3",
"star-1" => "star-1",
"touch" => "touch",
"medal" => "medal",
"world-wide-web-1" => "world-wide-web-1",
"phone" => "phone",
"social-media" => "social-media",
"24-7" => "24-7",
"hard-work" => "hard-work",
"star" => "star",
"plus" => "plus",
"minus-2" => "minus-2",
"menu-1" => "menu-1",
"cloud" => "cloud",
"handshake" => "handshake",
"people" => "people",
"ai" => "ai",
"save-money" => "save-money",
"shopping-online" => "shopping-online",
"profit-1" => "profit-1",
"blockchain" => "blockchain",
"sales" => "sales",
"back-in-time" => "back-in-time",
"clock-1" => "clock-1",
"user-3" => "user-3",
"user-2" => "user-2",
"pawprint" => "pawprint",
"payment-method" => "payment-method",
"world-wide-web" => "world-wide-web",
"minus-1" => "minus-1",
"add-1" => "add-1",
"management" => "management",
"help" => "help",
"chip" => "chip",
"artificial-intelligence" => "artificial-intelligence",
"group" => "group",
"money-1" => "money-1",
"conversation" => "conversation",
"email-2" => "email-2",
"rating" => "rating",
"placeholder" => "placeholder",
"trophy-2" => "trophy-2",
"cpu" => "cpu",
"home" => "home",
"right-arrow-1" => "right-arrow-1",
"like" => "like",
"mail" => "mail",
"briefcase" => "briefcase",
"money" => "money",
"up-arrow" => "up-arrow",
"trophy-1" => "trophy-1",
"user-1" => "user-1",
"question" => "question",
"team-1" => "team-1",
"user" => "user",
"email-1" => "email-1",
"price-tag-1" => "price-tag-1",
"tag" => "tag",
"loupe" => "loupe",
"right-arrow" => "right-arrow",
"left-arrow-1" => "left-arrow-1",
"down-arrow" => "down-arrow",
"price-tag" => "price-tag",
"stars" => "stars",
"search" => "search",
"phone-call-1" => "phone-call-1",
"award-symbol" => "award-symbol",
"christmas-stars" => "christmas-stars",
"minus" => "minus",
"add" => "add",
"cancel-1" => "cancel-1",
"checked" => "checked",
"cyber-security" => "cyber-security",
"data-protection" => "data-protection",
"hosting" => "hosting",
"brand-awareness" => "brand-awareness",
"ux-design" => "ux-design",
"influencer" => "influencer",
"online-advertising" => "online-advertising",
"web-management" => "web-management",
"seo-1" => "seo-1",
"computer" => "computer",
"software-development" => "software-development",
"coding-1" => "coding-1",
"coding" => "coding",
"app-development" => "app-development",
"content-marketing" => "content-marketing",
"social-media-marketing" => "social-media-marketing",
"analysis-1" => "analysis-1",
"twitter" => "twitter",
"repairing" => "repairing",
"data-visualization" => "data-visualization",
"information-technology" => "information-technology",
"statistics-1" => "statistics-1",
"exploration" => "exploration",
"project-1" => "project-1",
"cross-mark" => "cross-mark",
"search-analysis" => "search-analysis",
"system" => "system",
"hashtag-1" => "hashtag-1",
"hashtag" => "hashtag",
"it-department" => "it-department",
"creative" => "creative",
"online-analytical" => "online-analytical",
"secure-data" => "secure-data",
"slash" => "slash",
"creative-thinking" => "creative-thinking",
"right-up" => "right-up",
"dashboard" => "dashboard",
"profit" => "profit",
"project" => "project",
"phone-call" => "phone-call",
"seo" => "seo",
"prototype" => "prototype",
"creative-process" => "creative-process",
"growth" => "growth",
"technical-support" => "technical-support",
"technology" => "technology",
"solution-1" => "solution-1",
"creative-tools" => "creative-tools",
"data-science" => "data-science",
"costumer" => "costumer",
"cooperation" => "cooperation",
"next" => "next",
"back" => "back",
"brand" => "brand",
"right-arrows" => "right-arrows",
"idea" => "idea",
"design-thinking" => "design-thinking",
"check" => "check",
"cross" => "cross",
"right" => "right",
"link" => "link",
"server" => "server",
"analysis" => "analysis",
"support" => "support",
"project-management" => "project-management",
"networking" => "networking",
"team" => "team",
"check-mark" => "check-mark",
"consultation" => "consultation",
"solution" => "solution",
"success" => "success",
"customer-review" => "customer-review",
"select" => "select",
"statistics" => "statistics",
"machine-learning" => "machine-learning",
"vector" => "vector",
"trophy" => "trophy",
"data" => "data",
"clock" => "clock",
"cancel" => "cancel",
"customer-service" => "customer-service",
"digital-marketing" => "digital-marketing",
"email" => "email",
"stats" => "stats",
"menu" => "menu",
"location" => "location",
"tick" => "tick",
"left-arrow" => "left-arrow",
"dots-menu" => "dots-menu",
'microsoft-word' => 'microsoft-word',
'text-box' => 'text-box',
'document-1' => 'document-1',
'layers-1' => 'layers-1',
'folder-1' => 'folder-1',
'contract' => 'contract',
'layer' => 'layer',
'download-pdf' => 'download-pdf',
'pdf' => 'pdf',
'cloud-computing' => 'cloud-computing',
'downloads' => 'downloads',
'layers' => 'layers',
'document' => 'document',
'light-bulb-1' => 'light-bulb-1',
'idea-2' => 'idea-2',
'light-bulb' => 'light-bulb',
'idea-1' => 'idea-1',
'solution-2' => 'solution-2',
'lightbulb' => 'lightbulb',
'menus' => 'menus',
'support-1' => 'support-1',
'swipe-left' => 'swipe-left',
'development' => 'development',
'domain' => 'domain',
'pets' => 'pets',
'diagram' => 'diagram',
'targeting' => 'targeting',
'business-intelligence' => 'business-intelligence',
'menu-6' => 'menu-6',
'high-quality' => 'high-quality',
'campaign' => 'campaign',
'brain' => 'brain',
'software-application' => 'software-application',
'apps' => 'apps',
'wrench-1' => 'wrench-1',
'social-media-marketing-1' => 'social-media-marketing-1',
'category-1' => 'category-1',
'trophy-3' => 'trophy-3',
'email-marketing' => 'email-marketing',
'setting' => 'setting',
'more' => 'more',
'menu-5' => 'menu-5',
'menu-4' => 'menu-4',
'medical' => 'medical',
'sparkle' => 'sparkle',
'menu-3' => 'menu-3',
'technology-2' => 'technology-2',
'process' => 'process',
'hearth-1' => 'hearth-1',
'hearth' => 'hearth',
'technology-1' => 'technology-1',
'category' => 'category',
'customer-care' => 'customer-care',
'folder' => 'folder',
'portfolio-1' => 'portfolio-1',
'report' => 'report',
'thinking' => 'thinking',
'fingerprint' => 'fingerprint',
'clock-2' => 'clock-2',
'award' => 'award',
'paper-plane' => 'paper-plane',
'repair' => 'repair',
'email-5' => 'email-5',
'strategy' => 'strategy',
'portfolio' => 'portfolio',
'web-design' => 'web-design',
'email-4' => 'email-4',
'down-arrow-1' => 'down-arrow-1',
'location-2' => 'location-2',
'phone-call-2' => 'phone-call-2',
'telephone-call' => 'telephone-call',
'teamwork' => 'teamwork',
'up-arrow-1' => 'up-arrow-1',
'menu-2' => 'menu-2',
'developing' => 'developing',
'money-bag' => 'money-bag',
'thumbs-up' => 'thumbs-up',
'profits' => 'profits',
'location-1' => 'location-1',
'help-1' => 'help-1',
'online-chat' => 'online-chat',
'worker' => 'worker',
'smart-home' => 'smart-home',
'customer-service-1' => 'customer-service-1',
'internet' => 'internet',
'cash-flow' => 'cash-flow',
'monitor' => 'monitor',
'search-1' => 'search-1',
'wrench' => 'wrench',
'coin' => 'coin',
'cash' => 'cash',
'analyst' => 'analyst',
'dashboard-1' => 'dashboard-1',
'digital' => 'digital',
'searching' => 'searching',
'email-3' => 'email-3',
'star-1' => 'star-1',
'touch' => 'touch',
'medal' => 'medal',
'world-wide-web-1' => 'world-wide-web-1',
'phone' => 'phone',
'social-media' => 'social-media',
'24-7' => '24-7',
'hard-work' => 'hard-work',
'star' => 'star',
'plus' => 'plus',
'minus-2' => 'minus-2',
'menu-1' => 'menu-1',
'cloud' => 'cloud',
'handshake' => 'handshake',
'people' => 'people',
'ai' => 'ai',
'save-money' => 'save-money',
'shopping-online' => 'shopping-online',
'profit-1' => 'profit-1',
'blockchain' => 'blockchain',
'sales' => 'sales',
'back-in-time' => 'back-in-time',
'clock-1' => 'clock-1',
'user-3' => 'user-3',
'user-2' => 'user-2',
'pawprint' => 'pawprint',
'payment-method' => 'payment-method',
'world-wide-web' => 'world-wide-web',
'minus-1' => 'minus-1',
'add-1' => 'add-1',
'management' => 'management',
'help' => 'help',
'chip' => 'chip',
'artificial-intelligence' => 'artificial-intelligence',
'group' => 'group',
'money-1' => 'money-1',
'conversation' => 'conversation',
'email-2' => 'email-2',
'rating' => 'rating',
'placeholder' => 'placeholder',
'trophy-2' => 'trophy-2',
'cpu' => 'cpu',
'home' => 'home',
'right-arrow-1' => 'right-arrow-1',
'like' => 'like',
'mail' => 'mail',
'briefcase' => 'briefcase',
'money' => 'money',
'up-arrow' => 'up-arrow',
'trophy-1' => 'trophy-1',
'user-1' => 'user-1',
'question' => 'question',
'team-1' => 'team-1',
'user' => 'user',
'email-1' => 'email-1',
'price-tag-1' => 'price-tag-1',
'tag' => 'tag',
'loupe' => 'loupe',
'right-arrow' => 'right-arrow',
'left-arrow-1' => 'left-arrow-1',
'down-arrow' => 'down-arrow',
'price-tag' => 'price-tag',
'stars' => 'stars',
'search' => 'search',
'phone-call-1' => 'phone-call-1',
'award-symbol' => 'award-symbol',
'christmas-stars' => 'christmas-stars',
'minus' => 'minus',
'add' => 'add',
'cancel-1' => 'cancel-1',
'checked' => 'checked',
'cyber-security' => 'cyber-security',
'data-protection' => 'data-protection',
'hosting' => 'hosting',
'brand-awareness' => 'brand-awareness',
'ux-design' => 'ux-design',
'influencer' => 'influencer',
'online-advertising' => 'online-advertising',
'web-management' => 'web-management',
'seo-1' => 'seo-1',
'computer' => 'computer',
'software-development' => 'software-development',
'coding-1' => 'coding-1',
'coding' => 'coding',
'app-development' => 'app-development',
'content-marketing' => 'content-marketing',
'social-media-marketing' => 'social-media-marketing',
'analysis-1' => 'analysis-1',
'twitter' => 'twitter',
'repairing' => 'repairing',
'data-visualization' => 'data-visualization',
'information-technology' => 'information-technology',
'statistics-1' => 'statistics-1',
'exploration' => 'exploration',
'project-1' => 'project-1',
'cross-mark' => 'cross-mark',
'search-analysis' => 'search-analysis',
'system' => 'system',
'hashtag-1' => 'hashtag-1',
'hashtag' => 'hashtag',
'it-department' => 'it-department',
'creative' => 'creative',
'online-analytical' => 'online-analytical',
'secure-data' => 'secure-data',
'slash' => 'slash',
'creative-thinking' => 'creative-thinking',
'right-up' => 'right-up',
'dashboard' => 'dashboard',
'profit' => 'profit',
'project' => 'project',
'phone-call' => 'phone-call',
'seo' => 'seo',
'prototype' => 'prototype',
'creative-process' => 'creative-process',
'growth' => 'growth',
'technical-support' => 'technical-support',
'technology' => 'technology',
'solution-1' => 'solution-1',
'creative-tools' => 'creative-tools',
'data-science' => 'data-science',
'costumer' => 'costumer',
'cooperation' => 'cooperation',
'next' => 'next',
'back' => 'back',
'brand' => 'brand',
'right-arrows' => 'right-arrows',
'idea' => 'idea',
'design-thinking' => 'design-thinking',
'check' => 'check',
'cross' => 'cross',
'right' => 'right',
'link' => 'link',
'server' => 'server',
'analysis' => 'analysis',
'support' => 'support',
'project-management' => 'project-management',
'networking' => 'networking',
'team' => 'team',
'check-mark' => 'check-mark',
'consultation' => 'consultation',
'solution' => 'solution',
'success' => 'success',
'customer-review' => 'customer-review',
'select' => 'select',
'statistics' => 'statistics',
'machine-learning' => 'machine-learning',
'vector' => 'vector',
'trophy' => 'trophy',
'data' => 'data',
'clock' => 'clock',
'cancel' => 'cancel',
'customer-service' => 'customer-service',
'digital-marketing' => 'digital-marketing',
'email' => 'email',
'stats' => 'stats',
'menu' => 'menu',
'location' => 'location',
'tick' => 'tick',
'left-arrow' => 'left-arrow',
'dots-menu' => 'dots-menu',
];
}
public static function getNavigationGroup(): ?string
{
return __('CMS');
return __('Home');
}
public static function getNavigationLabel(): string
{
return __('Solutions');
return __('Manage Solutions');
}
public function getTitle(): string|Htmlable

View File

@@ -3,18 +3,20 @@
namespace App\Filament\Pages;
use App\Settings\SuccessSettings;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Form;
use Filament\Pages\SettingsPage;
use Illuminate\Contracts\Support\Htmlable;
class ManageSuccess extends SettingsPage
{
protected static ?string $navigationGroup = 'Home';
protected static ?string $navigationIcon = 'heroicon-o-check-circle';
protected static string $settings = SuccessSettings::class;
@@ -89,7 +91,7 @@ class ManageSuccess extends SettingsPage
public static function getNavigationGroup(): ?string
{
return __('CMS');
return __('Home');
}
public static function getNavigationLabel(): string

View File

@@ -0,0 +1,98 @@
<?php
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;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class AuthorResource extends Resource
{
protected static ?string $model = Author::class;
protected static ?string $navigationIcon = 'heroicon-o-users';
protected static ?string $navigationGroup = 'News';
public static function form(Form $form):
Form
{
return $form
->schema([
Forms\Components\Card::make()
->schema([
TextInput::make('name')
->required()
->maxLength(255),
FileUpload::make('profile_image')
->label('Profile Image 400x400')
->image()
->directory('authors')
->nullable(),
RichEditor::make('description')
->nullable()
->columnSpanFull(),
])->columns(1),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
ImageColumn::make('profile_image')
->square()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('name')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAuthors::route('/'),
'create' => Pages\CreateAuthor::route('/create'),
'edit' => Pages\EditAuthor::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAuthor extends CreateRecord
{
protected static string $resource = AuthorResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditAuthor extends EditRecord
{
protected static string $resource = AuthorResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListAuthors extends ListRecords
{
protected static string $resource = AuthorResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -19,7 +19,9 @@ class BrandResource extends Resource
{
protected static ?string $model = Brand::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationIcon = 'heroicon-o-tag';
protected static ?string $navigationGroup = 'Brands';
public static function form(Form $form): Form
{

View File

@@ -0,0 +1,115 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\CareerResource\Pages;
use App\Filament\Resources\CareerResource\RelationManagers;
use App\Models\Career;
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;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
class CareerResource extends Resource
{
protected static ?string $model = Career::class;
protected static ?string $navigationGroup = 'Careers';
protected static ?string $navigationIcon = 'heroicon-o-briefcase';
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('title')
->required()
->maxLength(255),
TextInput::make('location')
->required()
->maxLength(255),
Textarea::make('title_description')
->label('Description (show on modal)')
->required()
->maxLength(65535)
->columnSpan('full'),
TextInput::make('salary_per_month')
->required()
->numeric()
->label('Salary per month')
->maxLength(255),
Repeater::make('bullets')
->schema([
TextInput::make('bullet')
->required()
->maxLength(255),
])
->minItems(1)
->defaultItems(1)
->columnSpan('full'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->searchable(),
Tables\Columns\TextColumn::make('title_description')
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('salary_per_month')
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('location')
->searchable(),
Tables\Columns\TextColumn::make('salary')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
RelationManagers\ApplicationsRelationManager::class,
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCareers::route('/'),
'create' => Pages\CreateCareer::route('/create'),
'edit' => Pages\EditCareer::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\CareerResource\Pages;
use App\Filament\Resources\CareerResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCareer extends CreateRecord
{
protected static string $resource = CareerResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\CareerResource\Pages;
use App\Filament\Resources\CareerResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCareer extends EditRecord
{
protected static string $resource = CareerResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\CareerResource\Pages;
use App\Filament\Resources\CareerResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListCareers extends ListRecords
{
protected static string $resource = CareerResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace App\Filament\Resources\CareerResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class ApplicationsRelationManager extends RelationManager
{
protected static string $relationship = 'applications';
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
Forms\Components\DatePicker::make('birthdate')
->required(),
Forms\Components\FileUpload::make('resume_file')
->required()
->acceptedFileTypes(['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'])
->disk('public') // or your preferred disk
->directory('resumes'),
Forms\Components\TextInput::make('email')
->email()
->required()
->maxLength(255),
Forms\Components\TextInput::make('phone_number')
->required()
->maxLength(20),
Forms\Components\Textarea::make('cover_letter')
->maxLength(65535)
->nullable()
->columnSpan('full'),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('name')
->columns([
Tables\Columns\TextColumn::make('name')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('email')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('phone_number')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\CommentResource\Pages;
use App\Models\Comment;
use Filament\Forms;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
class CommentResource extends Resource
{
protected static ?string $model = Comment::class;
protected static ?string $navigationIcon = 'heroicon-o-chat-bubble-bottom-center-text';
protected static ?string $navigationGroup = 'News';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Card::make()
->schema([
Select::make('news_id')
->relationship('news', 'title')
->required(),
TextInput::make('title')
->required()
->maxLength(255),
RichEditor::make('message')
->required()
->columnSpanFull(),
TextInput::make('author_name')
->label('Author Name (Optional)')
->maxLength(255),
])
->columns(2),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('news.title')
->label('News Article')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('title')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('author_name')
->label('Author')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListComments::route('/'),
'create' => Pages\CreateComment::route('/create'),
'edit' => Pages\EditComment::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\CommentResource\Pages;
use App\Filament\Resources\CommentResource;
use Filament\Resources\Pages\CreateRecord;
class CreateComment extends CreateRecord
{
protected static string $resource = CommentResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\CommentResource\Pages;
use App\Filament\Resources\CommentResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditComment extends EditRecord
{
protected static string $resource = CommentResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\CommentResource\Pages;
use App\Filament\Resources\CommentResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListComments extends ListRecords
{
protected static string $resource = CommentResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -3,11 +3,13 @@
namespace App\Filament\Resources;
use App\Filament\Resources\NewsResource\Pages;
use App\Filament\Resources\NewsResource\RelationManagers\CommentsRelationManager;
use App\Models\News;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
@@ -22,7 +24,7 @@ class NewsResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-newspaper';
protected static ?string $navigationGroup = 'CMS';
protected static ?string $navigationGroup = 'News';
public static function form(Form $form): Form
{
@@ -42,10 +44,16 @@ class NewsResource extends Resource
->dehydrated()
->unique(News::class, 'slug', ignoreRecord: true),
FileUpload::make('image')
->label('Image 1100x660')
->image()
->directory('news')
->nullable()
->columnSpanFull(),
Select::make('author_id')
->relationship('author', 'name')
->searchable()
->preload()
->required(),
RichEditor::make('content')
->required()
->columnSpanFull(),
@@ -70,6 +78,10 @@ class NewsResource extends Resource
Tables\Columns\TextColumn::make('slug')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('author.name')
->label('Author Name')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('published_at')
->dateTime()
->sortable(),
@@ -99,7 +111,7 @@ class NewsResource extends Resource
public static function getRelations(): array
{
return [
//
CommentsRelationManager::class,
];
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Filament\Resources\NewsResource\RelationManagers;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
class CommentsRelationManager extends RelationManager
{
protected static string $relationship = 'comments';
public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('title')
->required()
->maxLength(255),
RichEditor::make('message')
->required()
->columnSpanFull(),
TextInput::make('author_name')
->label('Author Name (Optional)')
->maxLength(255),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('title')
->columns([
Tables\Columns\TextColumn::make('title')
->searchable(),
Tables\Columns\TextColumn::make('author_name')
->label('Author')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
}

View File

@@ -0,0 +1,103 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\SolutionResource\Pages;
use App\Models\Solution;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Support\Str;
class SolutionResource extends Resource
{
protected static ?string $model = Solution::class;
protected static ?string $navigationIcon = 'heroicon-o-light-bulb';
protected static ?string $navigationGroup = 'Solutions';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->required()
->maxLength(255)
->reactive()
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
Forms\Components\TextInput::make('slug')
->required()
->maxLength(255),
Forms\Components\TextInput::make('title_description')
->maxLength(255)
->required()
->columnSpanFull(),
Forms\Components\Repeater::make('bullets')
->schema([
Forms\Components\TextInput::make('bullet')
->label('Bullet Point')
->required(),
])
->columns(1)
->columnSpanFull()
->createItemButtonLabel('Add Bullet Point')
->defaultItems(1),
Forms\Components\RichEditor::make('description')
->required()
->columnSpanFull(),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->searchable(),
Tables\Columns\TextColumn::make('slug')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSolutions::route('/'),
'create' => Pages\CreateSolution::route('/create'),
'edit' => Pages\EditSolution::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\SolutionResource\Pages;
use App\Filament\Resources\SolutionResource;
use Filament\Resources\Pages\CreateRecord;
class CreateSolution extends CreateRecord
{
protected static string $resource = SolutionResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\SolutionResource\Pages;
use App\Filament\Resources\SolutionResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditSolution extends EditRecord
{
protected static string $resource = SolutionResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\SolutionResource\Pages;
use App\Filament\Resources\SolutionResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListSolutions extends ListRecords
{
protected static string $resource = SolutionResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,116 @@
<?php
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;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Table;
use Illuminate\Support\Str;
class SuccessResource extends Resource
{
protected static ?string $model = Success::class;
protected static ?string $navigationIcon = 'heroicon-o-bookmark-square';
protected static ?string $navigationGroup = 'Success Stories';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Card::make()
->schema([
TextInput::make('title')
->required()
->maxLength(255)
->reactive()
->afterStateUpdated(fn (string $operation, $state, Forms\Set $set) => $operation === 'create' ? $set('slug', Str::slug($state)) : null),
TextInput::make('slug')
->required()
->maxLength(255)
->disabled()
->dehydrated()
->unique(Success::class, 'slug', ignoreRecord: true),
FileUpload::make('image')
->label('Image 1100x660')
->image()
->directory('success')
->nullable()
->columnSpanFull(),
RichEditor::make('content')
->required()
->columnSpanFull(),
DateTimePicker::make('published_at')
->required()
->default(now()),
])
->columns(2),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
ImageColumn::make('image')
->square()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('title')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('slug')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('published_at')
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSuccesses::route('/'),
'create' => Pages\CreateSuccess::route('/create'),
'edit' => Pages\EditSuccess::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\SuccessResource\Pages;
use App\Filament\Resources\SuccessResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateSuccess extends CreateRecord
{
protected static string $resource = SuccessResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\SuccessResource\Pages;
use App\Filament\Resources\SuccessResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditSuccess extends EditRecord
{
protected static string $resource = SuccessResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\SuccessResource\Pages;
use App\Filament\Resources\SuccessResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListSuccesses extends ListRecords
{
protected static string $resource = SuccessResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Application;
class ApplicationController extends Controller
{
public function store(Request $request)
{
$validatedData = $request->validate([
'career_id' => 'required|exists:careers,id',
'name' => 'required|string|max:255',
'birthdate' => 'required|date',
'resume_file' => 'required|file|mimes:pdf,doc,docx|max:2048',
'email' => 'required|email|max:255',
'phone_number' => 'required|string|max:20',
'cover_letter' => 'nullable|string',
]);
$resumePath = $request->file('resume_file')->store('resumes');
Application::create([
'career_id' => $validatedData['career_id'],
'name' => $validatedData['name'],
'birthdate' => $validatedData['birthdate'],
'resume_file' => $resumePath,
'email' => $validatedData['email'],
'phone_number' => $validatedData['phone_number'],
'cover_letter' => $validatedData['cover_letter'] ?? null,
]);
return back()->with('success', 'Your application has been submitted successfully!');
}
}

View File

@@ -9,12 +9,9 @@ class CareersPageController extends Controller
{
public function index()
{
return view('web.pages.careers.index');
}
$careers = Career::query()->get();
public function store(Request $request)
{
dd($request->all());
return view('web.pages.careers.index', compact('careers'));
}
public function show(Career $career)

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Models\Brand;
use App\Models\News;
use App\Settings\HomeSettings;
class HomePageController extends Controller
@@ -11,7 +12,8 @@ class HomePageController extends Controller
{
$brands = Brand::query()->get(['id', 'image']);
$homeSettings = app(HomeSettings::class);
$allNews = News::query()->latest()->take(3)->get();
return view('web.pages.home.index', compact('homeSettings', 'brands'));
return view('web.pages.home.index', compact('homeSettings', 'brands', 'allNews'));
}
}

View File

@@ -3,18 +3,35 @@
namespace App\Http\Controllers;
use App\Models\News;
use Illuminate\Http\Request;
class NewsPageController extends Controller
{
public function index()
{
$allNews = News::all();
$allNews = News::query()->with('author')->latest()->get();
return view('web.pages.news.index', compact('allNews'));
}
public function show(News $news)
public function show($news)
{
return view('web.pages.news.show', compact('news'));
$news = News::where('slug', $news)->with('author', 'comments')->first();
$recentNews = News::query()->with('author')->latest()->limit(3)->get();
return view('web.pages.news.show', compact('news', 'recentNews'));
}
public function storeComment(Request $request, News $news)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'message' => 'required|string',
'author_name' => 'nullable|string|max:255',
]);
$news->comments()->create($validated);
return back()->with('success', 'Comment added successfully!');
}
}

View File

@@ -8,7 +8,9 @@ class OurSolutionPageController extends Controller
{
public function index()
{
return view('web.pages.our-solutions.index');
$solutions = Solution::query()->latest()->get();
return view('web.pages.our-solutions.index', compact('solutions'));
}
public function show(Solution $solution)

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Success;
use Illuminate\Http\Request;
class SuccessPageController extends Controller
{
public function index()
{
$allSuccesses = Success::query()->latest()->get();
return view('web.pages.success.index', compact('allSuccesses'));
}
public function show($success)
{
$success = Success::where('slug', $success)->firstOrFail();
$recentSuccesses = Success::query()->latest()->limit(3)->get();
return view('web.pages.success.show', compact('success', 'recentSuccesses'));
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Career;
class Application extends Model
{
protected $fillable = [
'career_id',
'name',
'birthdate',
'resume_file',
'email',
'phone_number',
'cover_letter',
];
public function career(): BelongsTo
{
return $this->belongsTo(Career::class);
}
}

23
app/Models/Author.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Author extends Model
{
use HasFactory;
protected $fillable = [
'name',
'description',
'profile_image',
];
public function news(): HasMany
{
return $this->hasMany(News::class);
}
}

View File

@@ -3,13 +3,25 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Application;
class Career extends Model
{
protected $fillable = [
'title',
'description',
'title_description',
'salary_per_month',
'bullets',
'location',
'salary',
];
protected $casts = [
'bullets' => 'array',
];
public function applications(): HasMany
{
return $this->hasMany(Application::class);
}
}

24
app/Models/Comment.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Comment extends Model
{
use HasFactory;
protected $fillable = [
'title',
'message',
'author_name',
'news_id',
];
public function news(): BelongsTo
{
return $this->belongsTo(News::class);
}
}

View File

@@ -4,6 +4,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class News extends Model
{
@@ -15,5 +17,16 @@ class News extends Model
'content',
'image',
'published_at',
'author_id',
];
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}
}

View File

@@ -13,5 +13,11 @@ class Solution extends Model
'title',
'description',
'slug',
'title_description',
'bullets',
];
protected $casts = [
'bullets' => 'array',
];
}

19
app/Models/Success.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Success extends Model
{
use HasFactory;
protected $fillable = [
'title',
'slug',
'content',
'image',
'published_at',
];
}

View File

@@ -2,6 +2,7 @@
namespace App\Providers;
use App\Models\Solution;
use App\Settings\SiteSettings;
use App\Settings\SiteSocialSettings;
use Illuminate\Database\Eloquent\Model;
@@ -27,6 +28,7 @@ class AppServiceProvider extends ServiceProvider
Model::unguard();
$this->addSettingsToViews();
$this->addSolutionsToViews();
// logDB();
}
@@ -41,4 +43,14 @@ class AppServiceProvider extends ServiceProvider
$view->with('socialMedia', app(SiteSocialSettings::class));
});
}
/**
* Add solutions to views
*/
public function addSolutionsToViews(): void
{
ViewFacade::composer(['web.layouts.navigation.header'], function (View $view) {
$view->with('solutions', Solution::query()->latest()->get());
});
}
}

View File

@@ -2,8 +2,9 @@
namespace App\Providers\Filament;
use App\Filament\Pages\HomePageSettings;
use App\Filament\Pages\ManageCtaSettings;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
@@ -15,6 +16,7 @@ use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
@@ -34,6 +36,8 @@ class PanelPanelProvider extends PanelProvider
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
Pages\Dashboard::class,
HomePageSettings::class,
ManageCtaSettings::class,
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Settings;
use Spatie\LaravelSettings\Settings;
class CtaSettings extends Settings
{
public string $title;
public string $button_text;
public string $button_url;
public string $background_image;
public static function group(): string
{
return 'cta';
}
}

View File

@@ -55,6 +55,10 @@
"@php artisan migrate --graceful --ansi"
],
"dev": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
],
"network": [
"Composer\\Config::disableProcessTimeout",
"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve --host=0.0.0.0\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite"
],

View File

@@ -13,12 +13,13 @@ class NewsFactory extends Factory
public function definition()
{
$title = $this->faker->sentence(6);
return [
'title' => $title,
'slug' => Str::slug($title),
'content' => $this->faker->paragraphs(3, true),
'image' => 'news/' . $this->faker->image('public/storage/news', 640, 480, null, false),
'image' => 'news/'.$this->faker->image('public/storage/news', 640, 480, null, false),
'published_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
];
}
}
}

View File

@@ -13,6 +13,9 @@ return new class extends Migration
{
Schema::create('solutions', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->string('slug')->unique();
$table->timestamps();
});
}

View File

@@ -14,9 +14,10 @@ return new class extends Migration
Schema::create('careers', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->text('title_description')->nullable();
$table->string('salary_per_month')->nullable();
$table->json('bullets')->nullable();
$table->string('location');
$table->string('salary')->nullable();
$table->timestamps();
});
}

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('news', function (Blueprint $table) {
$table->string('author')->after('image')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('news', function (Blueprint $table) {
$table->dropColumn('author');
});
}
};

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('comments', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('message');
$table->string('author_name')->nullable();
$table->foreignId('news_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('comments');
}
};

View File

@@ -0,0 +1,14 @@
<?php
use Spatie\LaravelSettings\Migrations\SettingsMigration;
return new class extends SettingsMigration
{
public function up(): void
{
$this->migrator->add('cta.title', 'Join Our Community and Access Exclusive Insights Today');
$this->migrator->add('cta.button_text', 'Free Consultation');
$this->migrator->add('cta.button_url', 'request-quote.html');
$this->migrator->add('cta.background_image', '');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('solutions', function (Blueprint $table) {
$table->string('title_description')->nullable()->after('description');
$table->json('bullets')->nullable()->after('title_description');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('solutions', function (Blueprint $table) {
$table->dropColumn(['title_description', 'bullets']);
});
}
};

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('news', function (Blueprint $table) {
$table->longText('author_description')->nullable()->after('author');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('news', function (Blueprint $table) {
$table->dropColumn('author_description');
});
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->longText('description')->nullable();
$table->string('profile_image')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('authors');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('news', function (Blueprint $table) {
$table->foreignId('author_id')->nullable()->constrained()->onDelete('set null');
$table->dropColumn('author');
$table->dropColumn('author_description');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('news', function (Blueprint $table) {
$table->dropForeign(['author_id']);
$table->dropColumn('author_id');
$table->string('author')->nullable();
$table->string('author_description')->nullable();
});
}
};

View File

@@ -0,0 +1,32 @@
<?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('successes', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->longText('content');
$table->string('image')->nullable();
$table->timestamp('published_at');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('successes');
}
};

View File

@@ -0,0 +1,34 @@
<?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('applications', function (Blueprint $table) {
$table->id();
$table->foreignId('career_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->date('birthdate');
$table->string('resume_file');
$table->string('email');
$table->string('phone_number');
$table->text('cover_letter')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('applications');
}
};

View File

@@ -2,9 +2,8 @@
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\News;
use Illuminate\Database\Seeder;
class NewsTableSeeder extends Seeder
{
@@ -13,6 +12,8 @@ class NewsTableSeeder extends Seeder
*/
public function run(): void
{
News::factory()->count(12)->create();
News::factory()->count(12)->create([
'image' => '/web/assets/img/page/breadcrumb.jpg',
]);
}
}
}

View File

@@ -5538,7 +5538,7 @@ p {
}
.price__area-item.active .price__area-item-price h3,
.price__area-item.active .price__area-item-price h2 {
color: var(--color-1);
color: var(--text-white);
}
.price__area-item.active .price__area-item-list {
border-color: #DDB348;
@@ -6695,7 +6695,7 @@ p {
margin: 3px 3px 3px 3px;
}
.gallery__area-button button.active {
color: var(--color-1);
color: var(--text-white);
background: var(--primary-color-1);
border-color: var(--primary-color-1);
}

View File

@@ -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('story.index') }}">{{ __('Success stories') }}</a></li>
<li><a href="{{ route('success.index') }}">{{ __('Success stories') }}</a></li>
</ul>
</div>
</div>

View File

@@ -20,19 +20,16 @@
<li class="menu-item-has-children"><a href="{{ route('our-solutions.index') }}">{{ __('Our solutions') }}</a>
<ul class="sub-menu">
<li><a href="history.html">Company History</a></li>
<li><a href="testimonial.html">Testimonials</a></li>
<li><a href="pricing.html">Price Plans</a></li>
<li><a href="faq.html">FAQ's</a></li>
<li><a href="request-quote.html">Request Quote</a></li>
<li><a href="404-error.html">404 Page</a></li>
@foreach($solutions as $solution)
<li><a href="{{ route('our-solutions.show', $solution->slug) }}">{{ $solution->title }}</a></li>
@endforeach
</ul>
</li>
<li class="menu-item-has-children"><a href="#">{{ __('News & Stories') }}</a>
<ul class="sub-menu">
<li><a href="{{ route('news.index') }}">{{ __('News') }}</a></li>
<li><a href="{{ route('story.index') }}">{{ __('Success Stories') }}</a></li>
<li><a href="{{ route('success.index') }}">{{ __('Success Stories') }}</a></li>
</ul>
</li>

View File

@@ -0,0 +1,170 @@
@extends('web.layouts.app')
@push('header-css')
<style>
#applicationForm > label > span {
color: var(--gujurly-primary);
}
</style>
@endpush
@section('content')
<!-- 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>Careers</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Careers</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Pricing Plan Area Start -->
<div class="price__area section-padding">
<div class="container">
<div class="row">
<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 }}<span>/Per monthly</span></h2>
</div>
<div class="price__area-item-list">
<ul>
@foreach($career->bullets as $bullet)
<li><i class="flaticon-checked"></i>{{ $bullet['bullet'] ?? '' }}</li>
@endforeach
</ul>
</div>
<div class="price__area-item-btn">
<button type="button" class="build_button apply-now-button" data-bs-toggle="modal" data-bs-target="#applicationModal" data-career-title="{{ $career->title }}" data-career-location="{{ $career->location }}" data-career-salary="{{ $career->salary_per_month }}" data-career-description="{{ $career->title_description }}" data-career-id="{{ $career->id }}">Apply Now<i class="flaticon-right-up"></i></button>
</div>
</div>
@empty
<span>No careers found...</span>
@endforelse
</div>
</div>
</div>
</div>
<!-- Pricing Plan Area End -->
<!-- Application Modal -->
<div class="modal fade" id="applicationModal" tabindex="-1" aria-labelledby="applicationModalLabel" aria-hidden="true">
<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>
</div>
<div class="modal-body">
<h6 id="jobLocation"></h6>
<p id="jobSalary"></p>
<p id="jobDescription"></p>
<form id="applicationForm" enctype="multipart/form-data" action="{{ route('applications.store') }}" method="POST">
@csrf
<input type="hidden" name="career_id" id="careerId">
<div class="row">
<div class="col-md-6 mb-3">
<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</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</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</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)</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>
<textarea class="form-control" id="cover_letter" name="cover_letter" rows="5"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit Application</button>
</form>
</div>
</div>
</div>
</div>
@endsection
@push('footer-js')
<script>
document.addEventListener('DOMContentLoaded', function () {
var applicationModal = document.getElementById('applicationModal');
applicationModal.addEventListener('show.bs.modal', function (event) {
var button = event.relatedTarget;
var careerTitle = button.getAttribute('data-career-title');
var careerLocation = button.getAttribute('data-career-location');
var careerSalary = button.getAttribute('data-career-salary');
var careerDescription = button.getAttribute('data-career-description');
var careerId = button.getAttribute('data-career-id');
var modalTitle = applicationModal.querySelector('#jobTitle');
var modalLocation = applicationModal.querySelector('#jobLocation');
var modalSalary = applicationModal.querySelector('#jobSalary');
var modalDescription = applicationModal.querySelector('#jobDescription');
var modalCareerId = applicationModal.querySelector('#careerId');
modalTitle.textContent = careerTitle;
modalLocation.textContent = 'Location: ' + careerLocation;
modalSalary.textContent = 'Salary: ' + careerSalary + ' / Per monthly';
modalDescription.textContent = careerDescription;
modalCareerId.value = careerId;
});
// Handle form submission with AJAX
document.getElementById('applicationForm').addEventListener('submit', function (e) {
e.preventDefault();
let form = e.target;
let formData = new FormData(form);
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert(data.message);
var modal = bootstrap.Modal.getInstance(applicationModal);
modal.hide();
form.reset();
} else {
alert('Error: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred. Please try again.');
});
});
});
</script>
@endpush

View File

@@ -3,6 +3,7 @@
@inject('solutionSettings', 'App\Settings\SolutionSettings')
@inject('successSettings', 'App\Settings\SuccessSettings')
@inject('portfolioSettings', 'App\Settings\PortfolioSettings')
@inject('ctaSettings', 'App\Settings\CtaSettings')
@section('content')
<!-- Banner Area Start -->
@@ -315,71 +316,33 @@
<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">Update News & Blogs</h2>
<h2 class="title_split_anim">News</h2>
</div>
</div>
</div>
<div class="row">
@foreach($allNews as $news)
<div class="col-xl-4 col-md-6 mt-25 wow fadeInUp" data-wow-delay=".4s">
<div class="blog__four-item">
<div class="blog__four-item-image">
<a href="blog-details.html"><img src="/web/assets/img/blog/blog-1.jpg" alt="image"></a>
<a href="{{ route('news.show', $news->slug) }}"><img src="/storage/{{ $news->image }}" alt="image"></a>
<div class="blog__four-item-image-date">
<h5>22</h5>
<h6>Dec</h6>
<h5>{{ \Carbon\Carbon::parse($news->published_at)->format('d') }}</h5>
<h6>{{ \Carbon\Carbon::parse($news->published_at)->format('M') }}</h6>
</div>
</div>
<div class="blog__four-item-content">
<div class="meta">
<ul>
<li><a href="#"><i class="far fa-user"></i>By-Admin</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>Comments (3)</a></li>
<li><a href="#"><i class="far fa-user"></i>{{ $news->author }}</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>Comments ({{ $news->comments->count() }})</a></li>
</ul>
</div>
<h4><a href="blog-details.html">How Weather Can Impact a Construction Project</a></h4>
</div>
</div>
</div>
<div class="col-xl-4 col-md-6 mt-25 wow fadeInUp" data-wow-delay=".7s">
<div class="blog__four-item">
<div class="blog__four-item-image">
<a href="blog-details.html"><img src="/web/assets/img/blog/blog-2.jpg" alt="image"></a>
<div class="blog__four-item-image-date">
<h5>19</h5>
<h6>Dec</h6>
</div>
</div>
<div class="blog__four-item-content">
<div class="meta">
<ul>
<li><a href="#"><i class="far fa-user"></i>By-Admin</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>Comments (3)</a></li>
</ul>
</div>
<h4><a href="blog-details.html">How to Choose the Perfect Construction Company</a></h4>
</div>
</div>
</div>
<div class="col-xl-4 col-md-6 mt-25 wow fadeInUp" data-wow-delay="1s">
<div class="blog__four-item">
<div class="blog__four-item-image">
<a href="blog-details.html"><img src="/web/assets/img/blog/blog-3.jpg" alt="image"></a>
<div class="blog__four-item-image-date">
<h5>14</h5>
<h6>Dec</h6>
</div>
</div>
<div class="blog__four-item-content">
<div class="meta">
<ul>
<li><a href="#"><i class="far fa-user"></i>By-Admin</a></li>
<li><a href="#"><i class="far fa-comment-dots"></i>Comments (3)</a></li>
</ul>
</div>
<h4><a href="blog-details.html">Top Mistakes to Avoid During Home Renovation</a></h4>
<h4><a href="{{ route('news.show', $news->slug) }}">{{ $news->title }}</a></h4>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
@@ -390,11 +353,11 @@
<div class="container">
<div class="row jc-center">
<div class="col-xl-12">
<div class="cta__four-area t-center" style="background-image: url('/web/assets/img/page/subscribe.jpg');">
<div class="cta__four-area t-center" style="background-image: url('/storage/{{ $ctaSettings->background_image }}');">
<div class="cta__four-area-content">
<h2 class="title_split_anim">Join Our Community and Access Exclusive Insights Today</h2>
<h2 class="title_split_anim">{{ $ctaSettings->title }}</h2>
<div class="item_bounce">
<a class="build_button mt-40" href="request-quote.html">Free Consultation<i class="flaticon-right-up"></i></a>
<a class="build_button mt-40" href="{{ $ctaSettings->button_url }}">{{ $ctaSettings->button_text }}<i class="flaticon-right-up"></i></a>
</div>
</div>
</div>

View File

@@ -2,15 +2,15 @@
@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>Blog 3 Columns</h2>
<h2>News</h2>
<ul>
<li><a href="index.html">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Blog 3 Columns</li>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>News</li>
</ul>
</div>
</div>
@@ -39,19 +39,6 @@
</div>
@endforeach
</div>
<div class="row mt-25">
<div class="col-xl-12">
<div class="theme__pagination t-center">
<ul>
<li><a class="active" href="#">01</a></li>
<li><a href="#">02</a></li>
<li><a href="#"><i class="far fa-ellipsis-h"></i></a></li>
<li><a href="#">05</a></li>
<li><a href="#"><i class="fa-regular fa-angle-right"></i></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Blog Area End -->

View File

@@ -0,0 +1,120 @@
@extends('web.layouts.app')
@section('content')
<!-- 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>{{ $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>{{ $news->title }}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Blog Details Area Start -->
<div class="blog__details section-padding">
<div class="container">
<div class="row">
<div class="col-lg-8 lg-mb-25">
<div class="blog__details-area">
<img src="/storage/{{ $news->image }}" alt="image">
<h3 class="mt-25 mb-20">{{ $news->title }}</h3>
<p>{{ $news->description }}</p>
<div class="blog__details-area-author">
<div class="blog__details-area-author-image">
<img src="{{ $news->author->profile_image ?? '/web/assets/img/team/member-1.jpg' }}" alt="avatar">
</div>
<div class="blog__details-area-author-content">
<h5>{{ $news->author->name ?? 'Admin' }}</h5>
<p>{{ $news->description ?? 'Super Admin' }}</p>
</div>
</div>
<div class="blog__details-area-comment mt-40">
<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">
<div class="blog__details-area-comment-item-comment-image">
<img src="/web/assets/img/team/member-5.jpg" alt="avatar-image">
</div>
<div class="blog__details-area-comment-item-comment-content">
<h5>{{ $comment->title ?? '-' }}</h5>
<span>Submitted {{ $comment->created_at->diffForHumans() }} by {{ $comment->author_name ?? 'Anonymous' }}</span>
<p>{{ $comment->message }}</p>
</div>
</div>
</div>
@empty
<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>
<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">
</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">
</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>
<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>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="col-lg-4 columns_sticky">
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Recent Blog</h4>
<div class="all__sidebar-item-post dark_image">
@foreach($recentNews as $news)
<div class="post__item">
<div class="post__item-image">
<a href="{{ route('news.show', $news->slug) }}"><img src="/storage/{{ $news->image }}" alt="post-image"></a>
</div>
<div class="post__item-title">
<h6><a href="{{ route('news.show', $news->slug) }}">{{ $news->title }}</a></h6>
<span><i class="far fa-calendar-alt"></i>{{ \Carbon\Carbon::parse($news->published_at)->format('d M Y') }}</span>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Blog Details Area End -->
@endsection

View File

@@ -0,0 +1,51 @@
@extends('web.layouts.app')
@section('content')
<!-- 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>Our Solutions</h2>
<ul>
<li><a href="index.html">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Our Solutions</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Pricing Plan Area Start -->
<div class="price__area section-padding">
<div class="container">
<div class="row">
<div class="col-xl-4 col-md-6 xl-mb-25 wow fadeInUp" data-wow-delay=".4s">
@foreach($solutions as $solution)
<div class="price__area-item">
<div class="price__area-item-price">
<span>{{ $solution->title_description }}</span>
<h3>{{ $solution->title }}</h3>
</div>
<div class="price__area-item-list">
<ul>
@foreach($solution->bullets as $bullet)
@isset($bullet['bullet'])
<li><i class="flaticon-checked"></i>{{ $bullet['bullet'] }}</li>
@endisset
@endforeach
</ul>
</div>
<div class="price__area-item-btn">
<a class="build_button" href="{{ route('our-solutions.show', $solution->slug) }}">Read More<i class="flaticon-right-up"></i></a>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
<!-- Pricing Plan Area End -->
@endsection

View File

@@ -0,0 +1,104 @@
@extends('web.layouts.app')
@section('content')
<!-- Breadcrumb Area Start -->
<div class="breadcrumb__area" style="background-image: url('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>Services Details</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Services Details Area Start -->
<div class="services__details section-padding">
<div class="container">
<div class="row">
<div class="col-lg-4">
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Our Solutions</h4>
<div class="all__sidebar-item-category">
<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>
</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 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>
<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>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Services Details Area End -->
@endsection

View File

@@ -0,0 +1,45 @@
@extends('web.layouts.app')
@section('content')
<!-- 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>Success Stories</h2>
<ul>
<li><a href="/">Home</a><i class="fa-regular fa-angle-right"></i></li>
<li>Success Stories</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Blog Area Start -->
<div class="blog-three__columns section-padding-three">
<div class="container">
<div class="row">
@foreach ($allSuccesses as $success)
<div class="col-xl-4 col-lg-6 wow fadeInUp" data-wow-delay=".4s">
<div class="blog__one-item">
<div class="blog__one-item-image">
<a href="{{ route('success.show', $success->slug) }}"><img src="/storage/{{ $success->image }}" alt="image"></a>
<div class="blog__one-item-image-date">
<h6><i class="fa-regular fa-calendar"></i>{{ \Carbon\Carbon::parse($success->published_at)->format('d M') }}</h6>
</div>
</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>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
<!-- Blog Area End -->
@endsection

View File

@@ -0,0 +1,59 @@
@extends('web.layouts.app')
@section('content')
<!-- 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>{{ $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>{{ $success->title }}</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Breadcrumb Area End -->
<!-- Blog Details Area Start -->
<div class="blog__details section-padding">
<div class="container">
<div class="row">
<div class="col-lg-8 lg-mb-25">
<div class="blog__details-area">
<img src="/storage/{{ $success->image }}" alt="image">
<h3 class="mt-25 mb-20">{{ $success->title }}</h3>
<p>{!! $success->content !!}</p>
</div>
</div>
<div class="col-lg-4 columns_sticky">
<div class="all__sidebar">
<div class="all__sidebar-item">
<h4>Recent Success Stories</h4>
<div class="all__sidebar-item-post dark_image">
@foreach($recentSuccesses as $success)
<div class="post__item">
<div class="post__item-image">
<a href="{{ route('success.show', $success->slug) }}"><img src="/storage/{{ $success->image }}" alt="post-image"></a>
</div>
<div class="post__item-title">
<h6><a href="{{ route('success.show', $success->slug) }}">{{ $success->title }}</a></h6>
<span><i class="far fa-calendar-alt"></i>{{ \Carbon\Carbon::parse($success->published_at)->format('d M Y') }}</span>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Blog Details Area End -->
@endsection

View File

@@ -9,6 +9,8 @@ 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;
// Homepage...
@@ -24,15 +26,16 @@ Route::get('our-solutiouns/{solution:slug}', [OurSolutionPageController::class,
// News...
Route::get('news', [NewsPageController::class, 'index'])->name('news.index');
Route::get('news/{news:slug}', [NewsPageController::class, 'show'])->name('news.show');
Route::post('news/{news:slug}/comments', [NewsPageController::class, 'storeComment'])->name('comments.store');
// Success stories...
Route::get('stories', [StoryPageController::class, 'index'])->name('story.index');
Route::get('stories/{story:slug}', [StoryPageController::class, 'show'])->name('story.show');
Route::get('success-stories', [SuccessPageController::class, 'index'])->name('success.index');
Route::get('success-stories/{success:slug}', [SuccessPageController::class, 'show'])->name('success.show');
// Careers...
Route::get('careers', [CareersPageController::class, 'index'])->name('career.index');
Route::get('careers/{career:slug}', [CareersPageController::class, 'show'])->name('career.show');
Route::post('careers', [CareersPageController::class, 'store'])->name('career.store');
Route::post('applications', [ApplicationController::class, 'store'])->name('applications.store');
// Internships...
Route::get('internships', [InternshipsPageController::class, 'index'])->name('internship.index');