feat: implement internship application wizard with terms acceptance and multi-step form view

This commit is contained in:
Ümit Tunç
2026-06-01 23:43:59 +03:00
parent 23f24e426b
commit 36ec1823c8
7 changed files with 491 additions and 118 deletions
+9
View File
@@ -121,4 +121,13 @@ return [
'mermaid_dec4' => 'هل تمت الموافقة على المهمة؟', 'mermaid_dec4' => 'هل تمت الموافقة على المهمة؟',
'mermaid_feedback' => 'طلب تصحيح وتعليقات', 'mermaid_feedback' => 'طلب تصحيح وتعليقات',
'mermaid_payment' => 'يتم دفع الرسوم', 'mermaid_payment' => 'يتم دفع الرسوم',
// Internship Wizard keys
'dear_intern' => 'عزيزي المرشح للمتدرب،',
'intern_welcome_text_1' => 'بصفتنا Trunçgil Technology، نحن فخورون بالمساهمة في تطوير المواهب الشابة من خلال برنامج التدريب عن بعد. نحن نقيّم المتدربين لدينا في مشاريع حقيقية، ونوفر لهم تجربة فريدة من نوعها في العمل عن بعد وتنسيق الفريق.',
'intern_welcome_text_2' => 'لكي يتم تقييم طلبك، يجب عليك أولاً مراجعة نموذج العمل وشروط التقديم لدينا، ثم ملء النموذج بالكامل عن طريق قبول شروط طلب التدريب.',
'intern_terms_accept_label' => 'لقد قرأت نموذج عمل التدريب عن بعد وشروط التقديم وتدفق عملية الموارد البشرية وأوافق عليها.',
'accept_intern_terms_btn' => 'قبول الشروط والانتقال إلى استمارة الطلب',
'intern_step_1_title' => '1. الشروط والأحكام',
'intern_step_2_title' => '2. أكمل التطبيق',
]; ];
+9
View File
@@ -130,4 +130,13 @@ return [
'mermaid_dec4' => 'Aufgabe freigegeben?', 'mermaid_dec4' => 'Aufgabe freigegeben?',
'mermaid_feedback' => 'Korrekturanforderung und Feedback', 'mermaid_feedback' => 'Korrekturanforderung und Feedback',
'mermaid_payment' => 'Zahlung wird geleistet', 'mermaid_payment' => 'Zahlung wird geleistet',
// Internship Wizard keys
'dear_intern' => 'Sehr geehrter Praktikantenkandidat,',
'intern_welcome_text_1' => 'Als Trunçgil Technology sind wir stolz darauf, durch unser Remote-Praktikumsprogramm zur Entwicklung junger Talente beizutragen. Wir bewerten unsere Praktikanten in realen Projekten und bieten ihnen eine einzigartige Erfahrung in der Remote-Arbeit und Teamkoordination.',
'intern_welcome_text_2' => 'Damit Ihre Bewerbung bewertet werden kann, müssen Sie zunächst unser Arbeitsmodell und unsere Bewerbungsbedingungen prüfen und dann das Formular durch Akzeptieren der Praktikumsbewerbungsbedingungen vollständig ausfüllen.',
'intern_terms_accept_label' => 'Ich habe das Arbeitsmodell des Remote-Praktikums, die Bewerbungsbedingungen und den HR-Prozessablauf gelesen und akzeptiere sie.',
'accept_intern_terms_btn' => 'Bedingungen akzeptieren und zum Bewerbungsformular fortfahren',
'intern_step_1_title' => '1. Geschäftsbedingungen',
'intern_step_2_title' => '2. Bewerbung abschließen',
]; ];
+9
View File
@@ -130,4 +130,13 @@ return [
'mermaid_dec4' => 'Is Task Approved?', 'mermaid_dec4' => 'Is Task Approved?',
'mermaid_feedback' => 'Revision Request and Feedback', 'mermaid_feedback' => 'Revision Request and Feedback',
'mermaid_payment' => 'Fee Payment is Made', 'mermaid_payment' => 'Fee Payment is Made',
// Internship Wizard keys
'dear_intern' => 'Dear Intern Candidate,',
'intern_welcome_text_1' => 'As Trunçgil Technology, we are proud to contribute to the development of young talents through our remote internship program. We evaluate our interns in real projects, providing them with a unique remote working and team coordination experience.',
'intern_welcome_text_2' => 'In order for your application to be evaluated, you must first review our working model and application conditions, and then fill out the form completely by accepting the internship application terms.',
'intern_terms_accept_label' => 'I have read and accept the remote internship working model, application conditions, and the HR process flow.',
'accept_intern_terms_btn' => 'Accept Terms and Proceed to Application Form',
'intern_step_1_title' => '1. Terms & Conditions',
'intern_step_2_title' => '2. Complete Application',
]; ];
+9
View File
@@ -130,4 +130,13 @@ return [
'mermaid_dec4' => 'Задача одобрена?', 'mermaid_dec4' => 'Задача одобрена?',
'mermaid_feedback' => 'Запрос на доработку и обратная связь', 'mermaid_feedback' => 'Запрос на доработку и обратная связь',
'mermaid_payment' => 'Производится выплата вознаграждения', 'mermaid_payment' => 'Производится выплата вознаграждения',
// Internship Wizard keys
'dear_intern' => 'Уважаемый кандидат на стажировку,',
'intern_welcome_text_1' => 'Как компания Trunçgil Technology, мы гордимся тем, что вносим вклад в развитие молодых талантов в рамках нашей программы дистанционной стажировки. Мы привлекаем стажеров к реальным проектам, давая им уникальный опыт удаленной работы и координации в команде.',
'intern_welcome_text_2' => 'Для оценки вашей заявки вам необходимо сначала ознакомиться с нашей моделью работы и условиями стажировки, а затем полностью заполнить форму, подтвердив согласие с условиями.',
'intern_terms_accept_label' => 'Я ознакомился с моделью дистанционной стажировки, условиями подачи заявки и этапами подбора персонала и принимаю их.',
'accept_intern_terms_btn' => 'Принять условия и перейти к анкете',
'intern_step_1_title' => '1. Правила и условия',
'intern_step_2_title' => '2. Завершить подачу',
]; ];
+9
View File
@@ -130,4 +130,13 @@ return [
'mermaid_dec4' => 'Är uppdraget godkänt?', 'mermaid_dec4' => 'Är uppdraget godkänt?',
'mermaid_feedback' => 'Begäran om korrigering och feedback', 'mermaid_feedback' => 'Begäran om korrigering och feedback',
'mermaid_payment' => 'Arvode betalas ut', 'mermaid_payment' => 'Arvode betalas ut',
// Internship Wizard keys
'dear_intern' => 'Bästa praktikantkandidat,',
'intern_welcome_text_1' => 'Som Trunçgil Technology är vi stolta över att bidra till utvecklingen av unga talanger genom vårt distanspraktikprogram. Vi utvärderar våra praktikanter i verkliga projekt och ger dem en unik erfarenhet av distansarbete och teamkoordinering.',
'intern_welcome_text_2' => 'För att din ansökan ska kunna utvärderas måste du först granska vår arbetsmodell och ansökningsvillkor, och sedan fylla i formuläret fullständigt genom att acceptera villkoren för praktikansökan.',
'intern_terms_accept_label' => 'Jag har läst och godkänner arbetsmodellen för distanspraktik, ansökningsvillkoren och HR-processflödet.',
'accept_intern_terms_btn' => 'Godkänn villkoren och gå till ansökningsformuläret',
'intern_step_1_title' => '1. Regler & Villkor',
'intern_step_2_title' => '2. Slutför ansökan',
]; ];
+9
View File
@@ -130,4 +130,13 @@ return [
'mermaid_dec4' => 'Görev Onaylandı mı?', 'mermaid_dec4' => 'Görev Onaylandı mı?',
'mermaid_feedback' => 'Düzeltme Talebi ve Geri Bildirim', 'mermaid_feedback' => 'Düzeltme Talebi ve Geri Bildirim',
'mermaid_payment' => 'Ücret Ödemesi Yapılır', 'mermaid_payment' => 'Ücret Ödemesi Yapılır',
// Internship Wizard keys
'dear_intern' => 'Değerli Stajyer Adayı,',
'intern_welcome_text_1' => 'Trunçgil Teknoloji olarak, uzaktan staj programımız aracılığıyla genç yeteneklerin gelişimine katkıda bulunmaktan gurur duyuyoruz. Stajyerlerimizi gerçek projelerde değerlendirerek onlara eşsiz bir uzaktan çalışma ve ekip koordinasyonu deneyimi kazandırıyoruz.',
'intern_welcome_text_2' => 'Başvurunuzun değerlendirilebilmesi için öncelikle çalışma modelimizi ve başvuru şartlarımızı incelemeniz, ardından staj başvuru şartlarını kabul ederek formu eksiksiz doldurmanız gerekmektedir.',
'intern_terms_accept_label' => 'Uzaktan staj çalışma modelini, başvuru şartlarını ve İK süreç akışını okudum, kabul ediyorum.',
'accept_intern_terms_btn' => 'Şartları Kabul Et ve Başvuru Formuna Geç',
'intern_step_1_title' => '1. Şartlar & Koşullar',
'intern_step_2_title' => '2. Başvuruyu Tamamla',
]; ];
+437 -118
View File
@@ -12,133 +12,245 @@
<section class="wrapper bg-white py-12 lg:py-20"> <section class="wrapper bg-white py-12 lg:py-20">
<div class="container px-4"> <div class="container px-4">
<div class="text-center mb-12"> <!-- Wizard Progress Tracker -->
<h2 class="text-xs uppercase font-bold tracking-widest text-[#e31e24] mb-2">{{ __('career.remote_work_title', ['default' => 'Süreç Nasıl İşliyor?']) }}</h2> <div class="max-w-md mx-auto mb-16">
<h3 class="text-3xl md:text-4xl font-extrabold text-slate-900">{{ __('career.remote_work_title', ['default' => 'Tamamen Uzaktan Staj Deneyimi']) }}</h3> <div class="relative flex items-center justify-between">
</div> <!-- Progress Line -->
<div class="absolute left-0 top-1/2 -translate-y-1/2 w-full h-1 bg-slate-100 -z-10 rounded-full">
<div class="flex flex-col lg:flex-row items-center gap-12 mb-20 max-w-6xl mx-auto"> <div id="wizard-progress-bar" class="h-full bg-[#e31e24] rounded-full transition-all duration-500 w-[0%]"></div>
<div class="w-full lg:w-3/5">
<div class="bg-white p-4 md:p-8 rounded-3xl shadow-2xl border border-slate-100 overflow-hidden flex justify-center">
<pre class="mermaid">
graph TD
A[İnternet Üzerinden Başvuru] --> B{Uzaktan Çalışma Koşulları}
B -- Uygun --> C[CV ve Evrakların İletilmesi]
B -- Uygun Değil --> D[Süreç Sonlandırılır]
C --> E[Ön Değerlendirme]
E --> F[Teknik Görüşme]
F --> G[Projelere Dahil Edilme]
style A fill:#f8fafc,stroke:#cbd5e1,stroke-width:2px
style G fill:#e31e24,stroke:#fff,stroke-width:2px,color:#fff
style B fill:#fff1f2,stroke:#fecdd3
</pre>
</div> </div>
</div>
<div class="w-full lg:w-2/5 space-y-8"> <!-- Step 1 Dot -->
<h4 class="text-2xl font-bold text-slate-900">{{ __('career.application_conditions_title', ['default' => 'Başvuru Şartları ve Çalışma Modeli']) }}</h4> <div class="flex flex-col items-center">
<div class="space-y-6"> <div id="step-dot-1" class="w-12 h-12 rounded-full bg-[#e31e24] text-white flex items-center justify-center font-extrabold shadow-lg shadow-red-500/20 transition-all duration-500 ring-4 ring-red-100">
<div class="flex items-start gap-4"> <i class="uil uil-info-circle text-xl"></i>
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.daily_standup', ['default' => 'Günlük Standup:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.daily_standup_desc', ['default' => 'Her gün düzenlenen kısa toplantılarla ekip içi iletişim ve ilerleme takibi sağlanır.']) }}</p>
</div>
</div> </div>
<div class="flex items-start gap-4"> <span id="step-label-1" class="text-xs md:text-sm font-bold text-slate-800 mt-3 transition-all duration-300">{{ __('career.intern_step_1_title') }}</span>
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]"> </div>
<i class="uil uil-check-circle text-xl"></i>
</div> <!-- Step 2 Dot -->
<div> <div class="flex flex-col items-center">
<span class="font-bold text-slate-800 block text-sm">{{ __('career.flexible_projects', ['default' => 'Esnek Projeler:']) }}</span> <div id="step-dot-2" class="w-12 h-12 rounded-full bg-slate-100 text-slate-400 flex items-center justify-center font-extrabold transition-all duration-500 ring-4 ring-transparent">
<p class="text-sm text-slate-500">{{ __('career.flexible_projects_desc', ['default' => 'Projelerimizde esneklik esastır. Yeteneklerinize uygun gerçek projelerde görev alırsınız.']) }}</p> <i class="uil uil-check-circle text-xl"></i>
</div>
</div>
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.focus_on_development', ['default' => 'Gelişim Odaklılık:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.condition_not_only_for_internship', ['default' => 'Yalnızca staj yapmak için yapmak isteyen kişiler alınmamaktadır.']) }}</p>
</div>
</div>
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.intent_letter', ['default' => 'Niyet Mektubu:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.condition_intent_letter', ['default' => 'Mesaj bölümünde nasıl bir katkı sağlayacağınızın niyet mektubu iletilmelidir.']) }}</p>
</div>
</div> </div>
<span id="step-label-2" class="text-xs md:text-sm font-medium text-slate-400 mt-3 transition-all duration-300">{{ __('career.intern_step_2_title') }}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="max-w-4xl mx-auto"> <!-- Main Form Container -->
<div class="bg-white rounded-[2rem] shadow-2xl overflow-hidden border border-slate-100"> <form action="{{ route('career.store') }}" method="POST" enctype="multipart/form-data" id="career-application-form">
<div class="p-8 md:p-12"> @csrf
<div class="mb-10"> <input type="hidden" name="type" value="internship">
<h2 class="text-2xl font-bold text-slate-900 mb-2">{{ __('career.internship_title') }}</h2>
<div class="w-12 h-1 bg-[#e31e24] rounded-full"></div> <!-- ================= STEP 1: TERMS & CONDITIONS ================= -->
<div id="step-content-1" class="wizard-step transition-all duration-500 opacity-100 block">
<div class="max-w-5xl mx-auto mb-12">
<!-- Welcome Message -->
<div class="bg-blue-50 border-l-4 border-blue-500 p-8 rounded-r-2xl shadow-sm mb-12">
<h4 class="text-xl font-bold text-blue-900 mb-4">{{ __('career.dear_intern') }}</h4>
<div class="text-blue-800 space-y-4 leading-relaxed text-sm md:text-base">
<p>{!! __('career.intern_welcome_text_1') !!}</p>
<p>{!! __('career.intern_welcome_text_2') !!}</p>
</div>
</div> </div>
<form action="{{ route('career.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6" id="career-application-form"> <div class="text-center mb-12">
@csrf <h2 class="text-xs uppercase font-bold tracking-widest text-[#e31e24] mb-2">{{ __('career.remote_work_title', ['default' => 'Süreç Nasıl İşliyor?']) }}</h2>
<input type="hidden" name="type" value="internship"> <h3 class="text-3xl md:text-4xl font-extrabold text-slate-900">{{ __('career.remote_work_title', ['default' => 'Tamamen Uzaktan Staj Deneyimi']) }}</h3>
</div>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<label for="name" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.name', ['default' => 'Ad Soyad']) }} <span class="text-[#e31e24]">*</span></label> <div class="flex flex-col lg:flex-row gap-12 items-start mb-12">
<div class="md:col-span-9"> <!-- Mermaid Flowchart Canvas -->
<input type="text" name="name" id="name" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="Örn: Ahmet Yılmaz" value="{{ old('name') }}" required> <div class="w-full lg:w-3/5">
<div id="mermaid-card" class="relative bg-white p-6 md:p-8 rounded-3xl shadow-xl border border-slate-100 overflow-x-auto flex flex-col items-center">
<!-- Fullscreen Toggle Button -->
<button type="button" onclick="toggleFullscreen()" class="absolute top-4 right-4 p-2.5 rounded-xl bg-slate-50 hover:bg-slate-100 border border-slate-100 hover:border-slate-200 text-slate-500 hover:text-slate-700 transition-all duration-200 shadow-sm flex items-center justify-center z-10" title="Tam Ekran / Fullscreen">
<i id="fullscreen-icon" class="uil uil-expand-arrows-alt text-lg"></i>
</button>
<span class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4"><i class="uil uil-presentation-play mr-1"></i> {{ __('career.hr_flow_diagram') }}</span>
<div class="mermaid w-full flex justify-center" style="min-height: 400px;">
graph TD
%% Styles
classDef startNode fill:#3b82f6,stroke:#1d4ed8,stroke-width:2px,color:#fff,font-weight:bold,rx:10px,ry:10px;
classDef decisionNode fill:#eab308,stroke:#ca8a04,stroke-width:2px,color:#1e293b,font-weight:bold;
classDef processNode fill:#10b981,stroke:#047857,stroke-width:2px,color:#fff,font-weight:bold,rx:5px,ry:5px;
classDef rejectNode fill:#ef4444,stroke:#b91c1c,stroke-width:2px,color:#fff,font-weight:bold,rx:5px,ry:5px;
classDef actionNode fill:#8b5cf6,stroke:#6d28d9,stroke-width:2px,color:#fff,font-weight:bold,rx:5px,ry:5px;
Start["{{ __('career.mermaid_start') }}"]:::startNode
Dec1{"{{ __('career.mermaid_dec1') }}"}:::decisionNode
Red1["{{ __('career.mermaid_red1') }}"]:::rejectNode
GitAccess["{{ __('career.mermaid_git') }}"]:::processNode
SampleTask["{{ __('career.mermaid_sample') }}"]:::processNode
Dec2{"{{ __('career.mermaid_dec2') }}"}:::decisionNode
Red2["{{ __('career.mermaid_red2') }}"]:::rejectNode
Issues["{{ __('career.mermaid_issues') }}"]:::processNode
Dec3{"{{ __('career.mermaid_dec3') }}"}:::decisionNode
WaitTask["{{ __('career.mermaid_wait') }}"]:::actionNode
Assign["{{ __('career.mermaid_assign') }}"]:::processNode
WorkStart["{{ __('career.mermaid_work') }}"]:::processNode
Review["{{ __('career.mermaid_review') }}"]:::processNode
Dec4{"{{ __('career.mermaid_dec4') }}"}:::decisionNode
Feedback["{{ __('career.mermaid_feedback') }}"]:::actionNode
Payment["{{ __('career.mermaid_payment') }}"]:::processNode
Start --> Dec1
Dec1 -- "Hayır" --> Red1
Dec1 -- "Evet" --> GitAccess
GitAccess --> SampleTask
SampleTask --> Dec2
Dec2 -- "Hayır" --> Red2
Dec2 -- "Evet" --> Issues
Issues --> Dec3
Dec3 -- "Hayır" --> WaitTask
Dec3 -- "Evet" --> Assign
Assign --> WorkStart
WorkStart --> Review
Review --> Dec4
Dec4 -- "Hayır" --> Feedback
Feedback --> WorkStart
Dec4 -- "Evet" --> Payment
Payment --> Issues
</div>
</div> </div>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center"> <!-- Conditions & Model Requirements -->
<label for="email" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.email', ['default' => 'E-posta']) }} <span class="text-[#e31e24]">*</span></label> <div class="w-full lg:w-2/5 space-y-8">
<div class="md:col-span-9"> <h4 class="text-2xl font-bold text-slate-900">{{ __('career.application_conditions_title', ['default' => 'Başvuru Şartları ve Çalışma Modeli']) }}</h4>
<input type="email" name="email" id="email" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="Örn: ahmet@example.com" value="{{ old('email') }}" required> <div class="space-y-6">
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.daily_standup', ['default' => 'Günlük Standup:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.daily_standup_desc', ['default' => 'Her gün düzenlenen kısa toplantılarla ekip içi iletişim ve ilerleme takibi sağlanır.']) }}</p>
</div>
</div>
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.flexible_projects', ['default' => 'Esnek Projeler:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.flexible_projects_desc', ['default' => 'Projelerimizde esneklik esastır. Yeteneklerinize uygun gerçek projelerde görev alırsınız.']) }}</p>
</div>
</div>
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.focus_on_development', ['default' => 'Gelişim Odaklılık:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.condition_not_only_for_internship', ['default' => 'Yalnızca staj yapmak için yapmak isteyen kişiler alınmamaktadır.']) }}</p>
</div>
</div>
<div class="flex items-start gap-4">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-red-50 flex items-center justify-center text-[#e31e24]">
<i class="uil uil-check-circle text-xl"></i>
</div>
<div>
<span class="font-bold text-slate-800 block text-sm">{{ __('career.intent_letter', ['default' => 'Niyet Mektubu:']) }}</span>
<p class="text-sm text-slate-500">{{ __('career.condition_intent_letter', ['default' => 'Mesaj bölümünde nasıl bir katkı sağlayacağınızın niyet mektubu iletilmelidir.']) }}</p>
</div>
</div>
</div> </div>
</div>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center"> <!-- Terms Acceptance & Next Trigger -->
<label for="phone" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.phone', ['default' => 'Telefon']) }}</label> <div class="bg-slate-50 p-6 rounded-2xl border border-slate-100 mt-8 space-y-4">
<div class="md:col-span-9"> <div class="flex items-start gap-3">
<input type="text" name="phone" id="phone" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="Örn: 05XX XXX XX XX" value="{{ old('phone') }}"> <input type="checkbox" id="terms-accept-checkbox" class="w-5 h-5 rounded border-slate-300 text-[#e31e24] focus:ring-[#e31e24] mt-1 cursor-pointer">
</div> <label for="terms-accept-checkbox" class="text-sm text-slate-700 font-semibold cursor-pointer">
</div> {{ __('career.intern_terms_accept_label') }} <span class="text-[#e31e24]">*</span>
</label>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center"> </div>
<label for="cv" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.cv', ['default' => 'Özgeçmiş (CV)']) }} <span class="text-[#e31e24]">*</span></label> <button type="button" onclick="nextStep(2)" id="step-1-next-btn" class="w-full py-4 bg-slate-300 text-slate-500 font-bold rounded-xl transition-all flex items-center justify-center gap-2 cursor-not-allowed" disabled>
<div class="md:col-span-9"> <span>{{ __('career.accept_intern_terms_btn') }}</span>
<input type="file" name="cv" id="cv" class="w-full px-5 py-2.5 rounded-xl border border-slate-200 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-[#e31e24] hover:file:bg-red-100 transition-all" required> <i class="uil uil-arrow-right text-lg"></i>
<p class="mt-2 text-xs text-slate-400">PDF, DOC, DOCX (Maks. 5MB)</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start">
<label for="message" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right pt-3">{{ __('career.message', ['default' => 'Mesajınız']) }}</label>
<div class="md:col-span-9">
<textarea name="message" id="message" class="w-full px-5 py-4 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300 min-h-[150px]" placeholder="Staj beklentileriniz ve çalışma alanlarınız hakkında bilgi verebilirsiniz...">{{ old('message') }}</textarea>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-12 gap-6">
<div class="md:col-start-4 md:col-span-9">
<button type="submit" id="submit-btn" class="w-full md:w-auto px-10 py-4 bg-[#e31e24] hover:bg-[#c4191f] text-white font-bold rounded-full transition-all shadow-lg shadow-red-500/30 flex items-center justify-center gap-3">
<span class="btn-text">{{ __('career.submit', ['default' => 'Başvuruyu Gönder']) }}</span>
<span class="spinner-border spinner-border-sm hidden animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full" role="status"></span>
<i class="uil uil-arrow-right text-xl btn-icon"></i>
</button> </button>
</div> </div>
</div> </div>
</form> </div>
</div> </div>
</div> </div>
</div>
<!-- ================= STEP 2: COMPLETE APPLICATION ================= -->
<div id="step-content-2" class="wizard-step transition-all duration-500 opacity-0 hidden">
<div class="max-w-4xl mx-auto">
<div class="bg-white rounded-[2rem] shadow-2xl overflow-hidden border border-slate-100">
<div class="p-8 md:p-12">
<div class="mb-10 text-center">
<h2 class="text-3xl font-bold text-slate-900 mb-2">{{ __('career.form_title') }}</h2>
<p class="text-slate-500">{{ __('career.form_subtitle') }}</p>
<div class="w-12 h-1 bg-[#e31e24] rounded-full mx-auto mt-4"></div>
</div>
<div class="space-y-6">
<!-- Name -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<label for="name" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.name') }} <span class="text-[#e31e24]">*</span></label>
<div class="md:col-span-9">
<input type="text" name="name" id="name" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="{{ __('career.name_placeholder') }}" value="{{ old('name') }}" required>
</div>
</div>
<!-- Email -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<label for="email" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.email') }} <span class="text-[#e31e24]">*</span></label>
<div class="md:col-span-9">
<input type="email" name="email" id="email" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="{{ __('career.email_placeholder') }}" value="{{ old('email') }}" required>
</div>
</div>
<!-- Phone -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<label for="phone" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.phone') }}</label>
<div class="md:col-span-9">
<input type="text" name="phone" id="phone" class="w-full px-5 py-3 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300" placeholder="{{ __('career.phone_placeholder') }}" value="{{ old('phone') }}">
</div>
</div>
<!-- CV Upload -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<label for="cv" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right">{{ __('career.cv') }} <span class="text-[#e31e24]">*</span></label>
<div class="md:col-span-9">
<input type="file" name="cv" id="cv" class="w-full px-5 py-2.5 rounded-xl border border-slate-200 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-xs file:font-semibold file:bg-red-50 file:text-[#e31e24] hover:file:bg-red-100 transition-all" required>
<p class="mt-2 text-xs text-slate-400">{{ __('career.cv_description') }}</p>
</div>
</div>
<!-- Message / Intent Letter -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start">
<label for="message" class="md:col-span-3 text-sm font-bold text-slate-700 md:text-right pt-3">{{ __('career.message') }}</label>
<div class="md:col-span-9">
<textarea name="message" id="message" class="w-full px-5 py-4 rounded-xl border border-slate-200 focus:ring-4 focus:ring-red-500/10 focus:border-[#e31e24] outline-none transition-all placeholder-slate-300 min-h-[150px]" placeholder="Staj beklentileriniz ve çalışma alanlarınız hakkında bilgi verebilirsiniz...">{{ old('message') }}</textarea>
</div>
</div>
<!-- Step 2 Navigation -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 pt-6 border-t border-slate-100">
<div class="md:col-start-4 md:col-span-9 flex items-center justify-between gap-4">
<button type="button" onclick="prevStep(1)" class="px-6 py-4 bg-slate-100 hover:bg-slate-200 text-slate-700 font-bold rounded-xl transition-all flex items-center gap-2">
<i class="uil uil-arrow-left text-lg"></i>
<span>{{ __('career.go_back') }}</span>
</button>
<button type="submit" id="submit-btn" class="flex-1 md:flex-none px-10 py-4 bg-[#e31e24] hover:bg-[#c4191f] text-white font-bold rounded-full transition-all shadow-lg shadow-red-500/30 flex items-center justify-center gap-3">
<span class="btn-text">{{ __('career.submit') }}</span>
<span class="spinner-border spinner-border-sm hidden animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full" role="status"></span>
<i class="uil uil-arrow-right text-xl btn-icon"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div> </div>
</section> </section>
@@ -200,6 +312,16 @@
outline: none; outline: none;
} }
input[type="checkbox"] {
-webkit-appearance: checkbox !important;
appearance: checkbox !important;
width: 1.25rem !important;
height: 1.25rem !important;
accent-color: var(--citrus-red);
cursor: pointer;
margin-top: 0;
}
.bg-soft-primary { .bg-soft-primary {
background: linear-gradient(135deg, #f0f7ff 0%, #e8f1ff 100%) !important; background: linear-gradient(135deg, #f0f7ff 0%, #e8f1ff 100%) !important;
} }
@@ -238,22 +360,210 @@
padding-left: 2rem; padding-left: 2rem;
position: relative; position: relative;
} }
/* Mermaid diagram readability and aesthetics */
.mermaid .nodeLabel,
.mermaid .node text,
.mermaid text,
.mermaid .node .label {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 1px rgba(0, 0, 0, 0.2) !important;
padding: 2px 8px !important;
}
.mermaid .node.decisionNode .nodeLabel,
.mermaid .node.decisionNode text,
.mermaid .node.decisionNode .label {
text-shadow: none !important;
color: #1e293b !important;
}
.mermaid svg {
filter: drop-shadow(0px 10px 20px rgba(15, 23, 42, 0.05));
}
/* Fullscreen styles for card container */
#mermaid-card:fullscreen,
#mermaid-card:-webkit-full-screen,
#mermaid-card:-ms-fullscreen {
background-color: #ffffff !important;
padding: 3rem 2rem !important;
display: flex !important;
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
overflow: auto !important;
border-radius: 0px !important;
width: 100% !important;
height: 100% !important;
}
</style> </style>
@endpush @endpush
@push('scripts') @push('scripts')
<script type="module"> <script src="https://cdn.jsdelivr.net/npm/mermaid@10.2.4/dist/mermaid.min.js"></script>
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'; <script>
mermaid.initialize({ // Initialize Mermaid
startOnLoad: true, mermaid.initialize({
theme: 'default', startOnLoad: false,
theme: 'neutral',
securityLevel: 'loose',
flowchart: { flowchart: {
useMaxWidth: true, useMaxWidth: true,
htmlLabels: true, htmlLabels: true
curve: 'basis'
} }
}); });
// Run mermaid after all fonts are fully loaded to ensure boxes match the text dimensions perfectly
if (document.fonts) {
document.fonts.ready.then(function() {
mermaid.run({
nodes: document.querySelectorAll('.mermaid')
});
});
} else {
window.addEventListener('load', function() {
mermaid.run({
nodes: document.querySelectorAll('.mermaid')
});
});
}
// Fullscreen toggle logic for Mermaid card
function toggleFullscreen() {
const card = document.getElementById('mermaid-card');
const icon = document.getElementById('fullscreen-icon');
if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
if (card.requestFullscreen) {
card.requestFullscreen();
} else if (card.webkitRequestFullscreen) { /* Safari */
card.webkitRequestFullscreen();
} else if (card.msRequestFullscreen) { /* IE11 */
card.msRequestFullscreen();
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
}
// Handle icon sync on fullscreen change
function handleFullscreenChange() {
const icon = document.getElementById('fullscreen-icon');
if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
icon.className = "uil uil-shrink text-lg";
} else {
icon.className = "uil uil-expand-arrows-alt text-lg";
}
}
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
document.addEventListener('msfullscreenchange', handleFullscreenChange);
// Step variables
let currentStep = 1;
// Track Terms checkbox to enable Step 1 Next button
document.getElementById('terms-accept-checkbox').addEventListener('change', function(e) {
const nextBtn = document.getElementById('step-1-next-btn');
if (e.target.checked) {
nextBtn.disabled = false;
nextBtn.classList.remove('bg-slate-300', 'text-slate-500', 'cursor-not-allowed');
nextBtn.classList.add('bg-[#e31e24]', 'text-white', 'hover:bg-[#c4191f]', 'shadow-lg', 'shadow-red-500/20');
} else {
nextBtn.disabled = true;
nextBtn.classList.add('bg-slate-300', 'text-slate-500', 'cursor-not-allowed');
nextBtn.classList.remove('bg-[#e31e24]', 'text-white', 'hover:bg-[#c4191f]', 'shadow-lg', 'shadow-red-500/20');
}
});
function updateProgressBar() {
const progressPercent = ((currentStep - 1) / 1) * 100;
document.getElementById('wizard-progress-bar').style.width = `${progressPercent}%`;
// Reset indicator classes
for (let i = 1; i <= 2; i++) {
const dot = document.getElementById(`step-dot-${i}`);
const label = document.getElementById(`step-label-${i}`);
if (i < currentStep) {
// Completed Step
dot.className = "w-12 h-12 rounded-full bg-emerald-500 text-white flex items-center justify-center font-extrabold shadow-lg shadow-emerald-500/20 ring-4 ring-emerald-100 transition-all duration-500";
dot.innerHTML = `<i class="uil uil-check text-xl"></i>`;
label.className = "text-xs md:text-sm font-bold text-slate-800 mt-3";
} else if (i === currentStep) {
// Active Step
dot.className = "w-12 h-12 rounded-full bg-[#e31e24] text-white flex items-center justify-center font-extrabold shadow-lg shadow-red-500/20 ring-4 ring-red-100 transition-all duration-500";
if (i === 1) dot.innerHTML = `<i class="uil uil-info-circle text-xl"></i>`;
if (i === 2) dot.innerHTML = `<i class="uil uil-check-circle text-xl"></i>`;
label.className = "text-xs md:text-sm font-bold text-slate-800 mt-3";
} else {
// Pending Step
dot.className = "w-12 h-12 rounded-full bg-slate-100 text-slate-400 flex items-center justify-center font-extrabold ring-4 ring-transparent transition-all duration-500";
if (i === 2) dot.innerHTML = `<i class="uil uil-check-circle text-xl"></i>`;
label.className = "text-xs md:text-sm font-medium text-slate-400 mt-3";
}
}
}
function nextStep(step) {
if (step === 2 && !document.getElementById('terms-accept-checkbox').checked) {
return;
}
// Hide current step content with nice fade animation
const currentStepEl = document.getElementById(`step-content-${currentStep}`);
currentStepEl.classList.remove('opacity-100');
currentStepEl.classList.add('opacity-0');
setTimeout(() => {
currentStepEl.classList.add('hidden');
// Show next step content
const nextStepEl = document.getElementById(`step-content-${step}`);
nextStepEl.classList.remove('hidden');
// Force repaint to trigger animation
nextStepEl.offsetHeight;
nextStepEl.classList.remove('opacity-0');
nextStepEl.classList.add('opacity-100');
currentStep = step;
updateProgressBar();
window.scrollTo({ top: document.querySelector('.wrapper').offsetTop - 50, behavior: 'smooth' });
}, 200);
}
function prevStep(step) {
const currentStepEl = document.getElementById(`step-content-${currentStep}`);
currentStepEl.classList.remove('opacity-100');
currentStepEl.classList.add('opacity-0');
setTimeout(() => {
currentStepEl.classList.add('hidden');
const prevStepEl = document.getElementById(`step-content-${step}`);
prevStepEl.classList.remove('hidden');
prevStepEl.offsetHeight;
prevStepEl.classList.remove('opacity-0');
prevStepEl.classList.add('opacity-100');
currentStep = step;
updateProgressBar();
window.scrollTo({ top: document.querySelector('.wrapper').offsetTop - 50, behavior: 'smooth' });
}, 200);
}
</script> </script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
@@ -306,6 +616,10 @@ document.addEventListener('DOMContentLoaded', function() {
confirmButtonText: '{{ __("career.ok") ?? "Tamam" }}' confirmButtonText: '{{ __("career.ok") ?? "Tamam" }}'
}).then(() => { }).then(() => {
form.reset(); form.reset();
// Go back to step 1
document.getElementById('terms-accept-checkbox').checked = false;
document.getElementById('terms-accept-checkbox').dispatchEvent(new Event('change'));
prevStep(1);
}); });
} else if (result.type === 'validation') { } else if (result.type === 'validation') {
Object.keys(result.errors).forEach(key => { Object.keys(result.errors).forEach(key => {
@@ -313,9 +627,14 @@ document.addEventListener('DOMContentLoaded', function() {
if (input) { if (input) {
input.classList.add('is-invalid'); input.classList.add('is-invalid');
const errorDiv = document.createElement('div'); const errorDiv = document.createElement('div');
errorDiv.className = 'invalid-feedback text-start d-block'; errorDiv.className = 'invalid-feedback text-start text-xs text-red-500 mt-1 block';
errorDiv.textContent = result.errors[key][0]; errorDiv.textContent = result.errors[key][0];
input.closest('.md\\:col-span-9')?.appendChild(errorDiv) || input.closest('.col-md-9')?.appendChild(errorDiv);
if (input.type === 'checkbox') {
input.closest('.flex').parentNode.appendChild(errorDiv);
} else {
input.parentNode.appendChild(errorDiv);
}
} }
}); });