Merge pull request #32 from truncgil/technical-debt-and-performance
Technical debt and performance
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications;
|
||||
|
||||
use App\Filament\Admin\Resources\CareerApplications\Pages\CreateCareerApplication;
|
||||
use App\Filament\Admin\Resources\CareerApplications\Pages\EditCareerApplication;
|
||||
use App\Filament\Admin\Resources\CareerApplications\Pages\ListCareerApplications;
|
||||
use App\Filament\Admin\Resources\CareerApplications\Schemas\CareerApplicationForm;
|
||||
use App\Filament\Admin\Resources\CareerApplications\Tables\CareerApplicationsTable;
|
||||
use App\Models\CareerApplication;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class CareerApplicationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = CareerApplication::class;
|
||||
|
||||
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-user-group';
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('career.navigation_label');
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('career.model_label');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('career.plural_model_label');
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return CareerApplicationForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return CareerApplicationsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListCareerApplications::route('/'),
|
||||
'create' => CreateCareerApplication::route('/create'),
|
||||
'edit' => EditCareerApplication::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\CareerApplications\CareerApplicationResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateCareerApplication extends CreateRecord
|
||||
{
|
||||
protected static string $resource = CareerApplicationResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\CareerApplications\CareerApplicationResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditCareerApplication extends EditRecord
|
||||
{
|
||||
protected static string $resource = CareerApplicationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\CareerApplications\CareerApplicationResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListCareerApplications extends ListRecords
|
||||
{
|
||||
protected static string $resource = CareerApplicationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications\Schemas;
|
||||
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class CareerApplicationForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label(__('career.name'))
|
||||
->required()
|
||||
->disabled(),
|
||||
|
||||
TextInput::make('email')
|
||||
->label(__('career.email'))
|
||||
->email()
|
||||
->required()
|
||||
->disabled(),
|
||||
|
||||
TextInput::make('phone')
|
||||
->label(__('career.phone'))
|
||||
->disabled(),
|
||||
|
||||
FileUpload::make('cv_path')
|
||||
->label(__('career.cv'))
|
||||
->disk('public')
|
||||
->directory('cvs')
|
||||
->required()
|
||||
->disabled(),
|
||||
|
||||
Textarea::make('message')
|
||||
->label(__('career.message'))
|
||||
->disabled()
|
||||
->columnSpanFull(),
|
||||
|
||||
Select::make('status')
|
||||
->label(__('career.status'))
|
||||
->options([
|
||||
'pending' => 'Pending',
|
||||
'reviewed' => 'Reviewed',
|
||||
'rejected' => 'Rejected',
|
||||
'accepted' => 'Accepted',
|
||||
])
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\CareerApplications\Tables;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class CareerApplicationsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label(__('career.name'))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('email')
|
||||
->label(__('career.email'))
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('phone')
|
||||
->label(__('career.phone'))
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label(__('career.status'))
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'pending' => 'gray',
|
||||
'reviewed' => 'info',
|
||||
'rejected' => 'danger',
|
||||
'accepted' => 'success',
|
||||
default => 'gray',
|
||||
}),
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->label(__('career.created_at'))
|
||||
->dateTime('d.m.Y H:i')
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('status')
|
||||
->label(__('career.status'))
|
||||
->options([
|
||||
'pending' => 'Pending',
|
||||
'reviewed' => 'Reviewed',
|
||||
'rejected' => 'Rejected',
|
||||
'accepted' => 'Accepted',
|
||||
]),
|
||||
])
|
||||
->actions([
|
||||
Action::make('download_cv')
|
||||
->label(__('career.download_cv'))
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->url(fn ($record) => Storage::disk('public')->url($record->cv_path))
|
||||
->openUrlInNewTab(),
|
||||
DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
])
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -106,9 +106,19 @@ class BlogController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
// Kategorileri al (filtreleme için)
|
||||
$categories = class_exists(\App\Models\BlogCategory::class) ? \App\Models\BlogCategory::where('is_active', true)->orderBy('sort_order')->get() : collect();
|
||||
|
||||
if ($request->ajax()) {
|
||||
return view('blog.partials.posts', [
|
||||
'posts' => $posts
|
||||
]);
|
||||
}
|
||||
|
||||
return view('blog.index', [
|
||||
'settings' => $settings,
|
||||
'posts' => $posts,
|
||||
'categories' => $categories,
|
||||
'renderedHeader' => $renderedHeader,
|
||||
'renderedFooter' => $renderedFooter,
|
||||
'meta' => [
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CareerApplication;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class CareerController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('front.career.index', [
|
||||
'meta' => [
|
||||
'title' => __('career.title', ['default' => 'Kariyer']),
|
||||
'description' => __('career.description', ['default' => 'Ekibimize katılmak için aşağıdaki formu doldurarak CV\'nizi iletebilirsiniz.']),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|email|max:255',
|
||||
'phone' => 'nullable|string|max:20',
|
||||
'cv' => 'required|file|mimes:pdf,doc,docx|max:5120', // Max 5MB
|
||||
'message' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$cvPath = null;
|
||||
if ($request->hasFile('cv')) {
|
||||
$cvPath = $request->file('cv')->store('cvs', 'public');
|
||||
}
|
||||
|
||||
CareerApplication::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'phone' => $request->phone,
|
||||
'cv_path' => $cvPath,
|
||||
'message' => $request->message,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', __('career.success_message'));
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ class ProductController extends Controller
|
||||
$meta = [
|
||||
'title' => $product->translate('title'),
|
||||
'description' => \Str::limit(strip_tags($product->translate('content')), 160),
|
||||
'image' => $product->hero_image ? asset('storage/' . $product->hero_image) : null,
|
||||
];
|
||||
|
||||
// Use custom view template if specified
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Page;
|
||||
use App\Models\Blog;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class SitemapController extends Controller
|
||||
{
|
||||
public function index(): Response
|
||||
{
|
||||
$urls = [];
|
||||
|
||||
// 1. Static & Main Pages
|
||||
$urls[] = [
|
||||
'loc' => url('/'),
|
||||
'lastmod' => now()->startOfDay()->toAtomString(),
|
||||
'changefreq' => 'daily',
|
||||
'priority' => '1.0',
|
||||
];
|
||||
|
||||
$urls[] = [
|
||||
'loc' => route('blog.index'),
|
||||
'lastmod' => now()->startOfDay()->toAtomString(),
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.8',
|
||||
];
|
||||
|
||||
$urls[] = [
|
||||
'loc' => route('career.index'),
|
||||
'lastmod' => now()->startOfMonth()->toAtomString(),
|
||||
'changefreq' => 'monthly',
|
||||
'priority' => '0.5',
|
||||
];
|
||||
|
||||
// 2. Dynamic Pages
|
||||
$pages = Page::where('status', 'published')
|
||||
->where('is_homepage', false)
|
||||
->get();
|
||||
foreach ($pages as $page) {
|
||||
$urls[] = [
|
||||
'loc' => url($page->slug),
|
||||
'lastmod' => $page->updated_at->toAtomString(),
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.7',
|
||||
];
|
||||
}
|
||||
|
||||
// 3. Blog Posts
|
||||
if (class_exists(Blog::class)) {
|
||||
$posts = Blog::published()->get();
|
||||
foreach ($posts as $post) {
|
||||
$urls[] = [
|
||||
'loc' => route('blog.show', $post->slug),
|
||||
'lastmod' => $post->updated_at->toAtomString(),
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.6',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Products
|
||||
if (class_exists(Product::class)) {
|
||||
$products = Product::where('is_active', true)->get();
|
||||
foreach ($products as $product) {
|
||||
$urls[] = [
|
||||
'loc' => route('products.show', $product->slug),
|
||||
'lastmod' => $product->updated_at->toAtomString(),
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.7',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return response()->view('sitemap', compact('urls'))
|
||||
->header('Content-Type', 'text/xml');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CareerApplication extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'phone',
|
||||
'cv_path',
|
||||
'message',
|
||||
'status',
|
||||
];
|
||||
}
|
||||
@@ -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::create('career_applications', function (Blueprint $blueprint) {
|
||||
$blueprint->id();
|
||||
$blueprint->string('name');
|
||||
$blueprint->string('email');
|
||||
$blueprint->string('phone')->nullable();
|
||||
$blueprint->string('cv_path');
|
||||
$blueprint->text('message')->nullable();
|
||||
$blueprint->string('status')->default('pending'); // pending, reviewed, rejected, accepted
|
||||
$blueprint->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('career_applications');
|
||||
}
|
||||
};
|
||||
@@ -659,6 +659,16 @@ class SettingSeeder extends Seeder
|
||||
'is_public' => false,
|
||||
'is_active' => true,
|
||||
],
|
||||
[
|
||||
'key' => 'seo_google_search_console',
|
||||
'value' => '',
|
||||
'type' => 'string',
|
||||
'group' => 'seo',
|
||||
'label' => 'Google Search Console',
|
||||
'description' => 'Google Search Console doğrulama kodu',
|
||||
'is_public' => false,
|
||||
'is_active' => true,
|
||||
],
|
||||
[
|
||||
'key' => 'seo_google_tag_manager_id',
|
||||
'value' => '',
|
||||
|
||||
@@ -104,4 +104,5 @@ return [
|
||||
'submit' => 'Submit',
|
||||
'comment_submitted' => 'Your comment has been submitted. It will be published after approval.',
|
||||
'comments_disabled' => 'Comments are disabled for this blog post.',
|
||||
'all_categories' => 'All Categories',
|
||||
];
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'navigation_label' => 'Career Applications',
|
||||
'model_label' => 'Application',
|
||||
'plural_model_label' => 'Career Applications',
|
||||
'title' => 'Career Form',
|
||||
'description' => 'To join our team, please fill out the form below and upload your CV.',
|
||||
'name' => 'Full Name',
|
||||
'email' => 'Email',
|
||||
'phone' => 'Phone',
|
||||
'cv' => 'Curriculum Vitae (CV)',
|
||||
'message' => 'Message',
|
||||
'status' => 'Status',
|
||||
'submit' => 'Submit Application',
|
||||
'success_message' => 'Your application has been received successfully. Thank you.',
|
||||
'download_cv' => 'Download CV',
|
||||
'created_at' => 'Application Date',
|
||||
];
|
||||
@@ -104,4 +104,5 @@ return [
|
||||
'submit' => 'Gönder',
|
||||
'comment_submitted' => 'Yorumunuz gönderildi. Onaylandıktan sonra yayınlanacaktır.',
|
||||
'comments_disabled' => 'Bu blog yazısında yorumlar devre dışı bırakılmıştır.',
|
||||
'all_categories' => 'Tüm Kategoriler',
|
||||
];
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'navigation_label' => 'Kariyer Başvuruları',
|
||||
'model_label' => 'Başvuru',
|
||||
'plural_model_label' => 'Kariyer Başvuruları',
|
||||
'title' => 'Kariyer Formu',
|
||||
'description' => 'Ekibimize katılmak için aşağıdaki formu doldurarak CV\'nizi iletebilirsiniz.',
|
||||
'name' => 'Ad Soyad',
|
||||
'email' => 'E-posta',
|
||||
'phone' => 'Telefon',
|
||||
'cv' => 'Özgeçmiş (CV)',
|
||||
'message' => 'Mesaj',
|
||||
'status' => 'Durum',
|
||||
'submit' => 'Başvuruyu Gönder',
|
||||
'success_message' => 'Başvurunuz başarıyla alındı. Teşekkür ederiz.',
|
||||
'download_cv' => 'CV İndir',
|
||||
'created_at' => 'Başvuru Tarihi',
|
||||
];
|
||||
@@ -21,172 +21,23 @@
|
||||
<div class="container !pb-[4.5rem] xl:!pb-24 lg:!pb-24 md:!pb-24">
|
||||
<div class="flex flex-wrap mx-[-15px]">
|
||||
<div class="xl:w-10/12 lg:w-10/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto">
|
||||
<div class="blog classic-view !mt-[-7rem]">
|
||||
@forelse($posts as $index => $post)
|
||||
@php
|
||||
$title = method_exists($post, 'translate') ? $post->translate('title') : $post->title;
|
||||
$excerpt = method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '');
|
||||
$categoryName = $post->category ? $post->category->name : '';
|
||||
$categorySlug = $post->category ? $post->category->slug : '';
|
||||
$publishedDate = $post->published_at ? $post->published_at->format('d M Y') : $post->created_at->format('d M Y');
|
||||
$imageUrl = $post->featured_image ? asset('storage/' . $post->featured_image) : asset('assets/img/photos/b1.webp');
|
||||
$blogUrl = route('blog.show', $post->slug);
|
||||
$commentCount = $post->comments_count ?? 0;
|
||||
$authorName = $post->author ? $post->author->name : '';
|
||||
@endphp
|
||||
|
||||
@if($index < 3)
|
||||
{{-- İlk 3 blog yazısı classic-view formatında --}}
|
||||
<article class="post !mb-8">
|
||||
<div class="card">
|
||||
@if($post->featured_image_url)
|
||||
<figure class="card-img-top overlay overlay-1 hover-scale group">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">
|
||||
<img class="!transition-all !duration-[0.35s] !ease-in-out group-hover:scale-105" src="{{ $imageUrl }}" alt="{{ $title }}" loading="lazy">
|
||||
</a>
|
||||
<figcaption class="group-hover:opacity-100 absolute w-full h-full opacity-0 text-center px-4 py-3 inset-0 z-[5] pointer-events-none p-2">
|
||||
<h5 class="from-top !mb-0 absolute w-full translate-y-[-80%] p-[.75rem_1rem] left-0 top-2/4">{{ __('blog.read_more') }}</h5>
|
||||
</figcaption>
|
||||
</figure>
|
||||
@endif
|
||||
<div class="card-body flex-[1_1_auto] p-[40px] xl:!p-[2rem_2.5rem_1.25rem] lg:!p-[2rem_2.5rem_1.25rem] md:!p-[2rem_2.5rem_1.25rem] max-md:pb-4">
|
||||
<div class="post-header !mb-[.9rem]">
|
||||
@if($categoryName)
|
||||
<div class="inline-flex !mb-[.4rem] uppercase !tracking-[0.02rem] text-[0.7rem] font-bold !text-[#aab0bc] relative align-top !pl-[1.4rem] before:content-[''] before:absolute before:inline-block before:translate-y-[-60%] before:w-3 before:h-[0.05rem] before:left-0 before:top-2/4 before:bg-[#e31e24]">
|
||||
<a href="{{ route('blog.index', ['category' => $categorySlug]) }}" class="hover" rel="category">{{ $categoryName }}</a>
|
||||
</div>
|
||||
@endif
|
||||
<!-- /.post-category -->
|
||||
<h2 class="post-title !mt-1 !leading-[1.35] !mb-0">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">{{ $title }}</a>
|
||||
</h2>
|
||||
</div>
|
||||
<!-- /.post-header -->
|
||||
<div class="!relative">
|
||||
<p>{{ $excerpt }}</p>
|
||||
</div>
|
||||
<!-- /.post-content -->
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
<div class="card-footer xl:!p-[1.25rem_2.5rem_1.25rem] lg:!p-[1.25rem_2.5rem_1.25rem] md:!p-[1.25rem_2.5rem_1.25rem] p-[18px_40px]">
|
||||
<ul class="!text-[0.7rem] !text-[#aab0bc] m-0 p-0 list-none flex !mb-0">
|
||||
<li class="post-date inline-block">
|
||||
<i class="uil uil-calendar-alt pr-[0.2rem] align-[-.05rem] before:content-['\e9ba']"></i>
|
||||
<span>{{ $publishedDate }}</span>
|
||||
</li>
|
||||
@if($authorName)
|
||||
<li class="post-author inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ route('blog.index', ['author' => $post->author_id]) }}">
|
||||
<i class="uil uil-user pr-[0.2rem] align-[-.05rem] before:content-['\ed6f']"></i>
|
||||
<span>{{ __('blog.by') }} {{ $authorName }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if($post->allow_comments)
|
||||
<li class="post-comments inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ $blogUrl }}#comments">
|
||||
<i class="uil uil-comment pr-[0.2rem] align-[-.05rem] before:content-['\ea54']"></i>
|
||||
<span>{{ $commentCount }} {{ __('blog.comments') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
<!-- /.post-meta -->
|
||||
</div>
|
||||
<!-- /.card-footer -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</article>
|
||||
<!-- /.post -->
|
||||
@endif
|
||||
@empty
|
||||
<div class="text-center py-12">
|
||||
<p class="text-[#aab0bc]">{{ __('blog.empty') }}</p>
|
||||
</div>
|
||||
@endforelse
|
||||
<!-- Category Filter -->
|
||||
@if(isset($categories) && $categories->count() > 0)
|
||||
<div class="flex flex-wrap justify-center !mb-10 gap-2 blog-filter-menu">
|
||||
<a href="#" class="category-filter-btn active !text-[0.8rem] !font-bold !uppercase !tracking-[0.02rem] !px-4 !py-2 !rounded-full !border !border-[#e31e24] !bg-[#e31e24] !text-white hover:!bg-[#c8191f] hover:!border-[#c8191f] transition-colors" data-category="">
|
||||
{{ __('blog.all_categories', ['default' => 'Tümü']) }}
|
||||
</a>
|
||||
@foreach($categories as $category)
|
||||
<a href="#" class="category-filter-btn !text-[0.8rem] !font-bold !uppercase !tracking-[0.02rem] !px-4 !py-2 !rounded-full !border !border-[#eef2f6] !bg-[#eef2f6] !text-[#343f52] hover:!bg-[#e31e24] hover:!text-white hover:!border-[#e31e24] transition-colors" data-category="{{ $category->slug }}">
|
||||
{{ $category->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
<!-- /.blog -->
|
||||
|
||||
@if($posts->count() > 3)
|
||||
<div class="blog itemgrid grid-view">
|
||||
<div class="flex flex-wrap mx-[-15px] isotope xl:mx-[-20px] lg:mx-[-20px] md:mx-[-20px] !mt-[-40px] !mb-8">
|
||||
@foreach($posts as $index => $post)
|
||||
@if($index >= 3)
|
||||
@php
|
||||
$title = method_exists($post, 'translate') ? $post->translate('title') : $post->title;
|
||||
$excerpt = method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '');
|
||||
$categoryName = $post->category ? $post->category->name : '';
|
||||
$categorySlug = $post->category ? $post->category->slug : '';
|
||||
$publishedDate = $post->published_at ? $post->published_at->format('d M Y') : $post->created_at->format('d M Y');
|
||||
$imageUrl = $post->featured_image ? asset('storage/' . $post->featured_image) : asset('assets/img/photos/b4.webp');
|
||||
$blogUrl = route('blog.show', $post->slug);
|
||||
$commentCount = $post->comments_count ?? 0;
|
||||
@endphp
|
||||
|
||||
<article class="item post xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] xl:!px-[20px] lg:!px-[20px] md:!px-[20px] !mt-[40px] !px-[15px] max-w-full">
|
||||
<div class="card">
|
||||
<figure class="card-img-top overlay overlay-1 hover-scale group">
|
||||
<a href="{{ $blogUrl }}">
|
||||
<img class="!transition-all !duration-[0.35s] !ease-in-out group-hover:scale-105" src="{{ $imageUrl }}" alt="{{ $title }}" loading="lazy">
|
||||
</a>
|
||||
<figcaption class="group-hover:opacity-100 absolute w-full h-full opacity-0 text-center px-4 py-3 inset-0 z-[5] pointer-events-none p-2">
|
||||
<h5 class="from-top !mb-0 absolute w-full translate-y-[-80%] p-[.75rem_1rem] left-0 top-2/4">{{ __('blog.read_more') }}</h5>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<div class="card-body flex-[1_1_auto] p-[40px] xl:!p-[1.75rem_1.75rem_1rem_1.75rem] lg:!p-[1.75rem_1.75rem_1rem_1.75rem] md:!p-[1.75rem_1.75rem_1rem_1.75rem] max-md:pb-4">
|
||||
<div class="post-header !mb-[.9rem]">
|
||||
@if($categoryName)
|
||||
<div class="inline-flex !mb-[.4rem] uppercase !tracking-[0.02rem] text-[0.7rem] font-bold !text-[#aab0bc] relative align-top !pl-[1.4rem] before:content-[''] before:absolute before:inline-block before:translate-y-[-60%] before:w-3 before:h-[0.05rem] before:left-0 before:top-2/4 before:bg-[#e31e24]">
|
||||
<a href="{{ route('blog.index', ['category' => $categorySlug]) }}" class="hover" rel="category">{{ $categoryName }}</a>
|
||||
</div>
|
||||
@endif
|
||||
<!-- /.post-category -->
|
||||
<h2 class="post-title h3 !mt-1 !mb-3">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">{{ $title }}</a>
|
||||
</h2>
|
||||
</div>
|
||||
<!-- /.post-header -->
|
||||
<div class="!relative">
|
||||
<p>{{ \Illuminate\Support\Str::limit($excerpt, 120) }}</p>
|
||||
</div>
|
||||
<!-- /.post-content -->
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
<div class="card-footer xl:!p-[1.25rem_1.75rem_1.25rem] lg:!p-[1.25rem_1.75rem_1.25rem] md:!p-[1.25rem_1.75rem_1.25rem] p-[18px_40px]">
|
||||
<ul class="!text-[0.7rem] !text-[#aab0bc] m-0 p-0 list-none flex !mb-0">
|
||||
<li class="post-date inline-block">
|
||||
<i class="uil uil-calendar-alt pr-[0.2rem] align-[-.05rem] before:content-['\e9ba']"></i>
|
||||
<span>{{ $publishedDate }}</span>
|
||||
</li>
|
||||
@if($post->allow_comments)
|
||||
<li class="post-comments inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ $blogUrl }}#comments">
|
||||
<i class="uil uil-comment pr-[0.2rem] align-[-.05rem] before:content-['\ea54']"></i>{{ $commentCount }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
<!-- /.post-meta -->
|
||||
</div>
|
||||
<!-- /.card-footer -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</article>
|
||||
<!-- /.post -->
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
<!-- /.isotope -->
|
||||
</div>
|
||||
<!-- /.blog itemgrid -->
|
||||
@endif
|
||||
|
||||
{{-- Pagination --}}
|
||||
@if(method_exists($posts, 'links') && $posts->hasPages())
|
||||
<div class="mt-8">
|
||||
{{ $posts->links() }}
|
||||
</div>
|
||||
@endif
|
||||
<div id="blog-posts-container" class="relative min-h-[400px]">
|
||||
@include('blog.partials.posts')
|
||||
</div>
|
||||
</div>
|
||||
<!-- /column -->
|
||||
</div>
|
||||
@@ -194,4 +45,179 @@
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</div>
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* Loading Overlay for AJAX Requests */
|
||||
.blog-loading-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding-top: 5rem;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.blog-loading-overlay.active {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
.blog-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #e31e24;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const container = document.getElementById('blog-posts-container');
|
||||
const filterBtns = document.querySelectorAll('.category-filter-btn');
|
||||
|
||||
// Create loading overlay
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'blog-loading-overlay';
|
||||
overlay.innerHTML = '<div class="blog-spinner"></div>';
|
||||
container.appendChild(overlay);
|
||||
|
||||
function fetchPosts(url) {
|
||||
overlay.classList.add('active');
|
||||
container.style.minHeight = container.offsetHeight + 'px'; // Maintain height during load
|
||||
|
||||
// Add AJAX header
|
||||
fetch(url, {
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Accept': 'text/html'
|
||||
}
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
// Update the posts container with new HTML
|
||||
container.innerHTML = html;
|
||||
// Re-append the overlay so it's ready for the next request
|
||||
container.appendChild(overlay);
|
||||
|
||||
// Re-bind pagination links
|
||||
bindPaginationLinks();
|
||||
|
||||
// Reinitialize any necessary plugins here (e.g. tooltips or image loaders if any)
|
||||
|
||||
// Update URL and History
|
||||
window.history.pushState({html: html}, '', url);
|
||||
|
||||
// Smooth scroll to top of blog section
|
||||
document.querySelector('.blog-filter-menu').scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
|
||||
setTimeout(() => {
|
||||
overlay.classList.remove('active');
|
||||
container.style.minHeight = 'auto'; // Reset min-height safely
|
||||
}, 300);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching posts:', error);
|
||||
overlay.classList.remove('active');
|
||||
});
|
||||
}
|
||||
|
||||
function bindPaginationLinks() {
|
||||
const paginationLinks = container.querySelectorAll('.pagination-container a, .pagination a');
|
||||
paginationLinks.forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
fetchPosts(this.href);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Bind Filter Buttons
|
||||
filterBtns.forEach(btn => {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Update active state
|
||||
filterBtns.forEach(b => {
|
||||
b.classList.remove('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
b.classList.add('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
});
|
||||
this.classList.remove('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
this.classList.add('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
|
||||
const category = this.getAttribute('data-category');
|
||||
|
||||
// Construct URL
|
||||
const url = new URL(window.location.href);
|
||||
if (category) {
|
||||
url.searchParams.set('category', category);
|
||||
} else {
|
||||
url.searchParams.delete('category');
|
||||
}
|
||||
// Reset to page 1 on category change
|
||||
url.searchParams.delete('page');
|
||||
|
||||
fetchPosts(url.toString());
|
||||
});
|
||||
});
|
||||
|
||||
// Handle browser back/forward buttons
|
||||
window.addEventListener('popstate', function(e) {
|
||||
if (e.state && e.state.html) {
|
||||
container.innerHTML = e.state.html;
|
||||
container.appendChild(overlay);
|
||||
bindPaginationLinks();
|
||||
|
||||
// Update active filter button based on URL
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const currentCategory = urlParams.get('category') || '';
|
||||
|
||||
filterBtns.forEach(b => {
|
||||
b.classList.remove('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
b.classList.add('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
if (b.getAttribute('data-category') === currentCategory) {
|
||||
b.classList.remove('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
b.classList.add('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Fallback for full page reload for history items without state
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
// Initial binding of pagination links that are on page load
|
||||
bindPaginationLinks();
|
||||
|
||||
// Set initial active state based on URL
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const initialCategory = urlParams.get('category') || '';
|
||||
if (initialCategory) {
|
||||
const activeBtn = Array.from(filterBtns).find(btn => btn.getAttribute('data-category') === initialCategory);
|
||||
if (activeBtn) {
|
||||
filterBtns.forEach(b => {
|
||||
b.classList.remove('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
b.classList.add('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
});
|
||||
activeBtn.classList.remove('!text-[#343f52]', '!bg-[#eef2f6]', '!border-[#eef2f6]');
|
||||
activeBtn.classList.add('!text-white', '!bg-[#e31e24]', '!border-[#e31e24]');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<div class="blog classic-view !mt-[-7rem]">
|
||||
@forelse($posts as $index => $post)
|
||||
@php
|
||||
$title = method_exists($post, 'translate') ? $post->translate('title') : $post->title;
|
||||
$excerpt = method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '');
|
||||
$categoryName = $post->category ? $post->category->name : '';
|
||||
$categorySlug = $post->category ? $post->category->slug : '';
|
||||
$publishedDate = $post->published_at ? $post->published_at->format('d M Y') : $post->created_at->format('d M Y');
|
||||
$imageUrl = $post->featured_image ? asset('storage/' . $post->featured_image) : asset('assets/img/photos/b1.webp');
|
||||
$blogUrl = route('blog.show', $post->slug);
|
||||
$commentCount = $post->comments_count ?? 0;
|
||||
$authorName = $post->author ? $post->author->name : '';
|
||||
@endphp
|
||||
|
||||
@if($index < 3)
|
||||
{{-- İlk 3 blog yazısı classic-view formatında --}}
|
||||
<article class="post !mb-8">
|
||||
<div class="card">
|
||||
@if($post->featured_image_url)
|
||||
<figure class="card-img-top overlay overlay-1 hover-scale group">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">
|
||||
<img class="!transition-all !duration-[0.35s] !ease-in-out group-hover:scale-105" src="{{ $imageUrl }}" alt="{{ $title }}" loading="lazy">
|
||||
</a>
|
||||
<figcaption class="group-hover:opacity-100 absolute w-full h-full opacity-0 text-center px-4 py-3 inset-0 z-[5] pointer-events-none p-2">
|
||||
<h5 class="from-top !mb-0 absolute w-full translate-y-[-80%] p-[.75rem_1rem] left-0 top-2/4">{{ __('blog.read_more') }}</h5>
|
||||
</figcaption>
|
||||
</figure>
|
||||
@endif
|
||||
<div class="card-body flex-[1_1_auto] p-[40px] xl:!p-[2rem_2.5rem_1.25rem] lg:!p-[2rem_2.5rem_1.25rem] md:!p-[2rem_2.5rem_1.25rem] max-md:pb-4">
|
||||
<div class="post-header !mb-[.9rem]">
|
||||
@if($categoryName)
|
||||
<div class="inline-flex !mb-[.4rem] uppercase !tracking-[0.02rem] text-[0.7rem] font-bold !text-[#aab0bc] relative align-top !pl-[1.4rem] before:content-[''] before:absolute before:inline-block before:translate-y-[-60%] before:w-3 before:h-[0.05rem] before:left-0 before:top-2/4 before:bg-[#e31e24]">
|
||||
<a href="{{ route('blog.index', ['category' => $categorySlug]) }}" class="hover category-link" data-category="{{ $categorySlug }}" rel="category">{{ $categoryName }}</a>
|
||||
</div>
|
||||
@endif
|
||||
<!-- /.post-category -->
|
||||
<h2 class="post-title !mt-1 !leading-[1.35] !mb-0">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">{{ $title }}</a>
|
||||
</h2>
|
||||
</div>
|
||||
<!-- /.post-header -->
|
||||
<div class="!relative">
|
||||
<p>{{ $excerpt }}</p>
|
||||
</div>
|
||||
<!-- /.post-content -->
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
<div class="card-footer xl:!p-[1.25rem_2.5rem_1.25rem] lg:!p-[1.25rem_2.5rem_1.25rem] md:!p-[1.25rem_2.5rem_1.25rem] p-[18px_40px]">
|
||||
<ul class="!text-[0.7rem] !text-[#aab0bc] m-0 p-0 list-none flex !mb-0">
|
||||
<li class="post-date inline-block">
|
||||
<i class="uil uil-calendar-alt pr-[0.2rem] align-[-.05rem] before:content-['\e9ba']"></i>
|
||||
<span>{{ $publishedDate }}</span>
|
||||
</li>
|
||||
@if($authorName)
|
||||
<li class="post-author inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ route('blog.index', ['author' => $post->author_id]) }}">
|
||||
<i class="uil uil-user pr-[0.2rem] align-[-.05rem] before:content-['\ed6f']"></i>
|
||||
<span>{{ __('blog.by') }} {{ $authorName }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if($post->allow_comments)
|
||||
<li class="post-comments inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ $blogUrl }}#comments">
|
||||
<i class="uil uil-comment pr-[0.2rem] align-[-.05rem] before:content-['\ea54']"></i>
|
||||
<span>{{ $commentCount }} {{ __('blog.comments') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
<!-- /.post-meta -->
|
||||
</div>
|
||||
<!-- /.card-footer -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</article>
|
||||
<!-- /.post -->
|
||||
@endif
|
||||
@empty
|
||||
<div class="text-center py-12">
|
||||
<p class="text-[#aab0bc]">{{ __('blog.empty') }}</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<!-- /.blog -->
|
||||
|
||||
@if($posts->count() > 3)
|
||||
<div class="blog itemgrid grid-view">
|
||||
<div class="flex flex-wrap mx-[-15px] isotope xl:mx-[-20px] lg:mx-[-20px] md:mx-[-20px] !mt-[-40px] !mb-8">
|
||||
@foreach($posts as $index => $post)
|
||||
@if($index >= 3)
|
||||
@php
|
||||
$title = method_exists($post, 'translate') ? $post->translate('title') : $post->title;
|
||||
$excerpt = method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '');
|
||||
$categoryName = $post->category ? $post->category->name : '';
|
||||
$categorySlug = $post->category ? $post->category->slug : '';
|
||||
$publishedDate = $post->published_at ? $post->published_at->format('d M Y') : $post->created_at->format('d M Y');
|
||||
$imageUrl = $post->featured_image ? asset('storage/' . $post->featured_image) : asset('assets/img/photos/b4.webp');
|
||||
$blogUrl = route('blog.show', $post->slug);
|
||||
$commentCount = $post->comments_count ?? 0;
|
||||
@endphp
|
||||
|
||||
<article class="item post xl:w-6/12 lg:w-6/12 md:w-6/12 w-full flex-[0_0_auto] xl:!px-[20px] lg:!px-[20px] md:!px-[20px] !mt-[40px] !px-[15px] max-w-full">
|
||||
<div class="card">
|
||||
<figure class="card-img-top overlay overlay-1 hover-scale group">
|
||||
<a href="{{ $blogUrl }}">
|
||||
<img class="!transition-all !duration-[0.35s] !ease-in-out group-hover:scale-105" src="{{ $imageUrl }}" alt="{{ $title }}" loading="lazy">
|
||||
</a>
|
||||
<figcaption class="group-hover:opacity-100 absolute w-full h-full opacity-0 text-center px-4 py-3 inset-0 z-[5] pointer-events-none p-2">
|
||||
<h5 class="from-top !mb-0 absolute w-full translate-y-[-80%] p-[.75rem_1rem] left-0 top-2/4">{{ __('blog.read_more') }}</h5>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<div class="card-body flex-[1_1_auto] p-[40px] xl:!p-[1.75rem_1.75rem_1rem_1.75rem] lg:!p-[1.75rem_1.75rem_1rem_1.75rem] md:!p-[1.75rem_1.75rem_1rem_1.75rem] max-md:pb-4">
|
||||
<div class="post-header !mb-[.9rem]">
|
||||
@if($categoryName)
|
||||
<div class="inline-flex !mb-[.4rem] uppercase !tracking-[0.02rem] text-[0.7rem] font-bold !text-[#aab0bc] relative align-top !pl-[1.4rem] before:content-[''] before:absolute before:inline-block before:translate-y-[-60%] before:w-3 before:h-[0.05rem] before:left-0 before:top-2/4 before:bg-[#e31e24]">
|
||||
<a href="{{ route('blog.index', ['category' => $categorySlug]) }}" class="hover category-link" data-category="{{ $categorySlug }}" rel="category">{{ $categoryName }}</a>
|
||||
</div>
|
||||
@endif
|
||||
<!-- /.post-category -->
|
||||
<h2 class="post-title h3 !mt-1 !mb-3">
|
||||
<a class="!text-[#343f52] hover:!text-[#e31e24]" href="{{ $blogUrl }}">{{ $title }}</a>
|
||||
</h2>
|
||||
</div>
|
||||
<!-- /.post-header -->
|
||||
<div class="!relative">
|
||||
<p>{{ \Illuminate\Support\Str::limit($excerpt, 120) }}</p>
|
||||
</div>
|
||||
<!-- /.post-content -->
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
<div class="card-footer xl:!p-[1.25rem_1.75rem_1.25rem] lg:!p-[1.25rem_1.75rem_1.25rem] md:!p-[1.25rem_1.75rem_1.25rem] p-[18px_40px]">
|
||||
<ul class="!text-[0.7rem] !text-[#aab0bc] m-0 p-0 list-none flex !mb-0">
|
||||
<li class="post-date inline-block">
|
||||
<i class="uil uil-calendar-alt pr-[0.2rem] align-[-.05rem] before:content-['\e9ba']"></i>
|
||||
<span>{{ $publishedDate }}</span>
|
||||
</li>
|
||||
@if($post->allow_comments)
|
||||
<li class="post-comments inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
|
||||
<a class="!text-[#aab0bc] hover:!text-[#e31e24] hover:!border-[#e31e24]" href="{{ $blogUrl }}#comments">
|
||||
<i class="uil uil-comment pr-[0.2rem] align-[-.05rem] before:content-['\ea54']"></i>{{ $commentCount }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
<!-- /.post-meta -->
|
||||
</div>
|
||||
<!-- /.card-footer -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</article>
|
||||
<!-- /.post -->
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
<!-- /.isotope -->
|
||||
</div>
|
||||
<!-- /.blog itemgrid -->
|
||||
@endif
|
||||
|
||||
{{-- Pagination --}}
|
||||
@if(method_exists($posts, 'links') && $posts->hasPages())
|
||||
<div class="mt-8 pagination-container">
|
||||
{{ $posts->links() }}
|
||||
</div>
|
||||
@endif
|
||||
@@ -405,4 +405,34 @@
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</section>
|
||||
|
||||
@push('scripts')
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"mainEntityOfPage": {
|
||||
"@type": "WebPage",
|
||||
"@id": "{{ route('blog.show', $post->slug) }}"
|
||||
},
|
||||
"headline": "{{ method_exists($post, 'translate') ? $post->translate('title') : $post->title }}",
|
||||
"description": "{{ method_exists($post, 'translate') ? $post->translate('excerpt') : ($post->excerpt ?? '') }}",
|
||||
"image": "{{ $post->featured_image_url ? $post->featured_image_url : asset('assets/img/logo.png') }}",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "{{ $post->author->name ?? 'Trunçgil Teknoloji Editörü' }}"
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "{{ setting('site_name', 'Trunçgil Teknoloji') }}",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "{{ asset('storage/' . setting('site_logo')) }}"
|
||||
}
|
||||
},
|
||||
"datePublished": "{{ $post->published_at ? $post->published_at->toIso8601String() : $post->created_at->toIso8601String() }}",
|
||||
"dateModified": "{{ $post->updated_at->toIso8601String() }}"
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
|
||||
@@ -140,3 +140,54 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* Smoother Offcanvas Menu Transition */
|
||||
.offcanvas {
|
||||
transition: transform 0.4s cubic-bezier(0.77, 0.2, 0.05, 1.0) !important;
|
||||
}
|
||||
.offcanvas-backdrop {
|
||||
transition: opacity 0.4s ease !important;
|
||||
}
|
||||
|
||||
/* Fluid Hamburger Animation */
|
||||
.hamburger {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.hamburger span,
|
||||
.hamburger::before,
|
||||
.hamburger::after {
|
||||
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55) !important;
|
||||
}
|
||||
.hamburger.is-active span {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.hamburger.is-active::before {
|
||||
transform: translateY(6px) rotate(45deg) !important;
|
||||
}
|
||||
.hamburger.is-active::after {
|
||||
transform: translateY(-6px) rotate(-45deg) !important;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var offcanvases = document.querySelectorAll('.offcanvas-nav');
|
||||
var hamburgers = document.querySelectorAll('.hamburger.offcanvas-nav-btn');
|
||||
|
||||
if (offcanvases.length > 0 && hamburgers.length > 0) {
|
||||
offcanvases.forEach(function(oc) {
|
||||
oc.addEventListener('show.bs.offcanvas', function () {
|
||||
hamburgers.forEach(function(h) { h.classList.add('is-active'); });
|
||||
});
|
||||
oc.addEventListener('hide.bs.offcanvas', function () {
|
||||
hamburgers.forEach(function(h) { h.classList.remove('is-active'); });
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
@extends('layouts.site')
|
||||
|
||||
@section('content')
|
||||
<section class="wrapper bg-soft-primary">
|
||||
<div class="container pt-15 pb-0 pt-md-20 pb-md-0 text-center">
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-lg-10 mx-auto">
|
||||
<h1 class="display-1 mb-3 text-dark">{{ __('career.title', ['default' => 'Kariyer']) }}</h1>
|
||||
<p class="lead mb-0 text-muted">{{ __('career.description', ['default' => 'Ekibimize katılmak için aşağıdaki formu doldurarak CV\'nizi iletebilirsiniz.']) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="wrapper bg-light">
|
||||
<div class="container pt-5 pb-14 pb-md-16">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 col-xl-9 col-xxl-8 mx-auto">
|
||||
<div class="card shadow-xl border-0 rounded-4">
|
||||
<div class="card-body p-8 p-md-12">
|
||||
<div class="row mb-10 text-center text-md-start">
|
||||
<div class="col-12">
|
||||
<h2 class="h3 mb-2 text-dark">Başvuru Formu</h2>
|
||||
<div class="divider-citrus"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success mt-4 mb-10 border-0 shadow-sm rounded-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="uil uil-check-circle fs-24 me-3 text-success"></i>
|
||||
<div class="fw-medium text-success">{{ session('success') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
trackEvent('career_form_success', {form_name: 'career_application'});
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('career.store') }}" method="POST" enctype="multipart/form-data" class="career-form">
|
||||
@csrf
|
||||
|
||||
<!-- Personal Info Group -->
|
||||
<div class="row mb-8 align-items-center">
|
||||
<label for="name" class="col-md-3 col-form-label fw-bold text-md-end text-dark mb-2 mb-md-0">{{ __('career.name', ['default' => 'Ad Soyad']) }} <span class="text-citrus">*</span></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" name="name" id="name" class="form-control custom-input @error('name') is-invalid @enderror" placeholder="Örn: Ahmet Yılmaz" value="{{ old('name') }}" required>
|
||||
@error('name') <div class="invalid-feedback text-start">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-8 align-items-center">
|
||||
<label for="email" class="col-md-3 col-form-label fw-bold text-md-end text-dark mb-2 mb-md-0">{{ __('career.email', ['default' => 'E-posta']) }} <span class="text-citrus">*</span></label>
|
||||
<div class="col-md-9">
|
||||
<input type="email" name="email" id="email" class="form-control custom-input @error('email') is-invalid @enderror" placeholder="Örn: ahmet@example.com" value="{{ old('email') }}" required>
|
||||
@error('email') <div class="invalid-feedback text-start">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-8 align-items-center">
|
||||
<label for="phone" class="col-md-3 col-form-label fw-bold text-md-end text-dark mb-2 mb-md-0">{{ __('career.phone', ['default' => 'Telefon']) }}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" name="phone" id="phone" class="form-control custom-input @error('phone') is-invalid @enderror" placeholder="Örn: 05XX XXX XX XX" value="{{ old('phone') }}">
|
||||
@error('phone') <div class="invalid-feedback text-start">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-8 align-items-center">
|
||||
<label for="cv" class="col-md-3 col-form-label fw-bold text-md-end text-dark mb-2 mb-md-0">{{ __('career.cv', ['default' => 'Özgeçmiş (CV)']) }} <span class="text-citrus">*</span></label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<input type="file" name="cv" id="cv" class="form-control custom-input @error('cv') is-invalid @enderror" required>
|
||||
</div>
|
||||
<div class="form-text text-start text-muted mt-2">PDF, DOC, DOCX dosyaları kabul edilir. (Maks. 5MB)</div>
|
||||
@error('cv') <div class="invalid-feedback d-block text-start">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-10">
|
||||
<label for="message" class="col-md-3 col-form-label fw-bold text-md-end text-dark mb-2 mb-md-0 pt-md-3">{{ __('career.message', ['default' => 'Mesajınız']) }}</label>
|
||||
<div class="col-md-9">
|
||||
<textarea name="message" id="message" class="form-control custom-input @error('message') is-invalid @enderror" placeholder="Başvurunuzla ilgili iletmek istediklerinizi yazabilirsiniz..." style="height: 180px">{{ old('message') }}</textarea>
|
||||
@error('message') <div class="invalid-feedback text-start">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-9 offset-md-3 text-center text-md-start">
|
||||
<button type="submit" class="btn btn-citrus btn-lg rounded-pill px-12 transition-all shadow-citrus" onclick="trackEvent('career_form_submit_attempt', {form_name: 'career_application'})">
|
||||
{{ __('career.submit', ['default' => 'Başvuruyu Gönder']) }}
|
||||
<i class="uil uil-arrow-right ms-2 fs-20"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--/.card-body -->
|
||||
</div>
|
||||
<!--/.card -->
|
||||
</div>
|
||||
<!-- /column -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</section>
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
:root {
|
||||
--citrus-red: #e31e24;
|
||||
--citrus-red-soft: rgba(227, 30, 36, 0.05);
|
||||
--citrus-red-hover: #c4191f;
|
||||
}
|
||||
|
||||
.text-citrus { color: var(--citrus-red) !important; }
|
||||
.bg-citrus { background-color: var(--citrus-red) !important; }
|
||||
|
||||
.btn-citrus {
|
||||
color: #fff !important;
|
||||
background-color: var(--citrus-red) !important;
|
||||
border-color: var(--citrus-red) !important;
|
||||
}
|
||||
.btn-citrus:hover {
|
||||
background-color: var(--citrus-red-hover) !important;
|
||||
border-color: var(--citrus-red-hover) !important;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.shadow-citrus {
|
||||
box-shadow: 0 0.5rem 1.5rem rgba(227, 30, 36, 0.25) !important;
|
||||
}
|
||||
|
||||
.divider-citrus {
|
||||
width: 60px;
|
||||
height: 4px;
|
||||
background-color: var(--citrus-red);
|
||||
border-radius: 2px;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.divider-citrus { margin: 1.5rem auto; }
|
||||
}
|
||||
|
||||
.career-form .custom-input {
|
||||
border: 1px solid #dfe5ef;
|
||||
padding: 1rem 1.2rem;
|
||||
background-color: #f8fbff;
|
||||
border-radius: 0.75rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.career-form .custom-input:focus {
|
||||
border-color: var(--citrus-red);
|
||||
box-shadow: 0 0 0 0.25rem var(--citrus-red-soft);
|
||||
background-color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.career-form .custom-input::placeholder {
|
||||
color: #aeb6c2;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.bg-soft-primary {
|
||||
background: linear-gradient(135deg, #f0f7ff 0%, #e8f1ff 100%) !important;
|
||||
}
|
||||
|
||||
.shadow-xl {
|
||||
box-shadow: 0 1.5rem 4rem rgba(30, 41, 59, 0.1) !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@endpush
|
||||
@endsection
|
||||
@@ -8,8 +8,35 @@ $favicon_path = setting('site_favicon');
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ setting('seo_meta_title') }} - {{ $meta['title'] ?? ($settings->default_meta_title ?? config('app.name')) }}</title>
|
||||
<meta name="description" content="{{ $meta['description'] ?? (setting('seo_meta_description') ?? '') }}">
|
||||
@php
|
||||
$seo_title = ($meta['title'] ?? null) ? $meta['title'] . ' - ' . setting('site_name') : setting('seo_meta_title');
|
||||
$seo_description = $meta['description'] ?? setting('seo_meta_description');
|
||||
$seo_image = $meta['image'] ?? setting('default_meta_image');
|
||||
if ($seo_image && !str_starts_with($seo_image, 'http')) {
|
||||
$seo_image = asset($seo_image);
|
||||
}
|
||||
@endphp
|
||||
<title>{{ $seo_title }}</title>
|
||||
<meta name="description" content="{{ $seo_description }}">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{ url()->current() }}">
|
||||
<meta property="og:title" content="{{ $seo_title }}">
|
||||
<meta property="og:description" content="{{ $seo_description }}">
|
||||
@if($seo_image)
|
||||
<meta property="og:image" content="{{ $seo_image }}">
|
||||
@endif
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:url" content="{{ url()->current() }}">
|
||||
<meta name="twitter:title" content="{{ $seo_title }}">
|
||||
<meta name="twitter:description" content="{{ $seo_description }}">
|
||||
@if($seo_image)
|
||||
<meta name="twitter:image" content="{{ $seo_image }}">
|
||||
@endif
|
||||
|
||||
<link rel="icon" href="{{ asset('storage/' . $favicon_path) }}">
|
||||
<link rel="stylesheet" href="{{ asset('html/style.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('assets/fonts/unicons/unicons.css') }}">
|
||||
@@ -18,10 +45,36 @@ $favicon_path = setting('site_favicon');
|
||||
<link rel="preload" href="{{ asset('assets/css/fonts/urbanist.css') }}" as="style" onload="this.rel='stylesheet'">
|
||||
<link rel="preload" href="{{ asset('assets/css/fonts/space.css') }}" as="style" onload="this.rel='stylesheet'">
|
||||
|
||||
<!-- Site Verification -->
|
||||
@if(setting('seo_google_search_console'))
|
||||
<meta name="google-site-verification" content="{{ setting('seo_google_search_console') }}" />
|
||||
@endif
|
||||
@if(setting('seo_bing_webmaster'))
|
||||
<meta name="msvalidate.01" content="{{ setting('seo_bing_webmaster') }}" />
|
||||
@endif
|
||||
|
||||
<style>
|
||||
<?php echo setting('custom_css') ?>
|
||||
</style>
|
||||
|
||||
<!-- Google Analytics 4 (GA4) -->
|
||||
@if(setting('seo_google_analytics_id'))
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ setting('seo_google_analytics_id') }}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '{{ setting('seo_google_analytics_id') }}');
|
||||
|
||||
// Global Event Tracker Helper
|
||||
window.trackEvent = function(eventName, params = {}) {
|
||||
if (typeof gtag === 'function') {
|
||||
gtag('event', eventName, params);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@endif
|
||||
|
||||
@stack('styles')
|
||||
|
||||
</head>
|
||||
|
||||
@@ -29,13 +29,13 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
<!-- Mobile Header -->
|
||||
<div class="flex flex-row w-full justify-between items-center xl:!hidden lg:!hidden">
|
||||
<div class="navbar-brand"><a href="/">
|
||||
<img class="logo-dark" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="image" loading="lazy">
|
||||
<img class="logo-light" src="{{ asset('assets/img/truncgil-yatay-dark.svg') }}" alt="image" loading="lazy">
|
||||
<img class="logo-dark" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="Truncgil" fetchpriority="high" decoding="async">
|
||||
<img class="logo-light" src="{{ asset('assets/img/truncgil-yatay-dark.svg') }}" alt="Truncgil" fetchpriority="high" decoding="async">
|
||||
</a></div>
|
||||
<div class="navbar-other !ml-auto">
|
||||
<ul class="navbar-nav flex-row items-center">
|
||||
<li class="nav-item xl:!hidden lg:!hidden">
|
||||
<button class="hamburger offcanvas-nav-btn"><span></span></button>
|
||||
<li class="nav-item">
|
||||
<button class="hamburger offcanvas-nav-btn" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-nav"><span></span></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -45,10 +45,12 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
@if($isHomepage)
|
||||
<!-- Homepage Layout (Center Logo) -->
|
||||
<div class="navbar-collapse-wrapper flex flex-row items-center w-full">
|
||||
<div class="navbar-collapse offcanvas offcanvas-nav offcanvas-start">
|
||||
<div id="offcanvas-nav" class="navbar-collapse offcanvas offcanvas-nav offcanvas-start">
|
||||
<div class="offcanvas-header lg:mx-auto xl:mx-auto order-0 lg:!order-1 lg:!px-[5rem] xl:!order-1 xl:!px-[5rem] p-[1.5rem] !flex items-center justify-between flex-row">
|
||||
<a class="transition-none hidden lg:!flex xl:!flex" href="/"><img class="logo-dark" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="image" loading="lazy">
|
||||
<img class="logo-light" src="{{ asset('assets/img/truncgil-yatay-dark.svg') }}" alt="image" loading="lazy"></a>
|
||||
<a class="transition-none hidden lg:!flex xl:!flex" href="/" onclick="trackEvent('logo_click', {location: 'header_center'})">
|
||||
<img class="logo-dark" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="Truncgil" fetchpriority="high" decoding="async">
|
||||
<img class="logo-light" src="{{ asset('assets/img/truncgil-yatay-dark.svg') }}" alt="Truncgil" fetchpriority="high" decoding="async">
|
||||
</a>
|
||||
<div class="" style="position: relative; left:5px">
|
||||
@include("components.custom.language-selector")
|
||||
</div>
|
||||
@@ -91,13 +93,13 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
<!-- Logo on Left -->
|
||||
<div class="navbar-brand">
|
||||
<a href="/">
|
||||
<img class="!h-[2.5rem]" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="Truncgil Teknoloji" loading="lazy">
|
||||
<img class="!h-[2.5rem]" src="{{ asset('assets/img/truncgil-yatay.svg') }}" alt="Truncgil Teknoloji" fetchpriority="high" decoding="async">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Menu in Center -->
|
||||
<div class="navbar-collapse offcanvas offcanvas-nav offcanvas-start">
|
||||
<div class="offcanvas-body flex justify-center">
|
||||
<!-- Menu in Center (Desktop) -->
|
||||
<div class="navbar-collapse w-full flex justify-center">
|
||||
<div class="flex justify-center w-full">
|
||||
<ul class="navbar-nav flex-row items-center gap-1">
|
||||
@foreach($menuItems as $item)
|
||||
<x-front.menu-item :item="$item" />
|
||||
@@ -111,27 +113,27 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
<nav class="nav social flex items-center gap-2">
|
||||
<?php $social_media = json_decode(setting('social_links'), true); ?>
|
||||
@if(!empty($social_media['Twitter']))
|
||||
<a class="!text-[#5daed5] hover:!text-[#3b9ec9] text-[1.1rem] transition-colors" href="{{ $social_media['Twitter'] }}" target="_blank" rel="noopener">
|
||||
<a class="!text-[#5daed5] hover:!text-[#3b9ec9] text-[1.1rem] transition-colors" href="{{ $social_media['Twitter'] }}" target="_blank" rel="noopener" onclick="trackEvent('social_click', {platform: 'twitter'})">
|
||||
<i class="uil uil-twitter"></i>
|
||||
</a>
|
||||
@endif
|
||||
@if(!empty($social_media['Facebook']))
|
||||
<a class="!text-[#4470cf] hover:!text-[#3259b8] text-[1.1rem] transition-colors" href="{{ $social_media['Facebook'] }}" target="_blank" rel="noopener">
|
||||
<a class="!text-[#4470cf] hover:!text-[#3259b8] text-[1.1rem] transition-colors" href="{{ $social_media['Facebook'] }}" target="_blank" rel="noopener" onclick="trackEvent('social_click', {platform: 'facebook'})">
|
||||
<i class="uil uil-facebook-f"></i>
|
||||
</a>
|
||||
@endif
|
||||
@if(!empty($social_media['Github']))
|
||||
<a class="!text-[#343a40] hover:!text-[#23272b] text-[1.1rem] transition-colors" href="{{ $social_media['Github'] }}" target="_blank" rel="noopener">
|
||||
<a class="!text-[#343a40] hover:!text-[#23272b] text-[1.1rem] transition-colors" href="{{ $social_media['Github'] }}" target="_blank" rel="noopener" onclick="trackEvent('social_click', {platform: 'github'})">
|
||||
<i class="uil uil-github"></i>
|
||||
</a>
|
||||
@endif
|
||||
@if(!empty($social_media['Instagram']))
|
||||
<a class="!text-[#d53581] hover:!text-[#c12570] text-[1.1rem] transition-colors" href="{{ $social_media['Instagram'] }}" target="_blank" rel="noopener">
|
||||
<a class="!text-[#d53581] hover:!text-[#c12570] text-[1.1rem] transition-colors" href="{{ $social_media['Instagram'] }}" target="_blank" rel="noopener" onclick="trackEvent('social_click', {platform: 'instagram'})">
|
||||
<i class="uil uil-instagram"></i>
|
||||
</a>
|
||||
@endif
|
||||
@if(!empty($social_media['Youtube']))
|
||||
<a class="!text-[#c8312b] hover:!text-[#b02822] text-[1.1rem] transition-colors" href="{{ $social_media['Youtube'] }}" target="_blank" rel="noopener">
|
||||
<a class="!text-[#c8312b] hover:!text-[#b02822] text-[1.1rem] transition-colors" href="{{ $social_media['Youtube'] }}" target="_blank" rel="noopener" onclick="trackEvent('social_click', {platform: 'youtube'})">
|
||||
<i class="uil uil-youtube"></i>
|
||||
</a>
|
||||
@endif
|
||||
@@ -141,7 +143,17 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu for Non-Homepage -->
|
||||
<div class="navbar-collapse offcanvas offcanvas-nav offcanvas-start lg:!hidden xl:!hidden">
|
||||
<div id="offcanvas-nav" class="navbar-collapse offcanvas offcanvas-nav offcanvas-start lg:!hidden xl:!hidden">
|
||||
<div class="offcanvas-header flex items-center justify-between flex-row p-6">
|
||||
<a href="/">
|
||||
{{-- Mobile menu is dark, so we only need the light (white) logo here --}}
|
||||
<img class="!h-[2.2rem]" src="{{ asset('assets/img/truncgil-yatay-dark.svg') }}" alt="Truncgil" fetchpriority="high" decoding="async">
|
||||
</a>
|
||||
<div class="flex items-center">
|
||||
@include("components.custom.language-selector")
|
||||
<button type="button" class="btn-close !text-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<ul class="navbar-nav">
|
||||
@foreach($menuItems as $item)
|
||||
@@ -169,4 +181,62 @@ $isHomepage = $currentRoute === 'homepage' || $currentPath === '/' || request()-
|
||||
@endif
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
</header>
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* Logo Visibility Fix */
|
||||
.logo-dark, .logo-light { display: none !important; }
|
||||
.navbar-light .logo-dark, .navbar-dark .logo-light { display: block !important; }
|
||||
/* Inside the offcanvas (mobile menu), we only want the light logo */
|
||||
.offcanvas .logo-dark { display: none !important; }
|
||||
.offcanvas .logo-light { display: block !important; }
|
||||
|
||||
/* Smoother Offcanvas Menu Transition */
|
||||
.offcanvas {
|
||||
transition: transform 0.4s cubic-bezier(0.77, 0.2, 0.05, 1.0) !important;
|
||||
}
|
||||
.offcanvas-backdrop {
|
||||
transition: opacity 0.4s ease !important;
|
||||
}
|
||||
|
||||
/* Fluid Hamburger Animation */
|
||||
.hamburger {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.hamburger span,
|
||||
.hamburger::before,
|
||||
.hamburger::after {
|
||||
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55) !important;
|
||||
}
|
||||
.hamburger.is-active span {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.hamburger.is-active::before {
|
||||
transform: translateY(6px) rotate(45deg) !important;
|
||||
}
|
||||
.hamburger.is-active::after {
|
||||
transform: translateY(-6px) rotate(-45deg) !important;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var offcanvases = document.querySelectorAll('.offcanvas-nav');
|
||||
var hamburgers = document.querySelectorAll('.hamburger.offcanvas-nav-btn');
|
||||
|
||||
if (offcanvases.length > 0 && hamburgers.length > 0) {
|
||||
offcanvases.forEach(function(oc) {
|
||||
oc.addEventListener('show.bs.offcanvas', function () {
|
||||
hamburgers.forEach(function(h) { h.classList.add('is-active'); });
|
||||
});
|
||||
oc.addEventListener('hide.bs.offcanvas', function () {
|
||||
hamburgers.forEach(function(h) { h.classList.remove('is-active'); });
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@@ -0,0 +1,11 @@
|
||||
{!! '<' . '?xml version="1.0" encoding="UTF-8"?' . '>' !!}
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
@foreach($urls as $url)
|
||||
<url>
|
||||
<loc>{{ $url['loc'] }}</loc>
|
||||
<lastmod>{{ $url['lastmod'] }}</lastmod>
|
||||
<changefreq>{{ $url['changefreq'] }}</changefreq>
|
||||
<priority>{{ $url['priority'] }}</priority>
|
||||
</url>
|
||||
@endforeach
|
||||
</urlset>
|
||||
@@ -105,6 +105,10 @@ Route::prefix('admin/api')->middleware(['auth', \App\Http\Middleware\SuperAdminM
|
||||
// Products & Services
|
||||
Route::get('/urun-hizmet/{slug}', [\App\Http\Controllers\ProductController::class, 'show'])->name('products.show');
|
||||
|
||||
// Career
|
||||
Route::get('/kariyer', [\App\Http\Controllers\CareerController::class, 'index'])->name('career.index');
|
||||
Route::post('/kariyer', [\App\Http\Controllers\CareerController::class, 'store'])->name('career.store');
|
||||
|
||||
// Payment Process
|
||||
Route::post('/payment/process', [\App\Http\Controllers\PaymentController::class, 'process'])->name('payment.process');
|
||||
Route::any('/payment/success', [\App\Http\Controllers\PaymentController::class, 'success'])->name('payment.success');
|
||||
@@ -131,6 +135,9 @@ Route::get('/logo-preview', function (Illuminate\Http\Request $request) {
|
||||
</html>";
|
||||
})->name('logo.preview');
|
||||
|
||||
// Sitemap
|
||||
Route::get('/sitemap.xml', [\App\Http\Controllers\SitemapController::class, 'index'])->name('sitemap');
|
||||
|
||||
// Nested Pages (Parent/Child)
|
||||
Route::get('/{parentSlug}/{slug}', [PageController::class, 'showNested'])->name('page.show_nested');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user