Compare commits
3 Commits
d0292af20c
...
2026-july
| Author | SHA1 | Date | |
|---|---|---|---|
| 161d1c86bc | |||
| 4af8900a78 | |||
| abcf105d07 |
@@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class ResetUserPassword extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'user:reset-password {email? : Kullanıcının e-posta adresi} {password? : Yeni şifre (Belirtilmezse etkileşimli olarak istenir veya otomatik oluşturulur)}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Belirtilen kullanıcının şifresini günceller';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
// E-posta adresini al veya sor
|
||||||
|
$email = $this->argument('email') ?: $this->ask('Kullanıcının e-posta adresini giriniz:');
|
||||||
|
|
||||||
|
if (empty($email)) {
|
||||||
|
$this->error('E-posta adresi boş olamaz!');
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Email formatını kontrol et
|
||||||
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$this->error('Geçersiz e-posta formatı!');
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kullanıcıyı bul
|
||||||
|
$user = User::where('email', $email)->first();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$this->error("E-posta adresi '{$email}' ile kayıtlı kullanıcı bulunamadı!");
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Şifreyi al veya sor ya da rastgele oluştur
|
||||||
|
$password = $this->argument('password');
|
||||||
|
|
||||||
|
if ($password === null) {
|
||||||
|
if ($this->confirm('Yeni şifreyi otomatik rastgele mi üretelim (6 haneli rakamsal)?', true)) {
|
||||||
|
$password = (string) random_int(100000, 999999);
|
||||||
|
} else {
|
||||||
|
$password = $this->secret('Yeni şifreyi giriniz:');
|
||||||
|
if (empty($password)) {
|
||||||
|
$this->error('Şifre boş olamaz!');
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Şifreyi güncelle ve kaydet
|
||||||
|
$user->password = Hash::make($password);
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
$this->info("✓ Kullanıcı '{$user->name}' ({$user->email}) şifresi başarıyla güncellendi!");
|
||||||
|
$this->info("Yeni Şifre: {$password}");
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -510,10 +510,4 @@ class InternApplicationResource extends Resource
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getWidgets(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Widgets\InternGanttChartWidget::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,4 @@ use Filament\Resources\Pages\ListRecords;
|
|||||||
class ListInternApplications extends ListRecords
|
class ListInternApplications extends ListRecords
|
||||||
{
|
{
|
||||||
protected static string $resource = InternApplicationResource::class;
|
protected static string $resource = InternApplicationResource::class;
|
||||||
|
|
||||||
protected function getHeaderWidgets(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
\App\Filament\Admin\Resources\InternApplications\Widgets\InternGanttChartWidget::class,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-174
@@ -1,175 +1,2 @@
|
|||||||
<?php
|
<?php
|
||||||
|
// Bu bileşen devre dışı bırakılmıştır.
|
||||||
namespace App\Filament\Admin\Resources\InternApplications\Widgets;
|
|
||||||
|
|
||||||
use App\Models\CareerApplication;
|
|
||||||
use Filament\Widgets\Widget;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
|
|
||||||
class InternGanttChartWidget extends Widget
|
|
||||||
{
|
|
||||||
protected string $view = 'filament.admin.resources.intern-applications.widgets.intern-gantt-chart-widget';
|
|
||||||
|
|
||||||
protected int | string | array $columnSpan = 'full';
|
|
||||||
|
|
||||||
public function getViewData(): array
|
|
||||||
{
|
|
||||||
$interns = CareerApplication::query()
|
|
||||||
->where('type', 'internship')
|
|
||||||
->where('status', 'accepted')
|
|
||||||
->whereNotNull('internship_start_date')
|
|
||||||
->whereNotNull('internship_end_date')
|
|
||||||
->orderBy('internship_start_date', 'asc')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
if ($interns->isEmpty()) {
|
|
||||||
return [
|
|
||||||
'interns' => [],
|
|
||||||
'months' => [],
|
|
||||||
'totalDays' => 0,
|
|
||||||
'minDate' => null,
|
|
||||||
'todayPercent' => null,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$minDate = Carbon::parse($interns->min('internship_start_date'))->startOfDay();
|
|
||||||
$maxDate = Carbon::parse($interns->max('internship_end_date'))->endOfDay();
|
|
||||||
|
|
||||||
// Pad the range slightly for better visual presentation
|
|
||||||
$minDate = $minDate->copy()->subDays(5);
|
|
||||||
$maxDate = $maxDate->copy()->addDays(5);
|
|
||||||
|
|
||||||
$totalDays = $minDate->diffInDays($maxDate);
|
|
||||||
if ($totalDays <= 0) {
|
|
||||||
$totalDays = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate months in range
|
|
||||||
$months = [];
|
|
||||||
$tempDate = $minDate->copy()->startOfMonth();
|
|
||||||
$endLimit = $maxDate->copy()->endOfMonth();
|
|
||||||
|
|
||||||
while ($tempDate->lte($endLimit)) {
|
|
||||||
$monthStart = $tempDate->copy()->startOfMonth();
|
|
||||||
$monthEnd = $tempDate->copy()->endOfMonth();
|
|
||||||
|
|
||||||
$overlapStart = $monthStart->gt($minDate) ? $monthStart : $minDate;
|
|
||||||
$overlapEnd = $monthEnd->lt($maxDate) ? $monthEnd : $maxDate;
|
|
||||||
|
|
||||||
if ($overlapStart->lte($overlapEnd)) {
|
|
||||||
$daysInOverlap = $overlapStart->diffInDays($overlapEnd) + 1;
|
|
||||||
$startOffset = $minDate->diffInDays($overlapStart);
|
|
||||||
$months[] = [
|
|
||||||
'name' => $tempDate->translatedFormat('F Y'),
|
|
||||||
'left' => ($startOffset / $totalDays) * 100,
|
|
||||||
'width' => ($daysInOverlap / $totalDays) * 100,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$tempDate->addMonth();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate today's line position if it falls within the range
|
|
||||||
$today = Carbon::today();
|
|
||||||
$todayPercent = null;
|
|
||||||
if ($today->between($minDate, $maxDate)) {
|
|
||||||
$todayPercent = ($minDate->diffInDays($today) / $totalDays) * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
$formattedInterns = $interns->map(function ($intern) use ($minDate, $totalDays) {
|
|
||||||
$start = Carbon::parse($intern->internship_start_date)->startOfDay();
|
|
||||||
$end = Carbon::parse($intern->internship_end_date)->endOfDay();
|
|
||||||
|
|
||||||
$startOffset = $minDate->diffInDays($start);
|
|
||||||
$duration = $start->diffInDays($end) + 1;
|
|
||||||
|
|
||||||
$left = ($startOffset / $totalDays) * 100;
|
|
||||||
$width = ($duration / $totalDays) * 100;
|
|
||||||
|
|
||||||
// Ensure width is at least a visible sliver
|
|
||||||
if ($width < 1.5) {
|
|
||||||
$width = 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign a stable color palette based on the intern ID
|
|
||||||
$palettes = [
|
|
||||||
[
|
|
||||||
'bg' => 'bg-emerald-500 dark:bg-emerald-600',
|
|
||||||
'gradient' => 'from-emerald-400 to-teal-500 dark:from-emerald-500 dark:to-teal-600',
|
|
||||||
'text' => 'text-emerald-950 dark:text-emerald-50',
|
|
||||||
'border' => 'border-emerald-500/20',
|
|
||||||
'shadow' => 'shadow-emerald-500/20'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'bg' => 'bg-blue-500 dark:bg-blue-600',
|
|
||||||
'gradient' => 'from-blue-400 to-indigo-500 dark:from-blue-500 dark:to-indigo-600',
|
|
||||||
'text' => 'text-blue-950 dark:text-blue-50',
|
|
||||||
'border' => 'border-blue-500/20',
|
|
||||||
'shadow' => 'shadow-blue-500/20'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'bg' => 'bg-rose-500 dark:bg-rose-600',
|
|
||||||
'gradient' => 'from-rose-400 to-pink-500 dark:from-rose-500 dark:to-pink-600',
|
|
||||||
'text' => 'text-rose-950 dark:text-rose-50',
|
|
||||||
'border' => 'border-rose-500/20',
|
|
||||||
'shadow' => 'shadow-rose-500/20'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'bg' => 'bg-amber-500 dark:bg-amber-600',
|
|
||||||
'gradient' => 'from-amber-400 to-orange-500 dark:from-amber-500 dark:to-orange-600',
|
|
||||||
'text' => 'text-amber-950 dark:text-amber-50',
|
|
||||||
'border' => 'border-amber-500/20',
|
|
||||||
'shadow' => 'shadow-amber-500/20'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'bg' => 'bg-violet-500 dark:bg-violet-600',
|
|
||||||
'gradient' => 'from-violet-400 to-purple-500 dark:from-violet-500 dark:to-purple-600',
|
|
||||||
'text' => 'text-violet-950 dark:text-violet-50',
|
|
||||||
'border' => 'border-violet-500/20',
|
|
||||||
'shadow' => 'shadow-violet-500/20'
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$paletteIndex = $intern->id % count($palettes);
|
|
||||||
$color = $palettes[$paletteIndex];
|
|
||||||
|
|
||||||
$startMonth = (int) $start->format('n');
|
|
||||||
$endMonth = (int) $end->format('n');
|
|
||||||
$gridStart = $startMonth + 1;
|
|
||||||
$gridEnd = min(14, $endMonth + 2);
|
|
||||||
|
|
||||||
// Background color map based on user's examples
|
|
||||||
$hexColors = [
|
|
||||||
'#2ecaac', // Emerald Teal
|
|
||||||
'#54c6f9', // Sky Blue
|
|
||||||
'#ff6252', // Red Coral
|
|
||||||
'#f59e0b', // Amber
|
|
||||||
'#8b5cf6', // Violet
|
|
||||||
];
|
|
||||||
$hexColor = $hexColors[$intern->id % count($hexColors)];
|
|
||||||
$isStripes = ($intern->id % 2 === 0);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => $intern->id,
|
|
||||||
'name' => $intern->name,
|
|
||||||
'start_date' => $start->translatedFormat('d M Y'),
|
|
||||||
'end_date' => $end->translatedFormat('d M Y'),
|
|
||||||
'total_days' => $intern->internship_total_days,
|
|
||||||
'left' => $left,
|
|
||||||
'width' => $width,
|
|
||||||
'color' => $color,
|
|
||||||
'grid_start' => $gridStart,
|
|
||||||
'grid_end' => $gridEnd,
|
|
||||||
'hex_color' => $hexColor,
|
|
||||||
'is_stripes' => $isStripes,
|
|
||||||
'raw_start' => $intern->internship_start_date,
|
|
||||||
'raw_end' => $intern->internship_end_date,
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
return [
|
|
||||||
'interns' => $formattedInterns,
|
|
||||||
'months' => $months,
|
|
||||||
'todayPercent' => $todayPercent,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,24 +12,50 @@ class SitemapController extends Controller
|
|||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
$urls = [];
|
$urls = [];
|
||||||
|
$activeLanguages = [];
|
||||||
|
if (class_exists(\App\Models\Language::class)) {
|
||||||
|
$activeLanguages = \App\Models\Language::where('is_active', true)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
$getAlternates = function (string $baseUrl) use ($activeLanguages) {
|
||||||
|
$alternates = [];
|
||||||
|
foreach ($activeLanguages as $lang) {
|
||||||
|
$connector = str_contains($baseUrl, '?') ? '&' : '?';
|
||||||
|
$alternates[] = [
|
||||||
|
'hreflang' => $lang->code,
|
||||||
|
'href' => $baseUrl . $connector . 'locale=' . $lang->code,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$alternates[] = [
|
||||||
|
'hreflang' => 'x-default',
|
||||||
|
'href' => $baseUrl,
|
||||||
|
];
|
||||||
|
return $alternates;
|
||||||
|
};
|
||||||
|
|
||||||
// 1. Static & Main Pages
|
// 1. Static & Main Pages
|
||||||
|
$homeUrl = url('/');
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => url('/'),
|
'loc' => $homeUrl,
|
||||||
|
'alternates' => $getAlternates($homeUrl),
|
||||||
'lastmod' => now()->startOfDay()->toAtomString(),
|
'lastmod' => now()->startOfDay()->toAtomString(),
|
||||||
'changefreq' => 'daily',
|
'changefreq' => 'daily',
|
||||||
'priority' => '1.0',
|
'priority' => '1.0',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$blogIndexUrl = route('blog.index');
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => route('blog.index'),
|
'loc' => $blogIndexUrl,
|
||||||
|
'alternates' => $getAlternates($blogIndexUrl),
|
||||||
'lastmod' => now()->startOfDay()->toAtomString(),
|
'lastmod' => now()->startOfDay()->toAtomString(),
|
||||||
'changefreq' => 'weekly',
|
'changefreq' => 'weekly',
|
||||||
'priority' => '0.8',
|
'priority' => '0.8',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$careerIndexUrl = route('career.index');
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => route('career.index'),
|
'loc' => $careerIndexUrl,
|
||||||
|
'alternates' => $getAlternates($careerIndexUrl),
|
||||||
'lastmod' => now()->startOfMonth()->toAtomString(),
|
'lastmod' => now()->startOfMonth()->toAtomString(),
|
||||||
'changefreq' => 'monthly',
|
'changefreq' => 'monthly',
|
||||||
'priority' => '0.5',
|
'priority' => '0.5',
|
||||||
@@ -40,8 +66,10 @@ class SitemapController extends Controller
|
|||||||
->where('is_homepage', false)
|
->where('is_homepage', false)
|
||||||
->get();
|
->get();
|
||||||
foreach ($pages as $page) {
|
foreach ($pages as $page) {
|
||||||
|
$pageUrl = url($page->slug);
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => url($page->slug),
|
'loc' => $pageUrl,
|
||||||
|
'alternates' => $getAlternates($pageUrl),
|
||||||
'lastmod' => $page->updated_at->toAtomString(),
|
'lastmod' => $page->updated_at->toAtomString(),
|
||||||
'changefreq' => 'weekly',
|
'changefreq' => 'weekly',
|
||||||
'priority' => '0.7',
|
'priority' => '0.7',
|
||||||
@@ -52,8 +80,10 @@ class SitemapController extends Controller
|
|||||||
if (class_exists(Blog::class)) {
|
if (class_exists(Blog::class)) {
|
||||||
$posts = Blog::published()->get();
|
$posts = Blog::published()->get();
|
||||||
foreach ($posts as $post) {
|
foreach ($posts as $post) {
|
||||||
|
$postUrl = route('blog.show', $post->slug);
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => route('blog.show', $post->slug),
|
'loc' => $postUrl,
|
||||||
|
'alternates' => $getAlternates($postUrl),
|
||||||
'lastmod' => $post->updated_at->toAtomString(),
|
'lastmod' => $post->updated_at->toAtomString(),
|
||||||
'changefreq' => 'weekly',
|
'changefreq' => 'weekly',
|
||||||
'priority' => '0.6',
|
'priority' => '0.6',
|
||||||
@@ -65,8 +95,10 @@ class SitemapController extends Controller
|
|||||||
if (class_exists(Product::class)) {
|
if (class_exists(Product::class)) {
|
||||||
$products = Product::where('is_active', true)->get();
|
$products = Product::where('is_active', true)->get();
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
|
$productUrl = route('products.show', $product->slug);
|
||||||
$urls[] = [
|
$urls[] = [
|
||||||
'loc' => route('products.show', $product->slug),
|
'loc' => $productUrl,
|
||||||
|
'alternates' => $getAlternates($productUrl),
|
||||||
'lastmod' => $product->updated_at->toAtomString(),
|
'lastmod' => $product->updated_at->toAtomString(),
|
||||||
'changefreq' => 'weekly',
|
'changefreq' => 'weekly',
|
||||||
'priority' => '0.7',
|
'priority' => '0.7',
|
||||||
|
|||||||
@@ -16,10 +16,25 @@ class SetLocale
|
|||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next): Response
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
// Session'dan locale'i al, yoksa varsayılan dil kodunu kullan
|
// Aktif dilleri veritabanından kontrol et
|
||||||
$locale = session('locale');
|
if (function_exists('available_language_codes')) {
|
||||||
|
$availableLocales = available_language_codes();
|
||||||
|
} else {
|
||||||
|
$availableLocales = ['tr', 'en', 'de', 'ar', 'se', 'ru'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query parametresinden al, yoksa session'dan al
|
||||||
|
$queryLocale = $request->query('locale') ?? $request->query('lang');
|
||||||
|
$locale = null;
|
||||||
|
|
||||||
|
if ($queryLocale && in_array($queryLocale, $availableLocales)) {
|
||||||
|
$locale = $queryLocale;
|
||||||
|
session(['locale' => $locale]);
|
||||||
|
} else {
|
||||||
|
$locale = session('locale');
|
||||||
|
}
|
||||||
|
|
||||||
// Eğer session'da locale yoksa, varsayılan dil kodunu kullan
|
// Eğer locale hala atanmadıysa varsayılan dil kodunu kullan
|
||||||
if (!$locale) {
|
if (!$locale) {
|
||||||
if (function_exists('default_language_code')) {
|
if (function_exists('default_language_code')) {
|
||||||
$locale = default_language_code();
|
$locale = default_language_code();
|
||||||
@@ -28,14 +43,7 @@ class SetLocale
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aktif dilleri veritabanından kontrol et
|
// Locale'i aktif diller arasında kontrol et ve ata
|
||||||
if (function_exists('available_language_codes')) {
|
|
||||||
$availableLocales = available_language_codes();
|
|
||||||
} else {
|
|
||||||
$availableLocales = ['tr', 'en'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locale'i aktif diller arasında kontrol et
|
|
||||||
if (in_array($locale, $availableLocales)) {
|
if (in_array($locale, $availableLocales)) {
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -85,6 +85,13 @@ class AdminPanelProvider extends PanelProvider
|
|||||||
->sort(100); // En sonda görünsün
|
->sort(100); // En sonda görünsün
|
||||||
})->toArray()
|
})->toArray()
|
||||||
])
|
])
|
||||||
|
->navigationItems([
|
||||||
|
\Filament\Navigation\NavigationItem::make('Admin Stajyer Paneli')
|
||||||
|
->url('https://truncgil.com/stajyer/admin/panel')
|
||||||
|
->openUrlInNewTab()
|
||||||
|
->icon('heroicon-o-academic-cap')
|
||||||
|
->sort(1000),
|
||||||
|
])
|
||||||
->assets([
|
->assets([
|
||||||
\Filament\Support\Assets\Css::make('citrus', resource_path('css/citrus.css')),
|
\Filament\Support\Assets\Css::make('citrus', resource_path('css/citrus.css')),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -63,10 +63,42 @@ abstract class StructuredData
|
|||||||
$siteName = static::siteName();
|
$siteName = static::siteName();
|
||||||
|
|
||||||
$node = [
|
$node = [
|
||||||
'@type' => 'Organization',
|
'@type' => 'ProfessionalService',
|
||||||
'@id' => $siteUrl . '#organization',
|
'@id' => $siteUrl . '#organization',
|
||||||
'name' => $siteName,
|
'name' => $siteName,
|
||||||
'url' => $siteUrl,
|
'url' => $siteUrl,
|
||||||
|
'priceRange' => '$$',
|
||||||
|
'geo' => [
|
||||||
|
'@type' => 'GeoCoordinates',
|
||||||
|
'latitude' => 37.025704,
|
||||||
|
'longitude' => 37.296559,
|
||||||
|
],
|
||||||
|
'areaServed' => [
|
||||||
|
[
|
||||||
|
'@type' => 'AdministrativeArea',
|
||||||
|
'name' => 'Gaziantep',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'@type' => 'Country',
|
||||||
|
'name' => 'Turkey',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'knowsAbout' => [
|
||||||
|
'Yazılım Geliştirme',
|
||||||
|
'Web Tasarım',
|
||||||
|
'Mobil Uygulama Geliştirme',
|
||||||
|
'E-Ticaret Sistemleri',
|
||||||
|
'SEO Danışmanlığı',
|
||||||
|
'Gaziantep Yazılım Şirketleri'
|
||||||
|
],
|
||||||
|
'openingHoursSpecification' => [
|
||||||
|
[
|
||||||
|
'@type' => 'OpeningHoursSpecification',
|
||||||
|
'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
|
||||||
|
'opens' => '09:00',
|
||||||
|
'closes' => '18:00',
|
||||||
|
]
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$logo = setting('site_logo');
|
$logo = setting('site_logo');
|
||||||
@@ -93,6 +125,10 @@ abstract class StructuredData
|
|||||||
$node['address'] = [
|
$node['address'] = [
|
||||||
'@type' => 'PostalAddress',
|
'@type' => 'PostalAddress',
|
||||||
'streetAddress' => $address,
|
'streetAddress' => $address,
|
||||||
|
'addressLocality' => 'Şahinbey',
|
||||||
|
'addressRegion' => 'Gaziantep',
|
||||||
|
'postalCode' => '27190',
|
||||||
|
'addressCountry' => 'TR',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
google-site-verification: googlef1M6GQLxVA5g7IaVY6kMQCoIrgADR6HjrOZu79CrXYc.html
|
||||||
+5
-1
@@ -1,2 +1,6 @@
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow:
|
Allow: /
|
||||||
|
Disallow: /admin/
|
||||||
|
Disallow: /stajyer/admin/
|
||||||
|
|
||||||
|
Sitemap: https://truncgil.com/sitemap.xml
|
||||||
|
|||||||
+1
-157
@@ -1,157 +1 @@
|
|||||||
<x-filament-widgets::widget>
|
{{-- Bu bileşen görünümü devre dışı bırakılmıştır. --}}
|
||||||
<!-- DevExtreme Gantt CSS Dependencies -->
|
|
||||||
<link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/23.2.5/css/dx.light.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/23.2.5/css/dx-gantt.css">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.fi-wi-intern-gantt-chart .demo-container {
|
|
||||||
height: 560px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
|
||||||
margin-top: 12px;
|
|
||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03);
|
|
||||||
}
|
|
||||||
.dark .fi-wi-intern-gantt-chart .demo-container {
|
|
||||||
background-color: #111827;
|
|
||||||
border-color: rgba(255, 255, 255, 0.05);
|
|
||||||
}
|
|
||||||
.fi-wi-intern-gantt-chart #gantt {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<x-filament::section class="fi-wi-intern-gantt-chart">
|
|
||||||
<x-slot name="heading">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<span class="text-lg font-bold tracking-tight text-gray-950 dark:text-white">
|
|
||||||
Stajyer Gantt Şeması ve Takvimi
|
|
||||||
</span>
|
|
||||||
<span class="text-xs px-2.5 py-1 bg-emerald-50 text-emerald-600 dark:bg-emerald-950 dark:text-emerald-400 rounded-full font-semibold">
|
|
||||||
DevExtreme Görünümü
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
@if(count($interns) === 0)
|
|
||||||
<div class="flex flex-col items-center justify-center p-8 text-center bg-gray-50 dark:bg-gray-900/40 rounded-xl border border-dashed border-gray-200 dark:border-gray-800">
|
|
||||||
<div class="p-3 bg-gray-100 dark:bg-gray-800 rounded-full mb-3 text-gray-400">
|
|
||||||
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5m-9-6h.008v.008H12v-.008ZM12 15h.008v.008H12V15Zm0 2.25h.008v.008H12v-.008ZM9.75 15h.008v.008H9.75V15Zm0 2.25h.008v.008H9.75v-.008ZM7.5 15h.008v.008H7.5V15Zm0 2.25h.008v.008H7.5v-.008Zm6.75-4.5h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008V15Zm0 2.25h.008v.008h-.008v-.008Zm2.25-4.5h.008v.008H16.5v-.008Zm0 2.25h.008v.008H16.5V15Z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">
|
|
||||||
Tarihleri belirlenmiş onaylı stajyer bulunamadı.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div
|
|
||||||
x-data="{
|
|
||||||
internsData: @js($interns),
|
|
||||||
loadScript(src) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (window.jQuery && src.includes('jquery')) { resolve(); return; }
|
|
||||||
if (window.DevExpress && src.includes('dx.all')) { resolve(); return; }
|
|
||||||
if (window.DevExpress && window.DevExpress.ui && window.DevExpress.ui.dxGantt && src.includes('dx-gantt')) { resolve(); return; }
|
|
||||||
|
|
||||||
const existing = document.querySelector(`script[src='${src}']`);
|
|
||||||
if (existing) {
|
|
||||||
if (existing.readyState === 'loaded' || existing.readyState === 'complete') {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
existing.addEventListener('load', resolve);
|
|
||||||
existing.addEventListener('error', reject);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = src;
|
|
||||||
script.async = true;
|
|
||||||
script.onload = resolve;
|
|
||||||
script.onerror = () => reject(new Error('Failed to load script: ' + src));
|
|
||||||
document.head.appendChild(script);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showError(msg) {
|
|
||||||
const errDiv = document.createElement('div');
|
|
||||||
errDiv.style.color = '#ef4444';
|
|
||||||
errDiv.style.padding = '20px';
|
|
||||||
errDiv.style.fontFamily = 'monospace';
|
|
||||||
errDiv.style.fontSize = '13px';
|
|
||||||
errDiv.innerHTML = '<strong>Gantt Load Error:</strong><br>' + msg;
|
|
||||||
this.$refs.ganttContainer.innerHTML = '';
|
|
||||||
this.$refs.ganttContainer.appendChild(errDiv);
|
|
||||||
},
|
|
||||||
async init() {
|
|
||||||
try {
|
|
||||||
await this.loadScript('https://code.jquery.com/jquery-3.7.1.min.js').catch(() => { throw new Error('jQuery failed to load'); });
|
|
||||||
await this.loadScript('https://cdn3.devexpress.com/jslib/23.2.5/js/dx.all.js').catch(() => { throw new Error('dx.all.js failed to load'); });
|
|
||||||
await this.loadScript('https://cdn3.devexpress.com/jslib/23.2.5/js/dx-gantt.min.js').catch(() => { throw new Error('dx-gantt.min.js failed to load'); });
|
|
||||||
|
|
||||||
if (window.jQuery && window.jQuery.fn.dxGantt) {
|
|
||||||
const formattedData = this.internsData.map(intern => ({
|
|
||||||
id: intern.id,
|
|
||||||
parentId: 0,
|
|
||||||
title: intern.name,
|
|
||||||
start: new Date(intern.raw_start),
|
|
||||||
end: new Date(intern.raw_end),
|
|
||||||
progress: 100
|
|
||||||
}));
|
|
||||||
|
|
||||||
jQuery(this.$refs.ganttContainer).dxGantt({
|
|
||||||
tasks: {
|
|
||||||
dataSource: formattedData,
|
|
||||||
},
|
|
||||||
editing: {
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
validation: {
|
|
||||||
autoUpdateParentTasks: true,
|
|
||||||
},
|
|
||||||
toolbar: {
|
|
||||||
items: [
|
|
||||||
'collapseAll',
|
|
||||||
'expandAll',
|
|
||||||
'separator',
|
|
||||||
'zoomIn',
|
|
||||||
'zoomOut',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
columns: [{
|
|
||||||
dataField: 'title',
|
|
||||||
caption: 'Stajyer Adı',
|
|
||||||
width: 250,
|
|
||||||
}, {
|
|
||||||
dataField: 'start',
|
|
||||||
caption: 'Başlangıç Tarihi',
|
|
||||||
dataType: 'date',
|
|
||||||
format: 'dd.MM.yyyy',
|
|
||||||
width: 120,
|
|
||||||
}, {
|
|
||||||
dataField: 'end',
|
|
||||||
caption: 'Bitiş Tarihi',
|
|
||||||
dataType: 'date',
|
|
||||||
format: 'dd.MM.yyyy',
|
|
||||||
width: 120,
|
|
||||||
}],
|
|
||||||
scaleType: 'days',
|
|
||||||
taskListWidth: 490,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw new Error('DevExpress Gantt component jQuery plugin is not defined after loading scripts.');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
this.showError(e.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
class="dx-viewport demo-container"
|
|
||||||
>
|
|
||||||
<div id="gantt" x-ref="ganttContainer" style="height: 100%; width: 100%;"></div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</x-filament::section>
|
|
||||||
</x-filament-widgets::widget>
|
|
||||||
|
|||||||
@@ -17,16 +17,35 @@ $favicon_path = setting('site_favicon');
|
|||||||
}
|
}
|
||||||
@endphp
|
@endphp
|
||||||
@php
|
@php
|
||||||
$seo_canonical = $meta['canonical'] ?? url()->current();
|
$seo_canonical = $meta['canonical'] ?? null;
|
||||||
|
if (!$seo_canonical) {
|
||||||
|
$seo_canonical = url()->current();
|
||||||
|
$localeQuery = request()->query('locale') ?? request()->query('lang');
|
||||||
|
if ($localeQuery && function_exists('available_language_codes') && in_array($localeQuery, available_language_codes())) {
|
||||||
|
$seo_canonical .= '?locale=' . $localeQuery;
|
||||||
|
}
|
||||||
|
}
|
||||||
$seo_robots = $meta['robots'] ?? 'index, follow';
|
$seo_robots = $meta['robots'] ?? 'index, follow';
|
||||||
$seo_og_type = $meta['og_type'] ?? 'website';
|
$seo_og_type = $meta['og_type'] ?? 'website';
|
||||||
$seo_og_locale = str_replace('_', '-', $meta['locale'] ?? app()->getLocale());
|
$seo_og_locale = str_replace('_', '-', $meta['locale'] ?? app()->getLocale());
|
||||||
|
|
||||||
|
$activeLanguages = class_exists(\App\Models\Language::class)
|
||||||
|
? \App\Models\Language::where('is_active', true)->get()
|
||||||
|
: collect([]);
|
||||||
|
$currentUrl = url()->current();
|
||||||
@endphp
|
@endphp
|
||||||
<title>{{ $seo_title }}</title>
|
<title>{{ $seo_title }}</title>
|
||||||
<meta name="description" content="{{ $seo_description }}">
|
<meta name="description" content="{{ $seo_description }}">
|
||||||
<meta name="robots" content="{{ $seo_robots }}">
|
<meta name="robots" content="{{ $seo_robots }}">
|
||||||
<link rel="canonical" href="{{ $seo_canonical }}">
|
<link rel="canonical" href="{{ $seo_canonical }}">
|
||||||
|
|
||||||
|
@foreach($activeLanguages as $lang)
|
||||||
|
<link rel="alternate" hreflang="{{ $lang->code }}" href="{{ $currentUrl . '?locale=' . $lang->code }}">
|
||||||
|
@endforeach
|
||||||
|
@if($activeLanguages->count() > 0)
|
||||||
|
<link rel="alternate" hreflang="x-default" href="{{ $currentUrl }}">
|
||||||
|
@endif
|
||||||
|
|
||||||
<!-- Open Graph / Facebook -->
|
<!-- Open Graph / Facebook -->
|
||||||
<meta property="og:type" content="{{ $seo_og_type }}">
|
<meta property="og:type" content="{{ $seo_og_type }}">
|
||||||
<meta property="og:url" content="{{ $seo_canonical }}">
|
<meta property="og:url" content="{{ $seo_canonical }}">
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
{!! '<' . '?xml version="1.0" encoding="UTF-8"?' . '>' !!}
|
{!! '<' . '?xml version="1.0" encoding="UTF-8"?' . '>' !!}
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||||
|
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
@foreach($urls as $url)
|
@foreach($urls as $url)
|
||||||
<url>
|
<url>
|
||||||
<loc>{{ $url['loc'] }}</loc>
|
<loc>{{ $url['loc'] }}</loc>
|
||||||
|
@if(!empty($url['alternates']))
|
||||||
|
@foreach($url['alternates'] as $alt)
|
||||||
|
<xhtml:link rel="alternate" hreflang="{{ $alt['hreflang'] }}" href="{{ $alt['href'] }}"/>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
<lastmod>{{ $url['lastmod'] }}</lastmod>
|
<lastmod>{{ $url['lastmod'] }}</lastmod>
|
||||||
<changefreq>{{ $url['changefreq'] }}</changefreq>
|
<changefreq>{{ $url['changefreq'] }}</changefreq>
|
||||||
<priority>{{ $url['priority'] }}</priority>
|
<priority>{{ $url['priority'] }}</priority>
|
||||||
|
|||||||
Reference in New Issue
Block a user