feat: implement Company History module with CRUD functionality, localization support, and timeline display for enhanced user experience
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
@props(['icon' => 'heroicon-o-building-office-2', 'color' => '#17a2b8'])
|
||||
|
||||
@php
|
||||
$paths = match ($icon) {
|
||||
'heroicon-o-academic-cap' => 'M4.26 10.147a60.438 60.438 0 0 0-.491 6.347A48.62 48.62 0 0 1 12 20.904a48.62 48.62 0 0 1 8.232-4.41 60.46 60.46 0 0 0-.491-6.347m-15.482 0a50.636 50.636 0 0 0-2.658-.813A59.906 59.906 0 0 1 12 3.493a59.903 59.903 0 0 1 10.399 5.84c-.896.248-1.783.52-2.658.814m-15.482 0A50.717 50.717 0 0 1 12 13.489a50.702 50.702 0 0 1 7.74-3.342M6.75 15a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm0 0v-3.675A55.378 55.378 0 0 1 12 8.443m0 0V5.25A2.25 2.25 0 0 0 9 3H5.25A2.25 2.25 0 0 0 3 5.25v3.175',
|
||||
'heroicon-o-globe-alt' => 'M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5a17.92 17.92 0 0 1-8.716-2.247m0 0A8.959 8.959 0 0 1 3 12c0-.778.099-1.533.284-2.253',
|
||||
'heroicon-o-users' => 'M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z',
|
||||
'heroicon-o-trophy' => 'M16.5 18.75h-9m9 0a3 3 0 0 1 3 3h-15a3 3 0 0 1 3-3m9 0v-3.375c0-.621-.503-1.125-1.125-1.125h-.871M7.5 18.75H4.875c-.621 0-1.125.503-1.125 1.125v.375M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z',
|
||||
'heroicon-o-map' => 'M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z',
|
||||
'heroicon-o-light-bulb' => 'M12 18v-5.25m0 0a6.01 6.01 0 0 0 1.5-.189m-1.5.189a6.01 6.01 0 0 1-1.5-.189m3.75 7.478a12.06 12.06 0 0 1-4.5 0m3.75 2.383a14.406 14.406 0 0 1-3 0M14.25 18v-.192c0-.983.658-1.823 1.508-2.316a7.5 7.5 0 1 0-7.517 0c.85.493 1.509 1.333 1.509 2.316V18',
|
||||
'heroicon-o-rocket-launch' => 'M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z',
|
||||
default => 'M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Z',
|
||||
};
|
||||
@endphp
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="{{ $color }}" class="company-history-icon-svg" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="{{ $paths }}" />
|
||||
</svg>
|
||||
@@ -0,0 +1,322 @@
|
||||
@props([
|
||||
'items' => collect(),
|
||||
'showHeader' => true,
|
||||
])
|
||||
|
||||
@php
|
||||
$historyItems = $items instanceof \Illuminate\Support\Collection ? $items : collect($items);
|
||||
$gradientStops = $historyItems->values()->map(function ($item, $index) use ($historyItems) {
|
||||
$percent = $historyItems->count() > 1
|
||||
? round(($index / ($historyItems->count() - 1)) * 100, 1)
|
||||
: 0;
|
||||
return ($item->color ?? '#17a2b8') . ' ' . $percent . '%';
|
||||
})->implode(', ');
|
||||
@endphp
|
||||
|
||||
@if($historyItems->isNotEmpty())
|
||||
<section class="company-history-timeline-section wrapper !bg-[#f4f6f8]">
|
||||
<div class="container py-20 xl:py-28 lg:py-28 md:py-28">
|
||||
@if($showHeader)
|
||||
<div class="flex flex-wrap mx-[-15px] !mb-14 !text-center">
|
||||
<div class="w-full flex-[0_0_auto] !px-[15px] max-w-full !mx-auto">
|
||||
<span class="inline-block text-[0.75rem] tracking-[0.12rem] uppercase font-bold !mb-3" style="color: #e31e24;">
|
||||
{{ __('company_history.timeline_section_badge') }}
|
||||
</span>
|
||||
<h2 class="!text-[calc(1.345rem_+_1.14vw)] font-bold !leading-[1.2] xl:!text-[2.2rem] !mb-3">
|
||||
{{ __('company_history.timeline_section_title') }}
|
||||
</h2>
|
||||
<p class="lead text-[1.05rem] !leading-[1.6] !text-[#60697b] max-w-[42rem] !mx-auto">
|
||||
{{ __('company_history.timeline_section_subtitle') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="company-history-timeline">
|
||||
<div class="company-history-timeline__start">
|
||||
<span>{{ __('company_history.timeline_start') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="company-history-timeline__track" style="--timeline-gradient: linear-gradient(to bottom, {{ $gradientStops }});">
|
||||
@foreach($historyItems as $item)
|
||||
@php
|
||||
$color = $item->color ?? '#17a2b8';
|
||||
$position = $item->resolved_position;
|
||||
$title = method_exists($item, 'translate') ? ($item->translate('title') ?: $item->title) : $item->title;
|
||||
$content = method_exists($item, 'translate') ? ($item->translate('content') ?: $item->content) : $item->content;
|
||||
@endphp
|
||||
<article
|
||||
class="company-history-timeline__item company-history-timeline__item--{{ $position }}"
|
||||
style="--item-color: {{ $color }};"
|
||||
>
|
||||
<div class="company-history-timeline__side company-history-timeline__side--outer">
|
||||
<div class="company-history-timeline__icon-ring">
|
||||
<x-company-history.icon :icon="$item->icon" :color="$color" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="company-history-timeline__axis">
|
||||
<span class="company-history-timeline__dot" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
<div class="company-history-timeline__side company-history-timeline__side--inner">
|
||||
<div class="company-history-timeline__content">
|
||||
<div class="company-history-timeline__year">{{ $item->year }}</div>
|
||||
@if($title)
|
||||
<h3 class="company-history-timeline__title">{{ strtoupper($title) }}</h3>
|
||||
@endif
|
||||
@if($content)
|
||||
<p class="company-history-timeline__text">{{ $content }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="company-history-timeline__finish">
|
||||
<span>{{ __('company_history.timeline_finish') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@once
|
||||
@push('styles')
|
||||
<style>
|
||||
.company-history-timeline {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.company-history-timeline__start,
|
||||
.company-history-timeline__finish {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__finish {
|
||||
margin-top: 1.75rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.company-history-timeline__start span,
|
||||
.company-history-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.14em;
|
||||
color: #4a5568;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.company-history-timeline__track {
|
||||
position: relative;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
.company-history-timeline__track::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
transform: translateX(-50%);
|
||||
background: var(--timeline-gradient);
|
||||
border-radius: 4px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.company-history-timeline__item {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 40px 1fr;
|
||||
align-items: center;
|
||||
gap: 0 1.5rem;
|
||||
min-height: 150px;
|
||||
margin-bottom: 2.75rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.company-history-timeline__item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.company-history-timeline__axis {
|
||||
grid-column: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.company-history-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);
|
||||
}
|
||||
|
||||
.company-history-timeline__icon-ring {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid var(--item-color);
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.company-history-timeline__icon-ring::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 48px;
|
||||
height: 0;
|
||||
border-top: 2px dotted var(--item-color);
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.company-history-icon-svg {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.company-history-timeline__year {
|
||||
font-size: clamp(2rem, 4vw, 2.85rem);
|
||||
font-weight: 800;
|
||||
line-height: 1.05;
|
||||
color: var(--item-color);
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__title {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--item-color);
|
||||
margin: 0 0 0.7rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__text {
|
||||
font-size: 0.93rem;
|
||||
line-height: 1.65;
|
||||
color: #718096;
|
||||
margin: 0;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
/* Sağ taraf: içerik sağda, ikon en sağda */
|
||||
.company-history-timeline__item--right .company-history-timeline__side--inner {
|
||||
grid-column: 3;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--right .company-history-timeline__side--outer {
|
||||
grid-column: 3;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: -5.5rem;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--right .company-history-timeline__icon-ring::before {
|
||||
right: 100%;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--right .company-history-timeline__content {
|
||||
padding-right: 5.5rem;
|
||||
}
|
||||
|
||||
/* Sol taraf: ikon en solda, içerik solda */
|
||||
.company-history-timeline__item--left .company-history-timeline__side--inner {
|
||||
grid-column: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__side--outer {
|
||||
grid-column: 1;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: -5.5rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__icon-ring::before {
|
||||
left: 100%;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__content {
|
||||
padding-left: 5.5rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__text {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.company-history-timeline__track::before {
|
||||
left: 24px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.company-history-timeline__item {
|
||||
grid-template-columns: 48px 1fr;
|
||||
gap: 0 1rem;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.company-history-timeline__axis {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
align-self: start;
|
||||
padding-top: 1.25rem;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__side--inner,
|
||||
.company-history-timeline__item--right .company-history-timeline__side--inner {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__side--outer,
|
||||
.company-history-timeline__item--right .company-history-timeline__side--outer {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
margin-top: 0.75rem;
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__content,
|
||||
.company-history-timeline__item--right .company-history-timeline__content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.company-history-timeline__icon-ring {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.company-history-timeline__icon-ring::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.company-history-timeline__item--left .company-history-timeline__text {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
@endonce
|
||||
@endif
|
||||
Reference in New Issue
Block a user