feat: implement full-stack awards module with Filament management, database support, and localization.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards;
|
||||
|
||||
use App\Filament\Admin\Resources\Awards\Pages\CreateAward;
|
||||
use App\Filament\Admin\Resources\Awards\Pages\EditAward;
|
||||
use App\Filament\Admin\Resources\Awards\Pages\ListAwards;
|
||||
use App\Filament\Admin\Resources\Awards\Schemas\AwardForm;
|
||||
use App\Filament\Admin\Resources\Awards\Tables\AwardsTable;
|
||||
use App\Models\Award;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class AwardResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Award::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-trophy';
|
||||
|
||||
protected static ?int $navigationSort = 46;
|
||||
|
||||
public static function getNavigationGroup(): ?string
|
||||
{
|
||||
return __('awards.navigation_group');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return __('awards.navigation_label');
|
||||
}
|
||||
|
||||
public static function getModelLabel(): string
|
||||
{
|
||||
return __('awards.model_label');
|
||||
}
|
||||
|
||||
public static function getPluralModelLabel(): string
|
||||
{
|
||||
return __('awards.plural_model_label');
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return AwardForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return AwardsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListAwards::route('/'),
|
||||
'create' => CreateAward::route('/create'),
|
||||
'edit' => EditAward::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\Awards\AwardResource;
|
||||
use App\Filament\Admin\Resources\Components\TranslationTabs;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateAward extends CreateRecord
|
||||
{
|
||||
protected static string $resource = AwardResource::class;
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return __('awards.create') ?? 'Yeni Ödül Ekle';
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
|
||||
protected function getCreatedNotificationTitle(): ?string
|
||||
{
|
||||
return __('awards.created_successfully') ?? 'Ödül başarıyla eklendi.';
|
||||
}
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
TranslationTabs::saveTranslations($this->record, $this->form->getState());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\Awards\AwardResource;
|
||||
use App\Filament\Admin\Resources\Components\TranslationTabs;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditAward extends EditRecord
|
||||
{
|
||||
protected static string $resource = AwardResource::class;
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return __('awards.edit') ?? 'Ödülü Düzenle';
|
||||
}
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make()
|
||||
->label(__('awards.delete') ?? 'Sil'),
|
||||
ForceDeleteAction::make()
|
||||
->label(__('awards.force_delete') ?? 'Kalıcı Olarak Sil'),
|
||||
RestoreAction::make()
|
||||
->label(__('awards.restore') ?? 'Geri Yükle'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
|
||||
protected function getSavedNotificationTitle(): ?string
|
||||
{
|
||||
return __('awards.updated_successfully') ?? 'Ödül başarıyla güncellendi.';
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeFill(array $data): array
|
||||
{
|
||||
return array_merge($data, TranslationTabs::fillFromRecord($this->record));
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
TranslationTabs::saveTranslations($this->record, $this->form->getState());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards\Pages;
|
||||
|
||||
use App\Filament\Admin\Resources\Awards\AwardResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListAwards extends ListRecords
|
||||
{
|
||||
protected static string $resource = AwardResource::class;
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return __('awards.title') ?? 'Ödüllerimiz';
|
||||
}
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make()
|
||||
->label(__('awards.create') ?? 'Yeni Ödül Ekle'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards\Schemas;
|
||||
|
||||
use App\Filament\Admin\Resources\Components\TranslationTabs;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class AwardForm
|
||||
{
|
||||
public static function categoryOptions(): array
|
||||
{
|
||||
return [
|
||||
'hackathon' => __('awards.category_hackathon') ?? 'Hackathon',
|
||||
'export' => __('awards.category_export') ?? 'İhracat',
|
||||
'innovation' => __('awards.category_innovation') ?? 'İnovasyon',
|
||||
'design' => __('awards.category_design') ?? 'Tasarım',
|
||||
'general' => __('awards.category_general') ?? 'Genel',
|
||||
];
|
||||
}
|
||||
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->columns(3)
|
||||
->schema([
|
||||
Section::make(__('awards.content_section') ?? 'Ödül İçeriği')
|
||||
->schema([
|
||||
TextInput::make('title')
|
||||
->label(__('awards.title_field') ?? 'Ödül Başlığı (Varsayılan)')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('issuer')
|
||||
->label(__('awards.issuer_field') ?? 'Ödülü Veren Kurum (Varsayılan)')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
|
||||
Textarea::make('description')
|
||||
->label(__('awards.description_field') ?? 'Açıklama (Varsayılan)')
|
||||
->required()
|
||||
->rows(5)
|
||||
->columnSpanFull(),
|
||||
|
||||
TranslationTabs::make([
|
||||
'title' => [
|
||||
'type' => 'text',
|
||||
'label' => __('awards.title_field') ?? 'Ödül Başlığı',
|
||||
'required' => false,
|
||||
'maxLength' => 255,
|
||||
],
|
||||
'issuer' => [
|
||||
'type' => 'text',
|
||||
'label' => __('awards.issuer_field') ?? 'Ödülü Veren Kurum',
|
||||
'required' => false,
|
||||
'maxLength' => 255,
|
||||
],
|
||||
'description' => [
|
||||
'type' => 'textarea',
|
||||
'label' => __('awards.description_field') ?? 'Açıklama',
|
||||
'required' => false,
|
||||
'rows' => 5,
|
||||
],
|
||||
]),
|
||||
])
|
||||
->columnSpan(2),
|
||||
|
||||
Section::make(__('awards.settings_section') ?? 'Ödül Ayarları')
|
||||
->schema([
|
||||
FileUpload::make('image')
|
||||
->label(__('awards.image_field') ?? 'Ödül Görseli / Logo')
|
||||
->image()
|
||||
->disk('public')
|
||||
->directory('awards')
|
||||
->required(),
|
||||
|
||||
DatePicker::make('award_date')
|
||||
->label(__('awards.date_field') ?? 'Ödül Tarihi')
|
||||
->required(),
|
||||
|
||||
Select::make('category')
|
||||
->label(__('awards.category_field') ?? 'Kategori')
|
||||
->options(self::categoryOptions())
|
||||
->default('general')
|
||||
->required()
|
||||
->native(false),
|
||||
|
||||
TextInput::make('external_link')
|
||||
->label(__('awards.link_field') ?? 'Doğrulama / Haber Linki')
|
||||
->url()
|
||||
->maxLength(255),
|
||||
|
||||
TextInput::make('sort_order')
|
||||
->label(__('awards.sort_order_field') ?? 'Sıralama')
|
||||
->numeric()
|
||||
->default(0)
|
||||
->minValue(0),
|
||||
|
||||
Toggle::make('is_featured')
|
||||
->label(__('awards.is_featured_field') ?? 'Öne Çıkarılan Ödül')
|
||||
->default(false),
|
||||
|
||||
Toggle::make('is_active')
|
||||
->label(__('awards.is_active_field') ?? 'Aktif / Görünür')
|
||||
->default(true),
|
||||
])
|
||||
->columnSpan(1),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Admin\Resources\Awards\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Columns\ToggleColumn;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class AwardsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
ImageColumn::make('image')
|
||||
->label(__('awards.table_image') ?? 'Logo')
|
||||
->disk('public')
|
||||
->square()
|
||||
->size(50),
|
||||
|
||||
TextColumn::make('title')
|
||||
->label(__('awards.table_title') ?? 'Ödül Başlığı')
|
||||
->searchable()
|
||||
->sortable()
|
||||
->limit(40),
|
||||
|
||||
TextColumn::make('issuer')
|
||||
->label(__('awards.table_issuer') ?? 'Veren Kurum')
|
||||
->searchable()
|
||||
->sortable()
|
||||
->limit(30),
|
||||
|
||||
TextColumn::make('award_date')
|
||||
->label(__('awards.table_date') ?? 'Ödül Tarihi')
|
||||
->date('d.m.Y')
|
||||
->sortable()
|
||||
->alignCenter(),
|
||||
|
||||
TextColumn::make('category')
|
||||
->label(__('awards.table_category') ?? 'Kategori')
|
||||
->badge()
|
||||
->formatStateUsing(fn (string $state): string => match ($state) {
|
||||
'hackathon' => __('awards.category_hackathon') ?? 'Hackathon',
|
||||
'export' => __('awards.category_export') ?? 'İhracat',
|
||||
'innovation' => __('awards.category_innovation') ?? 'İnovasyon',
|
||||
'design' => __('awards.category_design') ?? 'Tasarım',
|
||||
default => __('awards.category_general') ?? 'Genel',
|
||||
})
|
||||
->sortable()
|
||||
->alignCenter(),
|
||||
|
||||
ToggleColumn::make('is_featured')
|
||||
->label(__('awards.table_is_featured') ?? 'Öne Çıkan')
|
||||
->alignCenter(),
|
||||
|
||||
ToggleColumn::make('is_active')
|
||||
->label(__('awards.table_is_active') ?? 'Aktif')
|
||||
->alignCenter(),
|
||||
|
||||
TextColumn::make('sort_order')
|
||||
->label(__('awards.sort_order_field') ?? 'Sıra')
|
||||
->sortable()
|
||||
->alignCenter(),
|
||||
])
|
||||
->filters([
|
||||
TernaryFilter::make('is_active')
|
||||
->label(__('awards.is_active_field') ?? 'Aktiflik Durumu'),
|
||||
TernaryFilter::make('is_featured')
|
||||
->label(__('awards.is_featured_field') ?? 'Öne Çıkarılma Durumu'),
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make()
|
||||
->label(__('awards.edit') ?? 'Düzenle'),
|
||||
])
|
||||
->actions([
|
||||
// Individual actions can be put here if necessary
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make()
|
||||
->label(__('awards.delete') ?? 'Sil'),
|
||||
RestoreBulkAction::make()
|
||||
->label(__('awards.restore') ?? 'Geri Yükle'),
|
||||
ForceDeleteBulkAction::make()
|
||||
->label(__('awards.force_delete') ?? 'Kalıcı Olarak Sil'),
|
||||
]),
|
||||
])
|
||||
->defaultSort('sort_order', 'asc')
|
||||
->reorderable('sort_order');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Traits\HasTranslations;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Award extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes, HasTranslations;
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'description',
|
||||
'issuer',
|
||||
'award_date',
|
||||
'image',
|
||||
'external_link',
|
||||
'is_featured',
|
||||
'is_active',
|
||||
'sort_order',
|
||||
'category',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $translatable = [
|
||||
'title',
|
||||
'description',
|
||||
'issuer',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'award_date' => 'date',
|
||||
'is_featured' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
'sort_order' => 'integer',
|
||||
];
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
public function scopeFeatured($query)
|
||||
{
|
||||
return $query->where('is_featured', true);
|
||||
}
|
||||
|
||||
public function scopeOrdered($query)
|
||||
{
|
||||
return $query
|
||||
->orderBy('sort_order', 'asc')
|
||||
->orderBy('award_date', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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('awards', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title')->nullable(); // Original/fallback title
|
||||
$table->text('description')->nullable(); // Original/fallback description
|
||||
$table->string('issuer')->nullable(); // Original/fallback issuer
|
||||
$table->date('award_date')->nullable();
|
||||
$table->string('image')->nullable();
|
||||
$table->string('external_link')->nullable();
|
||||
$table->boolean('is_featured')->default(false);
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->string('category', 64)->default('general');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['is_active', 'sort_order']);
|
||||
$table->index('is_featured');
|
||||
$table->index('award_date');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('awards');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Award;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class AwardSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$awards = [
|
||||
[
|
||||
'title' => 'Here & AWS & THY Hackathon Birinciliği',
|
||||
'description' => '21 Mart 2019 yılında Here, Amazon Web Services (AWS) ve Türk Hava Yolları\'nın (THY) ortaklaşa yürüttüğü Hackathon kapsamında büyük bir başarı göstererek 1. lik ödülünü almaya hak kazandık.',
|
||||
'issuer' => 'Here & AWS & THY',
|
||||
'award_date' => '2019-03-21',
|
||||
'image' => 'assets/img/awards/truncgil-hackathon-birincisi-here-aws-thy.png',
|
||||
'external_link' => 'https://truncgil.com',
|
||||
'is_featured' => true,
|
||||
'is_active' => true,
|
||||
'sort_order' => 1,
|
||||
'category' => 'hackathon',
|
||||
'translations' => [
|
||||
'en' => [
|
||||
'title' => 'Here & AWS & THY Hackathon First Place',
|
||||
'description' => 'On March 21, 2019, we achieved outstanding success and won the 1st place award in the Hackathon jointly organized by Here, Amazon Web Services (AWS), and Turkish Airlines (THY).',
|
||||
'issuer' => 'Here, AWS & Turkish Airlines',
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => 'Gaziantep Teknopark Yılın İhracat Ödülü',
|
||||
'description' => 'İhracat faaliyetlerindeki üstün başarımızdan ötürü 26 Aralık 2019 yılında Gaziantep Teknopark tarafından "Yılın İhracat Ödülü"ne layık görüldük.',
|
||||
'issuer' => 'Gaziantep Teknopark',
|
||||
'award_date' => '2019-12-26',
|
||||
'image' => 'assets/img/awards/truncgil-teknoloji-yilin-ihracat-odulu.png',
|
||||
'external_link' => 'https://truncgil.com',
|
||||
'is_featured' => true,
|
||||
'is_active' => true,
|
||||
'sort_order' => 2,
|
||||
'category' => 'export',
|
||||
'translations' => [
|
||||
'en' => [
|
||||
'title' => 'Gaziantep Technopark Export of the Year Award',
|
||||
'description' => 'Due to our outstanding achievements in export activities, we were deemed worthy of the "Export of the Year Award" by Gaziantep Technopark on December 26, 2019.',
|
||||
'issuer' => 'Gaziantep Technopark',
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => 'HackSmarCity Hackathon Birinciliği',
|
||||
'description' => 'Gaziantep Teknopark, Target Teknoloji Transfer Ofisi, Gaziantep Büyükşehir Belediyesi ve Gaziantep Bilişim\'in ortaklaşa düzenlediği akıllı şehir çözümleri temalı HackSmarCity Hackathon\'unda 1. lik elde ettik.',
|
||||
'issuer' => 'Gaziantep Büyükşehir Belediyesi & Teknopark',
|
||||
'award_date' => '2019-11-15', // Approximate date in 2019/2020
|
||||
'image' => 'assets/img/awards/truncgil-teknoloji-hacksmarcity.jpg',
|
||||
'external_link' => 'https://truncgil.com',
|
||||
'is_featured' => false,
|
||||
'is_active' => true,
|
||||
'sort_order' => 3,
|
||||
'category' => 'hackathon',
|
||||
'translations' => [
|
||||
'en' => [
|
||||
'title' => 'HackSmarCity Hackathon First Place',
|
||||
'description' => 'We achieved 1st place in the HackSmarCity Hackathon themed around smart city solutions, jointly organized by Gaziantep Technopark, Target Technology Transfer Office, Gaziantep Metropolitan Municipality, and Gaziantep Bilisim.',
|
||||
'issuer' => 'Gaziantep Metropolitan Municipality & Technopark',
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($awards as $awardData) {
|
||||
$translations = $awardData['translations'] ?? [];
|
||||
unset($awardData['translations']);
|
||||
|
||||
$award = Award::updateOrCreate(
|
||||
[
|
||||
'award_date' => $awardData['award_date'],
|
||||
'image' => $awardData['image'],
|
||||
],
|
||||
$awardData
|
||||
);
|
||||
|
||||
// Save default (Turkish) translations in translation table too so HasTranslations resolves correctly
|
||||
$award->setTranslation('title', 'tr', $awardData['title'], 'published');
|
||||
$award->setTranslation('description', 'tr', $awardData['description'], 'published');
|
||||
$award->setTranslation('issuer', 'tr', $awardData['issuer'], 'published');
|
||||
|
||||
// Save English translations
|
||||
foreach ($translations as $langCode => $fields) {
|
||||
foreach ($fields as $fieldName => $value) {
|
||||
$award->setTranslation($fieldName, $langCode, $value, 'published');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ class DatabaseSeeder extends Seeder
|
||||
DekupaiProductSeeder::class,
|
||||
FinanceProductSeeder::class,
|
||||
BlogSeeder::class,
|
||||
AwardSeeder::class,
|
||||
]);
|
||||
|
||||
// User::factory(10)->create();
|
||||
|
||||
@@ -78,6 +78,24 @@ class PageSeeder extends Seeder
|
||||
]
|
||||
);
|
||||
|
||||
// 2.1.2 Ödüllerimiz (Child of Kurumsal)
|
||||
Page::updateOrCreate(
|
||||
['slug' => 'odullerimiz'],
|
||||
[
|
||||
'author_id' => $author->id,
|
||||
'parent_id' => $corporate->id,
|
||||
'title' => 'Ödüllerimiz',
|
||||
'excerpt' => 'Yenilikçi teknolojilerimizle sektöre yön veriyor, başarılarimizi küresel ödüllerle taçlandırıyoruz.',
|
||||
'content' => '<p>Yenilikçi teknolojilerimizle sektöre yön veriyor, başarılarimizi küresel ödüllerle taçlandırıyoruz.</p>',
|
||||
'template' => 'odullerimiz',
|
||||
'status' => 'published',
|
||||
'is_homepage' => false,
|
||||
'show_in_menu' => true,
|
||||
'sort_order' => 6, // Sort order among Kurumsal children
|
||||
'published_at' => now(),
|
||||
]
|
||||
);
|
||||
|
||||
// 2.2 Vizyon & Misyon (Child of Kurumsal)
|
||||
Page::updateOrCreate(
|
||||
['slug' => 'vizyon-misyon'],
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'navigation_group' => 'Corporate',
|
||||
'title' => 'Our Awards',
|
||||
'navigation_label' => 'Our Awards',
|
||||
'model_label' => 'Award',
|
||||
'plural_model_label' => 'Our Awards',
|
||||
|
||||
'create' => 'Add New Award',
|
||||
'edit' => 'Edit Award',
|
||||
'delete' => 'Delete',
|
||||
'restore' => 'Restore',
|
||||
'force_delete' => 'Force Delete',
|
||||
|
||||
'content_section' => 'Award Details',
|
||||
'settings_section' => 'Award Settings',
|
||||
|
||||
'title_field' => 'Award Title',
|
||||
'issuer_field' => 'Issuing Organization',
|
||||
'description_field' => 'Description',
|
||||
'image_field' => 'Award Logo / Badge',
|
||||
'date_field' => 'Award Date',
|
||||
'category_field' => 'Category',
|
||||
'link_field' => 'News / Verification Link',
|
||||
'sort_order_field' => 'Sort Order',
|
||||
'is_featured_field' => 'Feature Award',
|
||||
'is_active_field' => 'Active / Visible',
|
||||
|
||||
'table_image' => 'Logo',
|
||||
'table_title' => 'Award Title',
|
||||
'table_issuer' => 'Issuer',
|
||||
'table_date' => 'Date',
|
||||
'table_category' => 'Category',
|
||||
'table_is_featured' => 'Featured',
|
||||
'table_is_active' => 'Active',
|
||||
|
||||
'created_successfully' => 'Award successfully created.',
|
||||
'updated_successfully' => 'Award successfully updated.',
|
||||
'deleted_successfully' => 'Award successfully deleted.',
|
||||
|
||||
'category_hackathon' => 'Hackathon / Competition',
|
||||
'category_export' => 'Export / Success',
|
||||
'category_innovation' => 'Innovation / R&D',
|
||||
'category_design' => 'Design / UI',
|
||||
'category_general' => 'General Award',
|
||||
];
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'navigation_group' => 'Kurumsal',
|
||||
'title' => 'Ödüllerimiz',
|
||||
'navigation_label' => 'Ödüllerimiz',
|
||||
'model_label' => 'Ödül',
|
||||
'plural_model_label' => 'Ödüllerimiz',
|
||||
|
||||
'create' => 'Yeni Ödül Ekle',
|
||||
'edit' => 'Ödülü Düzenle',
|
||||
'delete' => 'Sil',
|
||||
'restore' => 'Geri Yükle',
|
||||
'force_delete' => 'Kalıcı Olarak Sil',
|
||||
|
||||
'content_section' => 'Ödül Bilgileri',
|
||||
'settings_section' => 'Ödül Ayarları',
|
||||
|
||||
'title_field' => 'Ödül Adı',
|
||||
'issuer_field' => 'Ödülü Veren Kurum',
|
||||
'description_field' => 'Açıklama',
|
||||
'image_field' => 'Ödül Görseli / Logo',
|
||||
'date_field' => 'Ödül Tarihi',
|
||||
'category_field' => 'Kategori',
|
||||
'link_field' => 'Haber / Doğrulama Linki',
|
||||
'sort_order_field' => 'Sıralama',
|
||||
'is_featured_field' => 'Öne Çıkar',
|
||||
'is_active_field' => 'Aktif / Görünür',
|
||||
|
||||
'table_image' => 'Logo',
|
||||
'table_title' => 'Ödül Adı',
|
||||
'table_issuer' => 'Veren Kurum',
|
||||
'table_date' => 'Tarih',
|
||||
'table_category' => 'Kategori',
|
||||
'table_is_featured' => 'Öne Çıkan',
|
||||
'table_is_active' => 'Aktif',
|
||||
|
||||
'created_successfully' => 'Ödül başarıyla eklendi.',
|
||||
'updated_successfully' => 'Ödül başarıyla güncellendi.',
|
||||
'deleted_successfully' => 'Ödül başarıyla silindi.',
|
||||
|
||||
'category_hackathon' => 'Hackathon / Yarışma',
|
||||
'category_export' => 'İhracat / Başarı',
|
||||
'category_innovation' => 'İnovasyon / Ar-Ge',
|
||||
'category_design' => 'Tasarım / Arayüz',
|
||||
'category_general' => 'Genel Ödül',
|
||||
];
|
||||
@@ -0,0 +1,410 @@
|
||||
@extends('layouts.site', [
|
||||
'header' => 'partials.header-demo1',
|
||||
'footer' => 'partials.footer',
|
||||
])
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$awards = \App\Models\Award::active()->ordered()->get();
|
||||
|
||||
// Extracted categories from active awards for dynamic filter options
|
||||
$categories = $awards->pluck('category')->unique()->toArray();
|
||||
|
||||
$heroTitle = $page ? ($page->translate('title') ?: $page->title) : t('Ödüllerimiz ve Başarılarımız');
|
||||
$heroExcerpt = $page ? ($page->translate('excerpt') ?: $page->excerpt) : t('Yenilikçi teknolojilerimizle sektöre yön veriyor, başarılarımızı küresel ödüllerle taçlandırıyoruz.');
|
||||
|
||||
// Timeline color palette
|
||||
$colors = ['#e31e24', '#f5a623', '#27ae60', '#2980b9', '#8e44ad', '#1abc9c'];
|
||||
@endphp
|
||||
|
||||
<div class="grow shrink-0 bg-[#fbfcfd]">
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="wrapper image-wrapper bg-image bg-overlay bg-overlay-400 !text-white bg-no-repeat bg-[center_center] bg-cover relative z-0 !bg-fixed before:content-[''] before:block before:absolute before:z-[1] before:w-full before:h-full before:left-0 before:top-0 before:bg-[rgba(30,34,40,.55)]" data-image-src="{{ asset('assets/img/photos/bg4.webp') }}" style="background-image: url('{{ asset('assets/img/photos/bg4.webp') }}');">
|
||||
<div class="container pt-28 pb-40 xl:pt-36 lg:pt-36 md:pt-36 xl:pb-[12.5rem] lg:pb-[12.5rem] md:pb-[12.5rem] !text-center">
|
||||
<div class="flex flex-wrap mx-[-15px]">
|
||||
<div class="xl:w-8/12 lg:w-8/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto">
|
||||
<h1 class="!text-[calc(1.365rem_+_1.38vw)] font-bold !leading-[1.2] xl:!text-[2.6rem] !mb-4 !text-white">{{ $heroTitle }}</h1>
|
||||
<p class="lead !text-[1.05rem] !leading-[1.6] !text-white opacity-90 max-w-2xl mx-auto mb-6">{{ $heroExcerpt }}</p>
|
||||
<nav class="inline-block" aria-label="breadcrumb">
|
||||
<ol class="breadcrumb flex flex-wrap bg-[none] p-0 !rounded-none list-none !mb-[20px] justify-center">
|
||||
<li class="breadcrumb-item flex !text-[#c3c3c3]"><a class="!text-white hover:text-[#e31e24]" href="{{ url('/') }}">{{ t('Anasayfa') }}</a></li>
|
||||
<li class="breadcrumb-item flex !text-white !pl-2 before:font-normal before:!flex before:items-center before:text-[rgba(255,255,255,.5)] before:content-['\e931'] before:text-[0.9rem] before:-mt-px before:!pr-2 before:font-Unicons active" aria-current="page">{{ t('Ödüllerimiz') }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Main Content wrapper with Timeline -->
|
||||
<section class="wrapper !bg-[#f4f6f8] relative border-0 upper-end before:top-[-4rem] before:border-l-transparent before:border-r-[100vw] before:border-t-[4rem] before:border-[#f4f6f8] before:content-[''] before:block before:absolute before:z-0 before:border-y-transparent before:border-0 before:border-solid before:right-0">
|
||||
<div class="container pb-16">
|
||||
<div class="xl:w-10/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto !mt-[-9rem] relative z-10">
|
||||
|
||||
<!-- Category Filters -->
|
||||
<div class="flex flex-wrap justify-center gap-2 mb-14" id="awards-filter-tabs">
|
||||
<button class="filter-btn active px-5 py-2 text-xs font-bold rounded-full transition-all border bg-white text-gray-700 hover:bg-gray-100 border-gray-200" data-filter="all">
|
||||
{{ t('Tüm Ödüller') }}
|
||||
</button>
|
||||
@if(in_array('hackathon', $categories))
|
||||
<button class="filter-btn px-5 py-2 text-xs font-bold rounded-full transition-all border bg-white text-gray-700 hover:bg-gray-100 border-gray-200" data-filter="hackathon">
|
||||
{{ t('Hackathon / Yarışma') }}
|
||||
</button>
|
||||
@endif
|
||||
@if(in_array('export', $categories))
|
||||
<button class="filter-btn px-5 py-2 text-xs font-bold rounded-full transition-all border bg-white text-gray-700 hover:bg-gray-100 border-gray-200" data-filter="export">
|
||||
{{ t('İhracat / Başarı') }}
|
||||
</button>
|
||||
@endif
|
||||
@if(in_array('innovation', $categories))
|
||||
<button class="filter-btn px-5 py-2 text-xs font-bold rounded-full transition-all border bg-white text-gray-700 hover:bg-gray-100 border-gray-200" data-filter="innovation">
|
||||
{{ t('İnovasyon / Ar-Ge') }}
|
||||
</button>
|
||||
@endif
|
||||
@if(in_array('design', $categories))
|
||||
<button class="filter-btn px-5 py-2 text-xs font-bold rounded-full transition-all border bg-white text-gray-700 hover:bg-gray-100 border-gray-200" data-filter="design">
|
||||
{{ t('Tasarım') }}
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Timeline Container -->
|
||||
<div class="awards-timeline" data-timeline-animate>
|
||||
<div class="awards-timeline__start awards-timeline__reveal">
|
||||
<span>{{ t('BAŞLANGIÇ') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="awards-timeline__track">
|
||||
@foreach($awards as $index => $award)
|
||||
@php
|
||||
$color = $colors[$index % count($colors)];
|
||||
$position = $index % 2 === 0 ? 'right' : 'left';
|
||||
$imgSrc = str_starts_with($award->image, 'assets/') ? asset($award->image) : asset('storage/' . $award->image);
|
||||
@endphp
|
||||
<article class="awards-timeline__item awards-timeline__item--{{ $position }} awards-timeline__reveal" style="--item-color: {{ $color }};" data-category="{{ $award->category }}">
|
||||
|
||||
<!-- Timeline Axis Dot & Line -->
|
||||
<div class="awards-timeline__axis">
|
||||
<span class="awards-timeline__dot"></span>
|
||||
</div>
|
||||
|
||||
<!-- Timeline Card -->
|
||||
<div class="awards-timeline__side awards-timeline__side--inner">
|
||||
<div class="awards-timeline__content bg-white rounded-[0.8rem] border border-[rgba(30,34,40,0.06)] hover:translate-y-[-0.25rem] transition-all duration-300 hover:shadow-[0_1rem_2.5rem_rgba(30,34,40,0.08)] flex flex-col overflow-hidden group">
|
||||
|
||||
<!-- Ceremony Photo Banner -->
|
||||
<div class="award-photo-wrapper" style="width: 100%; height: 240px; overflow: hidden; position: relative; background: #eef1f4;">
|
||||
<img src="{{ $imgSrc }}" alt="{{ $award->translate('title') }}" style="width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease;" class="award-photo-img group-hover:scale-105" />
|
||||
<!-- Badge on Image -->
|
||||
<div style="position: absolute; top: 12px; left: 12px; display: flex; gap: 6px;">
|
||||
<span class="badge bg-[#1e2229]/80 !text-white text-[0.62rem] uppercase tracking-wider px-2.5 py-1" style="border-radius: 4px;">
|
||||
{{ $award->category === 'hackathon' ? t('Yarışma') : ($award->category === 'export' ? t('İhracat') : t('Başarı')) }}
|
||||
</span>
|
||||
@if($award->is_featured)
|
||||
<span class="badge bg-[#f5a623] !text-white text-[0.62rem] uppercase tracking-wider px-2.5 py-1" style="border-radius: 4px;">
|
||||
<i class="uil uil-star"></i> {{ t('Öne Çıkan') }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card Info Padding Content -->
|
||||
<div class="p-6 md:p-8 flex flex-col gap-3 text-start">
|
||||
<div style="font-size: 0.72rem; color: #959ca9; font-weight: 600;">
|
||||
<i class="uil uil-calendar-alt"></i> {{ $award->award_date ? $award->award_date->translatedFormat('d F Y') : '' }}
|
||||
</div>
|
||||
|
||||
<h3 class="text-base font-extrabold text-gray-900 mb-1 leading-snug group-hover:text-[#e31e24] transition-colors duration-300">
|
||||
{{ $award->translate('title') }}
|
||||
</h3>
|
||||
|
||||
<p class="text-xs leading-relaxed text-gray-500 mb-2">
|
||||
{{ $award->translate('description') }}
|
||||
</p>
|
||||
|
||||
<!-- Footer elements -->
|
||||
<div class="flex items-center justify-between pt-3 border-t border-gray-100 mt-2">
|
||||
<span class="text-[0.72rem] font-bold text-gray-600 flex items-center gap-1">
|
||||
<i class="uil uil-award text-[#e31e24] text-sm"></i> {{ $award->translate('issuer') }}
|
||||
</span>
|
||||
@if($award->external_link)
|
||||
<a href="{{ $award->external_link }}" target="_blank" class="text-[0.72rem] font-bold text-[#e31e24] hover:underline flex items-center gap-0.5">
|
||||
{{ t('Doğrula') }} <i class="uil uil-external-link-alt"></i>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="awards-timeline__finish awards-timeline__reveal">
|
||||
<span>{{ t('BUGÜN') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Standards and Trust elements -->
|
||||
<div class="my-16 border-t border-gray-200/60 pt-16">
|
||||
<div class="text-center mb-8">
|
||||
<span class="badge bg-pale-red text-red !rounded-[50rem] uppercase tracking-wider font-semibold text-[0.7rem] px-3 py-1 mb-2 inline-block">{{ t('GÜVEN & STANDARTLAR') }}</span>
|
||||
<h3 class="!text-[calc(1.2rem_+_0.6vw)] font-bold xl:!text-[1.8rem] !leading-[1.3] text-[#1e2229]">{{ t('Standartlarımız ve Sertifikalarımız') }}</h3>
|
||||
<p class="text-xs text-gray-500 leading-relaxed max-w-xl mx-auto mt-2">{{ t('Bir teknoloji şirketi olarak, geliştirdiğimiz tüm sistemlerde ulusal ve uluslararası güvenlik ve kalite standartlarına tam uyum sağlıyoruz.') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap justify-center items-center gap-8 md:gap-12 mt-10">
|
||||
<!-- ISO 27001 -->
|
||||
<div class="flex flex-col items-center max-w-[120px] text-center group">
|
||||
<div class="w-16 h-16 rounded-full border border-gray-200/80 bg-white shadow-sm flex items-center justify-center p-3 mb-2 group-hover:border-red/40 group-hover:shadow-md transition-all duration-300">
|
||||
<i class="uil uil-shield-check text-2xl text-gray-400 group-hover:text-red transition-colors duration-300"></i>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-gray-700 leading-tight">ISO 27001</span>
|
||||
<span class="text-[0.62rem] text-gray-400 mt-0.5">{{ t('Bilgi Güvenliği') }}</span>
|
||||
</div>
|
||||
<!-- ISO 9001 -->
|
||||
<div class="flex flex-col items-center max-w-[120px] text-center group">
|
||||
<div class="w-16 h-16 rounded-full border border-gray-200/80 bg-white shadow-sm flex items-center justify-center p-3 mb-2 group-hover:border-red/40 group-hover:shadow-md transition-all duration-300">
|
||||
<i class="uil uil-check-square text-2xl text-gray-400 group-hover:text-red transition-colors duration-300"></i>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-gray-700 leading-tight">ISO 9001</span>
|
||||
<span class="text-[0.62rem] text-gray-400 mt-0.5">{{ t('Kalite Yönetimi') }}</span>
|
||||
</div>
|
||||
<!-- KVKK / GDPR -->
|
||||
<div class="flex flex-col items-center max-w-[120px] text-center group">
|
||||
<div class="w-16 h-16 rounded-full border border-gray-200/80 bg-white shadow-sm flex items-center justify-center p-3 mb-2 group-hover:border-red/40 group-hover:shadow-md transition-all duration-300">
|
||||
<i class="uil uil-lock text-2xl text-gray-400 group-hover:text-red transition-colors duration-300"></i>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-gray-700 leading-tight">KVKK / GDPR</span>
|
||||
<span class="text-[0.62rem] text-gray-400 mt-0.5">{{ t('Veri Güvenliği') }}</span>
|
||||
</div>
|
||||
<!-- Teknopark -->
|
||||
<div class="flex flex-col items-center max-w-[120px] text-center group">
|
||||
<div class="w-16 h-16 rounded-full border border-gray-200/80 bg-white shadow-sm flex items-center justify-center p-3 mb-2 group-hover:border-red/40 group-hover:shadow-md transition-all duration-300">
|
||||
<i class="uil uil-building text-2xl text-gray-400 group-hover:text-red transition-colors duration-300"></i>
|
||||
</div>
|
||||
<span class="text-xs font-bold text-gray-700 leading-tight">Teknopark</span>
|
||||
<span class="text-[0.62rem] text-gray-400 mt-0.5">{{ t('Ar-Ge Liderliği') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Employer Branding Closing CTA -->
|
||||
<div class="my-16 bg-gradient-to-r from-red to-rose-600 rounded-[1rem] p-8 md:p-12 !text-white text-center shadow-lg relative overflow-hidden group">
|
||||
<div class="absolute -right-16 -top-16 w-48 h-48 rounded-full bg-white/10 opacity-30 group-hover:scale-110 transition-transform duration-500"></div>
|
||||
<div class="absolute -left-16 -bottom-16 w-48 h-48 rounded-full bg-white/10 opacity-30 group-hover:scale-110 transition-transform duration-500"></div>
|
||||
|
||||
<h3 class="text-xl md:text-2xl font-bold !text-white mb-3 relative z-10">{{ t('Bu başarıları birlikte kazandık!') }}</h3>
|
||||
<p class="text-sm leading-relaxed max-w-xl mx-auto mb-6 opacity-90 relative z-10">{{ t('Geleceği yenilikçi teknolojilerle şekillendiren bu harika ekibin bir parçası olmak, bizimle yeni ödüllere koşmak ister misin?') }}</p>
|
||||
<a href="{{ url('/kariyer') }}" class="btn btn-white !rounded-[50rem] px-6 py-2.5 text-xs font-bold hover:translate-y-[-0.15rem] hover:shadow-md transition-all relative z-10 !bg-white !text-[#e31e24] hover:!bg-gray-50 border-0">
|
||||
{{ t('Aramıza Katıl') }} <i class="uil uil-arrow-right ml-1"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.filter-btn.active {
|
||||
background-color: #e31e24 !important;
|
||||
border-color: #e31e24 !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 4px 12px rgba(227, 30, 36, 0.2);
|
||||
}
|
||||
|
||||
/* Timeline Design System drawing inspiration from hakkimizda */
|
||||
.awards-timeline {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.awards-timeline__start,
|
||||
.awards-timeline__finish {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.awards-timeline__finish {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.awards-timeline__start span,
|
||||
.awards-timeline__finish span {
|
||||
display: inline-block;
|
||||
padding: 0.45rem 1.4rem;
|
||||
border: 2px solid #cbd5e0;
|
||||
border-radius: 999px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.16em;
|
||||
color: #4a5568;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.awards-timeline__track {
|
||||
position: relative;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.awards-timeline__track::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
transform: translateX(-50%);
|
||||
background: linear-gradient(to bottom, #e31e24, #f5a623, #27ae60, #2980b9);
|
||||
border-radius: 4px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.awards-timeline__item {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 40px 1fr;
|
||||
align-items: center;
|
||||
gap: 0 2rem;
|
||||
margin-bottom: 2.75rem;
|
||||
z-index: 1;
|
||||
transition: all 0.45s ease;
|
||||
}
|
||||
|
||||
.awards-timeline__item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.awards-timeline__axis {
|
||||
grid-column: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.awards-timeline__dot {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: var(--item-color);
|
||||
border: 3px solid #fff;
|
||||
box-shadow: 0 0 0 2px var(--item-color);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.awards-timeline__item:hover .awards-timeline__dot {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
|
||||
/* Alternating Right side */
|
||||
.awards-timeline__item--right .awards-timeline__side--inner {
|
||||
grid-column: 3;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Alternating Left side */
|
||||
.awards-timeline__item--left .awards-timeline__side--inner {
|
||||
grid-column: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Animations reveal */
|
||||
.awards-timeline__reveal {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 32px, 0);
|
||||
transition: opacity 0.85s cubic-bezier(0.22, 1, 0.36, 1), transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
.awards-timeline__reveal.is-visible {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
/* Dynamic hide class */
|
||||
.awards-timeline__item.hidden-by-filter {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.awards-timeline__track::before {
|
||||
left: 20px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.awards-timeline__item {
|
||||
grid-template-columns: 40px 1fr;
|
||||
gap: 0 1rem;
|
||||
}
|
||||
|
||||
.awards-timeline__axis {
|
||||
grid-column: 1;
|
||||
align-self: start;
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
|
||||
.awards-timeline__item--left .awards-timeline__side--inner,
|
||||
.awards-timeline__item--right .awards-timeline__side--inner {
|
||||
grid-column: 2;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const filterButtons = document.querySelectorAll('.filter-btn');
|
||||
const awardCards = document.querySelectorAll('.awards-timeline__item');
|
||||
|
||||
filterButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
filterButtons.forEach(btn => btn.classList.remove('active'));
|
||||
this.classList.add('active');
|
||||
|
||||
const filterValue = this.getAttribute('data-filter');
|
||||
|
||||
awardCards.forEach(card => {
|
||||
if (filterValue === 'all' || card.getAttribute('data-category') === filterValue) {
|
||||
card.classList.remove('hidden-by-filter');
|
||||
} else {
|
||||
card.classList.add('hidden-by-filter');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Reveal animation on scroll drawing inspiration from hakkimizda.blade.php
|
||||
const revealElements = document.querySelectorAll('.awards-timeline__reveal');
|
||||
|
||||
if (revealElements.length > 0) {
|
||||
const observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('is-visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
root: null,
|
||||
rootMargin: '0px 0px -10% 0px',
|
||||
threshold: 0.1,
|
||||
});
|
||||
|
||||
revealElements.forEach(function (element) {
|
||||
observer.observe(element);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
Reference in New Issue
Block a user