feat: add SEO schema markup and page preloader to web development template

This commit is contained in:
Ümit Tunç
2026-05-23 11:13:20 +03:00
parent 53a265844f
commit b2e6f89bcb
@@ -12,6 +12,110 @@
<link rel="preload" as="image" href="{{ asset($pageHero['webp']) }}" type="image/webp" fetchpriority="high">
@endif
@endif
<script type="application/ld+json">
{
"@@context": "https://schema.org",
"@@graph": [
{
"@@type": "ProfessionalService",
"@@id": "{{ url()->current() }}#organization",
"name": "Trunçgil Teknoloji",
"image": "{{ asset('assets/img/logo.png') }}",
"url": "{{ url('/') }}",
"telephone": "+902244431620",
"priceRange": "$$$",
"address": {
"@@type": "PostalAddress",
"streetAddress": "Ulutek Teknoloji Geliştirme Bölgesi, Görükle Kampüsü, No: 104",
"addressLocality": "Nilüfer",
"addressRegion": "Bursa",
"postalCode": "16059",
"addressCountry": "TR"
},
"geo": {
"@@type": "GeoCoordinates",
"latitude": 40.2201925,
"longitude": 28.8711467
},
"openingHoursSpecification": {
"@@type": "OpeningHoursSpecification",
"dayOfWeek": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
],
"opens": "09:00",
"closes": "18:00"
},
"sameAs": [
"https://www.facebook.com/truncgil",
"https://www.instagram.com/truncgil",
"https://www.linkedin.com/company/truncgil-technology"
]
},
{
"@@type": "Service",
"@@id": "{{ url()->current() }}#service",
"serviceType": "Web Application Development",
"provider": {
"@@id": "{{ url()->current() }}#organization"
},
"name": {!! json_encode(t('Web Uygulamaları Geliştirme Hizmeti')) !!},
"description": {!! json_encode(t('Trunçgil Teknoloji olarak; Three.js\'den Django\'ya, Node.js\'den React ve Vue\'ye kadar tüm modern teknolojilerle ölçeklenebilir ve güvenli web uygulamaları geliştiriyoruz.')) !!},
"areaServed": [
{
"@@type": "AdministrativeArea",
"name": "Bursa"
},
{
"@@type": "AdministrativeArea",
"name": "Türkiye"
},
{
"@@type": "AdministrativeArea",
"name": "Global"
}
],
"hasOfferCatalog": {
"@@type": "OfferCatalog",
"name": "Web Development Offer Catalog",
"itemListElement": [
{
"@@type": "Offer",
"itemOffered": {
"@@type": "Service",
"name": "Single Page Application (SPA)"
}
},
{
"@@type": "Offer",
"itemOffered": {
"@@type": "Service",
"name": "Progressive Web App (PWA)"
}
},
{
"@@type": "Offer",
"itemOffered": {
"@@type": "Service",
"name": "API & Web Service Integration"
}
},
{
"@@type": "Offer",
"itemOffered": {
"@@type": "Service",
"name": "3D Web Development (Three.js)"
}
}
]
}
}
]
}
</script>
@endpush
@push('styles')
@@ -32,10 +136,10 @@
transform: translateY(-8px) scale(1.03);
box-shadow: 0 1.25rem 2.5rem rgba(116, 126, 209, 0.12) !important;
}
.tech-card svg {
.tech-card img {
transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.tech-card:hover svg {
.tech-card:hover img {
transform: rotate(10deg) scale(1.1);
}
@@ -124,11 +228,81 @@
.web-dev-illustration--cta {
max-width: 32rem;
}
/* Preloader Styling with Smooth Easing */
.page-preloader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ffffff;
z-index: 99999;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.8s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.8s cubic-bezier(0.77, 0, 0.175, 1);
opacity: 1;
visibility: visible;
}
.page-preloader.fade-out {
opacity: 0;
visibility: hidden;
}
.preloader-content {
text-align: center;
}
.spinner-dot-container {
display: flex;
justify-content: center;
gap: 8px;
margin-bottom: 15px;
}
.spinner-dot {
width: 12px;
height: 12px;
background-color: #747ed1;
border-radius: 50%;
animation: preloader-bounce 1.4s infinite ease-in-out both;
}
.spinner-dot:nth-child(1) {
animation-delay: -0.32s;
}
.spinner-dot:nth-child(2) {
animation-delay: -0.16s;
}
@keyframes preloader-bounce {
0%, 80%, 100% {
transform: scale(0);
} 40% {
transform: scale(1.0);
}
}
.preloader-text {
font-family: 'Outfit', sans-serif;
font-size: 0.95rem;
font-weight: 500;
color: #74788d;
letter-spacing: 0.05rem;
text-transform: uppercase;
}
</style>
@endpush
@section('content')
{{-- Easing Preloader --}}
<div id="page-preloader" class="page-preloader">
<div class="preloader-content">
<div class="spinner-dot-container">
<div class="spinner-dot"></div>
<div class="spinner-dot"></div>
<div class="spinner-dot"></div>
</div>
<div class="preloader-text">{!! t('Yükleniyor...') !!}</div>
</div>
</div>
@php
$featureBgColors = [
'#f0f2fd', '#fbf1f4', '#fdf3e7', '#edf9f6',
@@ -430,13 +604,13 @@
<div class="flex flex-wrap mx-[-15px] xl:mx-[-20px] lg:mx-[-20px] md:mx-[-20px] !mt-[-40px] justify-center">
@foreach($technologies as $tech)
<div class="md:w-6/12 lg:w-3/12 xl:w-3/12 w-full flex-[0_0_auto] !px-[15px] xl:!px-[20px] lg:!px-[20px] md:!px-[20px] !mt-[40px] max-w-full">
<div class="card tech-card h-full !shadow-[0_0.25rem_1.75rem_rgba(30,34,40,0.05)] border-0 flex flex-col justify-between !rounded-[0.8rem]">
<div class="card-body p-[30px] flex flex-col items-center text-center">
<div class="w-16 h-16 flex items-center justify-center !rounded-[100%] !mb-4" style="background-color: {{ $tech['bg'] }};">
<div class="card tech-card h-full !shadow-[0_0.25rem_1.75rem_rgba(30,34,40,0.05)] border-0 flex flex-col justify-between !rounded-[1.2rem] overflow-hidden">
<div class="card-body !p-8 md:!p-10 flex flex-col items-center text-center">
<div class="w-16 h-16 flex items-center justify-center !rounded-[100%] !mb-5" style="background-color: {{ $tech['bg'] }};">
<img src="{{ asset('assets/img/tech-logos/' . $tech['icon']) }}" class="w-8 h-8 object-contain" alt="{{ $tech['name'] }}" loading="lazy" decoding="async">
</div>
<h4 class="!text-[1.1rem] !font-bold !mb-2">{{ $tech['name'] }}</h4>
<p class="!text-[0.825rem] !mb-0 text-muted">{!! t($tech['desc']) !!}</p>
<h4 class="!text-[1.15rem] !font-bold !mb-2">{{ $tech['name'] }}</h4>
<p class="!text-[0.85rem] !mb-0 text-muted">{!! t($tech['desc']) !!}</p>
</div>
</div>
</div>
@@ -458,12 +632,12 @@
<div class="flex flex-wrap mx-[-15px] !mb-28">
@foreach($capabilities as $index => $cap)
<div class="md:w-6/12 lg:w-4/12 xl:w-4/12 w-full flex-[0_0_auto] !px-[15px] !mt-6 max-w-full">
<div class="card h-full !shadow-[0_0.25rem_1.75rem_rgba(30,34,40,0.06)] flex flex-col justify-between">
<div class="card-body p-[40px] flex-[1_1_auto] flex flex-col">
<div class="card h-full !shadow-[0_0.25rem_1.75rem_rgba(30,34,40,0.06)] border-0 flex flex-col justify-between !rounded-[1.2rem] overflow-hidden">
<div class="card-body !p-8 md:!p-10 flex-[1_1_auto] flex flex-col">
<div class="icon btn btn-circle btn-lg btn-soft-purple pointer-events-none !mb-4 xl:!text-[1.3rem] w-12 h-12 !inline-flex !items-center !justify-center !leading-none !p-0 !rounded-[100%]">
<i class="uil {{ $cap['icon'] }}"></i>
</div>
<h4 class="!text-[1.1rem] !font-bold !mb-2">{!! t($cap['title']) !!}</h4>
<h4 class="!text-[1.15rem] !font-bold !mb-2">{!! t($cap['title']) !!}</h4>
<p class="!text-[0.85rem] !mb-0 text-muted flex-1">{!! t($cap['description']) !!}</p>
</div>
</div>
@@ -632,8 +806,8 @@
<div class="flex flex-wrap mx-[-15px] isotope !mt-[-30px]">
@foreach($testimonials as $testimonial)
<div class="item md:w-6/12 lg:w-6/12 xl:w-6/12 w-full flex-[0_0_auto] !px-[15px] max-w-full !mt-[30px]">
<div class="card !shadow-none !rounded-[0.8rem]" style="background-color: {{ $testimonial['bg'] }};">
<div class="card-body flex-[1_1_auto] p-[40px]">
<div class="card !shadow-none !rounded-[1.2rem] overflow-hidden" style="background-color: {{ $testimonial['bg'] }};">
<div class="card-body flex-[1_1_auto] !p-8 md:!p-10">
<blockquote class="!text-[0.875rem] !leading-[1.7] !font-normal !pl-4 icon !mb-0 relative p-0 border-0 before:content-['\201d'] before:absolute before:top-[-1.5rem] before:left-[-0.9rem] before:text-[rgba(52,63,82,0.05)] before:text-[10rem] before:leading-none before:z-[1]">
<p class="!mb-4">{!! t($testimonial['quote']) !!}</p>
<div class="flex items-center text-left">
@@ -690,4 +864,24 @@
</div>
</section>
@push('scripts')
<script>
document.addEventListener("DOMContentLoaded", function() {
const preloader = document.getElementById('page-preloader');
if (preloader) {
window.addEventListener('load', function() {
setTimeout(function() {
preloader.classList.add('fade-out');
}, 200);
});
// Fallback in case load event already fired or is delayed
setTimeout(function() {
preloader.classList.add('fade-out');
}, 2500);
}
});
</script>
@endpush
@endsection