@artilingo/artiframe-cli 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +660 -660
  2. package/bin/artiframe.js +0 -0
  3. package/bin/artiframe.php +0 -0
  4. package/core-stubs/app/ApiAuthControl.php +76 -0
  5. package/core-stubs/app/ApiControl.php +81 -35
  6. package/core-stubs/app/AuthControl.php +39 -0
  7. package/core-stubs/app/Database.php +36 -35
  8. package/core-stubs/app/DotEnv.php +19 -1
  9. package/core-stubs/app/ViewControl.php +47 -1
  10. package/core-stubs/bin/SQLMethod.php +261 -0
  11. package/core-stubs/bin/SystemMethod.php +115 -74
  12. package/core-stubs/bin/ViewMethod.php +19 -5
  13. package/core-stubs/docs/de.html +4325 -4347
  14. package/core-stubs/docs/en.html +4325 -4347
  15. package/core-stubs/docs/es.html +4325 -4347
  16. package/core-stubs/docs/fr.html +4325 -4347
  17. package/core-stubs/docs/tr.html +117 -46
  18. package/core-stubs/public/403.php +52 -0
  19. package/core-stubs/public/assets/css/components/header.css +174 -0
  20. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  21. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  22. package/core-stubs/public/assets/css/root/app.css +975 -38
  23. package/core-stubs/public/assets/css/root/root.css +64 -0
  24. package/core-stubs/public/assets/js/components/header.js +380 -0
  25. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  26. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  27. package/core-stubs/public/assets/js/root/app.js +1870 -0
  28. package/core-stubs/public/includes/footer.php +4 -5
  29. package/core-stubs/public/includes/head-auth.php +65 -0
  30. package/core-stubs/public/includes/head.php +56 -17
  31. package/core-stubs/public/includes/header.php +135 -1
  32. package/core-stubs/public/includes/mobilenav.php +75 -3
  33. package/core-stubs/public/includes/sidebar.php +186 -1
  34. package/core-stubs/public/includes/theme-modal.php +1 -0
  35. package/db-studio/debug.log +3 -0
  36. package/db-studio/index.html +1755 -0
  37. package/db-studio/launcher.html +102 -0
  38. package/db-studio/launcher.js +180 -0
  39. package/db-studio/logo.svg +22 -0
  40. package/db-studio/main.js +568 -0
  41. package/db-studio/package-lock.json +1034 -0
  42. package/db-studio/package.json +16 -0
  43. package/db-studio/preload.js +29 -0
  44. package/devops-studio/api-inspector.js +222 -0
  45. package/devops-studio/index.html +1892 -0
  46. package/devops-studio/logo.svg +22 -0
  47. package/devops-studio/main.js +67 -0
  48. package/devops-studio/make-wizard.js +635 -0
  49. package/devops-studio/package-lock.json +871 -0
  50. package/devops-studio/package.json +12 -0
  51. package/package.json +5 -2
  52. package/scripts/postinstall.js +44 -8
  53. package/server-studio/.json-404-guard +1 -0
  54. package/server-studio/index.html +283 -0
  55. package/server-studio/logo.svg +22 -0
  56. package/server-studio/main.js +133 -0
  57. package/server-studio/package-lock.json +1179 -0
  58. package/server-studio/package.json +15 -0
  59. package/server-studio/router.php +99 -0
  60. package/src/App.php +29 -0
  61. package/src/Commands/AddCommand.php +26 -9
  62. package/src/Commands/DbExportCommand.php +131 -0
  63. package/src/Commands/DbStartCommand.php +46 -0
  64. package/src/Commands/DevopsCommand.php +35 -0
  65. package/src/Commands/GoCommand.php +48 -48
  66. package/src/Commands/ListCommand.php +68 -68
  67. package/src/Commands/MakeApiCommand.php +6 -1
  68. package/src/Commands/MakeViewCommand.php +25 -2
  69. package/src/Commands/NewProjectCommand.php +16 -11
  70. package/src/Commands/OptimizeCommand.php +61 -0
  71. package/src/Commands/RemoveCommand.php +36 -7
  72. package/src/Commands/ServeCommand.php +46 -91
  73. package/src/Commands/ShowCommand.php +24 -24
  74. package/src/Commands/UpgradeCommand.php +39 -10
  75. package/stubs/make/api-switch-case.stub +1 -1
  76. package/stubs/make/auth-api-standart.stub +20 -0
  77. package/stubs/make/auth-api-switch-case.stub +38 -0
  78. package/stubs/make/auth-view.stub +26 -0
  79. package/stubs/make/class.stub +10 -2
  80. package/stubs/make/view.stub +3 -0
  81. package/stubs/service/image.stub +334 -334
  82. package/stubs/service/iyzico.stub +637 -637
  83. package/stubs/service/jwt.stub +312 -312
  84. package/stubs/service/phpmailer.stub +143 -143
  85. package/stubs/service/pusher.stub +232 -232
  86. package/stubs/service/qrcode.stub +169 -169
  87. package/stubs/service/redis.stub +361 -361
  88. package/stubs/service/s3.stub +377 -377
  89. package/stubs/service/stripe.stub +526 -526
  90. package/stubs/service/twilio.stub +361 -361
@@ -1,5 +1,4 @@
1
- <!-- Footer Component Starts Here -->
2
- <footer class="app-footer">
3
-
4
- </footer>
5
- <!-- Footer Component Ends Here -->
1
+ <!--
2
+ Uygulamanın sosyal medya / infinite scroll yapısı gereği statik footer iptal edilmiştir.
3
+ Eğer sayfanın altında linkler gösterilmek istenirse bu dosya tekrar aktif edilebilir.
4
+ -->
@@ -0,0 +1,65 @@
1
+ <meta charset="UTF-8">
2
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
+ <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1">
4
+
5
+ <!-- Open Graph / Sosyal Medya Paylaşım (Zorunlu SEO/SMO Metaları) -->
6
+ <meta property="og:title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
7
+ <meta property="og:description" content="ArtiFrame tabanlı web uygulaması.">
8
+ <meta property="og:type" content="website">
9
+ <meta property="og:url" content="<?= defined('APP_URL') ? APP_URL : 'http://localhost' ?><?= htmlspecialchars($_SERVER['REQUEST_URI'] ?? '') ?>">
10
+ <meta property="og:image" content="<?= defined('APP_URL') ? APP_URL : '' ?>/assets/images/social-cover.jpg">
11
+ <meta property="og:site_name" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
12
+
13
+ <!-- Twitter Cards -->
14
+ <meta name="twitter:card" content="summary_large_image">
15
+ <meta name="twitter:title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
16
+ <meta name="twitter:description" content="ArtiFrame tabanlı web uygulaması.">
17
+ <meta name="twitter:image" content="<?= defined('APP_URL') ? APP_URL : '' ?>/assets/images/social-cover.jpg">
18
+
19
+ <!-- CSRF Token (AJAX/Fetch işlemleri için global erişim sağlar) -->
20
+ <?php
21
+ $shouldGenerateCsrf = true;
22
+ if (empty($_SESSION['kullaniciId']) && defined('ALLOW_PUBLIC_VIEW') && ALLOW_PUBLIC_VIEW === true) {
23
+ $shouldGenerateCsrf = false;
24
+ }
25
+ ?>
26
+ <?php if ($shouldGenerateCsrf): ?>
27
+ <meta name="csrf-token" content="<?= \Bin\SystemMethod::generateCsrf() ?>">
28
+ <?php endif; ?>
29
+
30
+ <!-- FOUC (Tema göz kırpmasını) Engellemek için Inline Tema Yükleyici -->
31
+ <script>
32
+ const savedTheme = localStorage.getItem('artiframe_theme_mode') || localStorage.getItem('app-mode') || 'dark';
33
+ document.documentElement.setAttribute('data-mode', savedTheme);
34
+ </script>
35
+
36
+ <!-- Favicons -->
37
+ <link rel="icon" type="image/png" href="/assets/images/favicon/favicon-96x96.png" sizes="96x96" />
38
+ <link rel="icon" type="image/svg+xml" href="/assets/images/favicon/favicon.svg" />
39
+ <link rel="shortcut icon" href="/assets/images/favicon/favicon.ico" />
40
+ <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/favicon/apple-touch-icon.png" />
41
+ <meta name="apple-mobile-web-app-title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>" />
42
+ <link rel="manifest" href="/site.webmanifest" />
43
+
44
+ <!-- FontAwesome 6 Icons -->
45
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
46
+
47
+ <!-- Global Assets -->
48
+ <!-- Viewer.js (Mobile-First Image Viewer) -->
49
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.css" />
50
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.js" defer></script>
51
+
52
+ <link rel="stylesheet" href="/assets/css/root/app.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
53
+ <script src="/assets/js/root/app.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
54
+
55
+ <!-- Component Assets (Bileşen CSS/JS Dosyaları) -->
56
+ <link rel="stylesheet" href="/assets/css/components/header.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
57
+ <link rel="stylesheet" href="/assets/css/components/footer.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
58
+ <link rel="stylesheet" href="/assets/css/components/sidebar.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
59
+ <link rel="stylesheet" href="/assets/css/components/mobilenav.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
60
+ <link rel="stylesheet" href="/assets/css/components/theme-modal.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
61
+
62
+ <script src="/assets/js/components/header.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
63
+ <script src="/assets/js/components/sidebar.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
64
+ <script src="/assets/js/components/mobilenav.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
65
+ <script src="/assets/js/components/theme-modal.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
@@ -1,26 +1,65 @@
1
1
  <meta charset="UTF-8">
2
2
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
- <meta name="robots" content="index, follow">
3
+ <meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
4
+
5
+ <!-- Open Graph / Sosyal Medya Paylaşım (Zorunlu SEO/SMO Metaları) -->
6
+ <meta property="og:title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
7
+ <meta property="og:description" content="ArtiFrame tabanlı web uygulaması.">
8
+ <meta property="og:type" content="website">
9
+ <meta property="og:url" content="<?= defined('APP_URL') ? APP_URL : 'http://localhost' ?><?= htmlspecialchars($_SERVER['REQUEST_URI'] ?? '') ?>">
10
+ <meta property="og:image" content="<?= defined('APP_URL') ? APP_URL : '' ?>/assets/images/social-cover.jpg">
11
+ <meta property="og:site_name" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
12
+
13
+ <!-- Twitter Cards -->
14
+ <meta name="twitter:card" content="summary_large_image">
15
+ <meta name="twitter:title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>">
16
+ <meta name="twitter:description" content="ArtiFrame tabanlı web uygulaması.">
17
+ <meta name="twitter:image" content="<?= defined('APP_URL') ? APP_URL : '' ?>/assets/images/social-cover.jpg">
4
18
 
5
19
  <!-- CSRF Token (AJAX/Fetch işlemleri için global erişim sağlar) -->
6
- <meta name="csrf-token" content="<?= \Bin\SystemMethod::generateCsrf() ?>">
20
+ <?php
21
+ $shouldGenerateCsrf = true;
22
+ if (empty($_SESSION['kullaniciId']) && defined('ALLOW_PUBLIC_VIEW') && ALLOW_PUBLIC_VIEW === true) {
23
+ $shouldGenerateCsrf = false;
24
+ }
25
+ ?>
26
+ <?php if ($shouldGenerateCsrf): ?>
27
+ <meta name="csrf-token" content="<?= \Bin\SystemMethod::generateCsrf() ?>">
28
+ <?php endif; ?>
29
+
30
+ <!-- FOUC (Tema göz kırpmasını) Engellemek için Inline Tema Yükleyici -->
31
+ <script>
32
+ const savedTheme = localStorage.getItem('artiframe_theme_mode') || localStorage.getItem('app-mode') || 'dark';
33
+ document.documentElement.setAttribute('data-mode', savedTheme);
34
+ </script>
7
35
 
8
- <!-- Favicon -->
9
- <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
10
- <link rel="manifest" href="/site.webmanifest">
36
+ <!-- Favicons -->
37
+ <link rel="icon" type="image/png" href="/assets/images/favicon/favicon-96x96.png" sizes="96x96" />
38
+ <link rel="icon" type="image/svg+xml" href="/assets/images/favicon/favicon.svg" />
39
+ <link rel="shortcut icon" href="/assets/images/favicon/favicon.ico" />
40
+ <link rel="apple-touch-icon" sizes="180x180" href="/assets/images/favicon/apple-touch-icon.png" />
41
+ <meta name="apple-mobile-web-app-title" content="<?= defined('APP_NAME') ? APP_NAME : 'ArtiFrame' ?>" />
42
+ <link rel="manifest" href="/site.webmanifest" />
43
+
44
+ <!-- FontAwesome 6 Icons -->
45
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
11
46
 
12
47
  <!-- Global Assets -->
13
- <link rel="stylesheet" href="/assets/css/root/app.css?v=<?= APP_VERSION ?>">
14
- <script src="/assets/js/root/app.js?v=<?= APP_VERSION ?>" defer></script>
48
+ <!-- Viewer.js (Mobile-First Image Viewer) -->
49
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.css" />
50
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.js" defer></script>
51
+
52
+ <link rel="stylesheet" href="/assets/css/root/app.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
53
+ <script src="/assets/js/root/app.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
15
54
 
16
55
  <!-- Component Assets (Bileşen CSS/JS Dosyaları) -->
17
- <link rel="stylesheet" href="/assets/css/components/header.css?v=<?= APP_VERSION ?>">
18
- <link rel="stylesheet" href="/assets/css/components/footer.css?v=<?= APP_VERSION ?>">
19
- <link rel="stylesheet" href="/assets/css/components/sidebar.css?v=<?= APP_VERSION ?>">
20
- <link rel="stylesheet" href="/assets/css/components/mobilenav.css?v=<?= APP_VERSION ?>">
21
- <link rel="stylesheet" href="/assets/css/components/theme-modal.css?v=<?= APP_VERSION ?>">
22
-
23
- <script src="/assets/js/components/header.js?v=<?= APP_VERSION ?>" defer></script>
24
- <script src="/assets/js/components/sidebar.js?v=<?= APP_VERSION ?>" defer></script>
25
- <script src="/assets/js/components/mobilenav.js?v=<?= APP_VERSION ?>" defer></script>
26
- <script src="/assets/js/components/theme-modal.js?v=<?= APP_VERSION ?>" defer></script>
56
+ <link rel="stylesheet" href="/assets/css/components/header.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
57
+ <link rel="stylesheet" href="/assets/css/components/footer.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
58
+ <link rel="stylesheet" href="/assets/css/components/sidebar.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
59
+ <link rel="stylesheet" href="/assets/css/components/mobilenav.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
60
+ <link rel="stylesheet" href="/assets/css/components/theme-modal.css?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>">
61
+
62
+ <script src="/assets/js/components/header.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
63
+ <script src="/assets/js/components/sidebar.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
64
+ <script src="/assets/js/components/mobilenav.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
65
+ <script src="/assets/js/components/theme-modal.js?v=<?= defined('APP_VERSION') ? APP_VERSION : '1.0.0' ?>" defer></script>
@@ -1,5 +1,139 @@
1
+ <?php
2
+ $headerAvatarUrl = "https://sinavortagim.artilingo.com/system/default-avatar.png";
3
+ if (!empty($_SESSION['kullaniciAdi'])) {
4
+ $headerUser = \Src\User::getProfileByUsername($_SESSION['kullaniciAdi']);
5
+ if ($headerUser && !empty($headerUser['profilFotografi'])) {
6
+ $headerAvatarUrl = str_starts_with($headerUser['profilFotografi'], 'http')
7
+ ? $headerUser['profilFotografi']
8
+ : "/uploads/profiles/" . $headerUser['profilFotografi'];
9
+ }
10
+ }
11
+ ?>
1
12
  <!-- Header Component Starts Here -->
2
- <header class="app-header">
13
+ <?php
14
+ $isGuestHeader = empty($_SESSION['kullaniciId']);
15
+ $wsToken = '';
16
+ $wsUserIdHex = '';
17
+ if (!$isGuestHeader) {
18
+ $wsUserIdHex = bin2hex($_SESSION['kullaniciId']);
19
+ $wsToken = hash_hmac('sha256', $wsUserIdHex, 'S1nav0rtagim_WS_SecReT');
20
+ }
21
+ ?>
22
+ <script>
23
+ window.WS_USER_ID = "<?= $wsUserIdHex ?>";
24
+ window.WS_TOKEN = "<?= $wsToken ?>";
25
+ </script>
26
+ <header class="app-header" <?= $isGuestHeader ? 'style="justify-content: center; position: relative;"' : '' ?>>
3
27
 
28
+ <?php if ($isGuestHeader): ?>
29
+ <a href="/" style="display: flex; align-items: center; justify-content: center; height: 100%;">
30
+ <img src="/assets/images/sinavOrtagim.svg" data-light-src="/assets/images/sinavOrtagim.svg" data-dark-src="/assets/images/sinavOrtagim-dark.svg" alt="Sınav Ortağım" class="theme-image" style="height: 36px; width: auto;">
31
+ </a>
32
+ <button class="header-action theme-toggle-btn" id="themeToggleBtn" title="Tema Değiştir" style="position: absolute; right: 20px;">
33
+ <i class="fa-solid fa-moon"></i>
34
+ </button>
35
+ <?php else: ?>
36
+ <!-- Tema Değiştirici -->
37
+ <button class="header-action theme-toggle-btn" id="themeToggleBtn" title="Tema Değiştir" style="margin-right: auto;">
38
+ <i class="fa-solid fa-moon"></i>
39
+ </button>
40
+ <!-- Arama -->
41
+ <a href="/ara" class="header-action" title="Ara" style="display: flex; align-items: center; justify-content: center; text-decoration: none;">
42
+ <i class="fa-solid fa-magnifying-glass"></i>
43
+ </a>
44
+
45
+ <!-- Sepet -->
46
+ <?php
47
+ $headerCartCount = 0;
48
+ if (!empty($_SESSION['kullaniciId'])) {
49
+ if (!class_exists('\Src\Magaza')) {
50
+ require_once $_SERVER['DOCUMENT_ROOT'] . '/../src/Magaza.php';
51
+ }
52
+ $headerMagaza = new \Src\Magaza();
53
+ $headerCartCount = count($headerMagaza->getCartItems($_SESSION['kullaniciId']));
54
+ }
55
+ ?>
56
+ <a href="/magaza/sepet" class="header-action" id="headerCartBtn" title="Sepetim" style="display: flex; align-items: center; justify-content: center; text-decoration: none; position: relative;">
57
+ <i class="fa-solid fa-cart-shopping"></i>
58
+ <span class="badge" id="cartBadge" style="<?= $headerCartCount > 0 ? 'display: flex;' : 'display: none;' ?> background: var(--brand-primary); color: white; position: absolute; top: -5px; right: -5px; font-size: 0.7rem; border-radius: 50%; width: 16px; height: 16px; align-items: center; justify-content: center;"><?= $headerCartCount ?></span>
59
+ </a>
60
+
61
+ <!-- Bildirimler -->
62
+ <div class="header-avatar-container" id="notificationDropdownContainer" title="Bildirimler">
63
+ <button class="header-action" id="notificationBtn">
64
+ <i class="fa-regular fa-bell"></i>
65
+ <span class="badge" id="notificationBadge" style="display: none;">0</span>
66
+ </button>
67
+
68
+ <div class="profile-dropdown-menu" id="notificationDropdownMenu" style="width: 320px; padding: 0; display: flex; flex-direction: column;">
69
+ <div style="display:flex; border-bottom:1px solid var(--border); position: sticky; top: 0; background: var(--card-bg); z-index: 10; border-radius: 16px 16px 0 0; overflow: hidden;">
70
+ <button class="notif-tab active" data-target="notif-subscriptions" style="flex:1; padding:12px; background:none; border:none; color:var(--brand-primary); font-weight:600; cursor:pointer; border-bottom:2px solid var(--brand-primary); font-size: 0.8rem; transition: all 0.2s;">Abonelikler</button>
71
+ <button class="notif-tab" data-target="notif-general" style="flex:1; padding:12px; background:none; border:none; color:var(--text-muted); font-weight:600; cursor:pointer; border-bottom:2px solid transparent; font-size: 0.8rem; transition: all 0.2s;">Genel</button>
72
+ <button class="notif-tab" data-target="notif-special" style="flex:1; padding:12px; background:none; border:none; color:var(--text-muted); font-weight:600; cursor:pointer; border-bottom:2px solid transparent; font-size: 0.8rem; transition: all 0.2s;">Özel</button>
73
+ <button class="notif-tab" data-target="notif-system" style="flex:1; padding:12px; background:none; border:none; color:var(--text-muted); font-weight:600; cursor:pointer; border-bottom:2px solid transparent; font-size: 0.8rem; transition: all 0.2s;">Sistem</button>
74
+ </div>
75
+
76
+ <div id="notif-subscriptions" class="notif-content-pane" style="display:flex; flex-direction:column; max-height: 400px; overflow-y: auto;">
77
+ <div style="padding: 20px; text-align: center; color: var(--text-muted); font-size: 0.85rem;">Yükleniyor...</div>
78
+ </div>
79
+
80
+ <div id="notif-general" class="notif-content-pane" style="display:none; flex-direction:column; max-height: 400px; overflow-y: auto;">
81
+ <div style="padding: 20px; text-align: center; color: var(--text-muted); font-size: 0.85rem;">Yükleniyor...</div>
82
+ </div>
83
+
84
+ <div id="notif-special" class="notif-content-pane" style="display:none; flex-direction:column; max-height: 400px; overflow-y: auto;">
85
+ <div style="padding: 20px; text-align: center; color: var(--text-muted); font-size: 0.85rem;">Yükleniyor...</div>
86
+ </div>
87
+
88
+ <div id="notif-system" class="notif-content-pane" style="display:none; flex-direction:column; max-height: 400px; overflow-y: auto;">
89
+ <div style="padding: 20px; text-align: center; color: var(--text-muted); font-size: 0.85rem;">Yükleniyor...</div>
90
+ </div>
91
+
92
+ <div style="padding: 10px; border-top: 1px solid var(--border); text-align: center; background: var(--card-bg); border-radius: 0 0 16px 16px;">
93
+ <span id="notificationMarkReadText" style="font-size: 0.85rem; font-weight: 500; color: var(--brand-primary); cursor: pointer; display: none;">Tümünü Okundu İşaretle</span>
94
+ </div>
95
+ </div>
96
+ </div>
97
+
98
+ <!-- Kullanıcı Avatarı & Açılır Menü -->
99
+ <div class="header-avatar-container" id="profileDropdownContainer" title="Profil İşlemleri">
100
+ <div class="header-avatar" id="profileDropdownBtn">
101
+ <img src="<?= htmlspecialchars($headerAvatarUrl) ?>" alt="Profil" style="object-fit: cover;">
102
+ </div>
103
+
104
+ <div class="profile-dropdown-menu" id="profileDropdownMenu">
105
+ <a class="dropdown-item" href="/user/profil<?= !empty($_SESSION['kullaniciAdi']) ? '/' . htmlspecialchars($_SESSION['kullaniciAdi']) : '' ?>">
106
+ <i class="fa-regular fa-user"></i>
107
+ <span>Profilim</span>
108
+ </a>
109
+ <a class="dropdown-item" href="/user/basvuru">
110
+ <i class="fa-solid fa-shield-halved"></i>
111
+ <span>Onaylı Hesap</span>
112
+ </a>
113
+ <a class="dropdown-item" href="/kaydedilenler">
114
+ <i class="fa-regular fa-bookmark"></i>
115
+ <span>Kaydedilenler</span>
116
+ </a>
117
+ <a class="dropdown-item" href="/arsiv">
118
+ <i class="fa-solid fa-box-archive"></i>
119
+ <span>Arşiv</span>
120
+ </a>
121
+ <a class="dropdown-item" href="/user/engellediklerim">
122
+ <i class="fa-solid fa-user-slash"></i>
123
+ <span>Engellenenler</span>
124
+ </a>
125
+ <a class="dropdown-item" href="/user/ayarlar">
126
+ <i class="fa-solid fa-gear"></i>
127
+ <span>Ayarlar</span>
128
+ </a>
129
+ <hr class="dropdown-divider">
130
+ <a class="dropdown-item text-danger" href="/logout">
131
+ <i class="fa-solid fa-arrow-right-from-bracket"></i>
132
+ <span>Çıkış Yap</span>
133
+ </a>
134
+ </div>
135
+ </div>
136
+ <?php endif; ?>
137
+
4
138
  </header>
5
139
  <!-- Header Component Ends Here -->
@@ -1,5 +1,77 @@
1
+ <?php
2
+ // $allowedMenuItems sidebar.php üzerinden oluşturulup buraya kadar ulaştı.
3
+ // Eğer doğrudan mobilenav yüklenirse hata vermemesi için varsayılan atayalım:
4
+ if (!isset($allowedMenuItems)) {
5
+ $allowedMenuItems = [];
6
+ }
7
+
8
+ // Sadece mobilde gösterilecek öğeleri filtrele
9
+ $mobileAllowedItems = array_filter($allowedMenuItems, function($item) {
10
+ return !isset($item['show_in_mobile']) || $item['show_in_mobile'] === true;
11
+ });
12
+ $mobileAllowedItems = array_values($mobileAllowedItems);
13
+
14
+ $primaryItems = array_slice($mobileAllowedItems, 0, 4);
15
+ $secondaryItems = array_slice($mobileAllowedItems, 4);
16
+
17
+ $currentUrl = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
18
+ ?>
1
19
  <!-- Mobile Navigation Component Starts Here -->
2
- <nav class="app-mobilenav">
3
-
4
- </nav>
20
+ <div class="app-mobile-nav d-lg-none">
21
+ <div class="mobile-bottom-bar">
22
+ <?php foreach ($primaryItems as $item): ?>
23
+ <?php
24
+ // Anasayfa ise tam eşleşme, değilse başlangıç eşleşmesi arar
25
+ if ($item['url'] === '/') {
26
+ $isActive = ($currentUrl === '/');
27
+ } else {
28
+ $isActive = (strpos($currentUrl, $item['url']) === 0);
29
+ }
30
+ ?>
31
+ <a href="<?= htmlspecialchars($item['url']) ?>" class="bottom-nav-item <?= $isActive ? 'active' : '' ?>" title="<?= htmlspecialchars($item['title']) ?>">
32
+ <?php if (isset($item['icon_img'])): ?>
33
+ <img src="<?= htmlspecialchars($item['icon_img']) ?>" class="menu-svg-icon" alt="<?= htmlspecialchars($item['title']) ?>">
34
+ <?php else: ?>
35
+ <i class="<?= htmlspecialchars($item['icon']) ?>"></i>
36
+ <span class="nav-label"><?= htmlspecialchars($item['title']) ?></span>
37
+ <?php endif; ?>
38
+ </a>
39
+ <?php endforeach; ?>
40
+
41
+ <?php if (!empty($secondaryItems)): ?>
42
+ <button class="bottom-nav-item mobile-menu-toggle" id="mobileMenuBtn" aria-label="Menüyü Aç">
43
+ <i class="fa-solid fa-border-all"></i>
44
+ <span class="nav-label">Menü</span>
45
+ </button>
46
+ <?php endif; ?>
47
+ </div>
48
+
49
+ <?php if (!empty($secondaryItems)): ?>
50
+ <div class="mobile-bottom-sheet" id="mobileBottomSheet">
51
+ <div class="sheet-overlay" id="sheetOverlay"></div>
52
+ <div class="sheet-content">
53
+ <div class="sheet-header">
54
+ <div class="drag-handle"></div>
55
+ <h3 class="sheet-title">Diğer İşlemler</h3>
56
+ </div>
57
+ <div class="sheet-body">
58
+ <?php foreach ($secondaryItems as $item): ?>
59
+ <a href="<?= htmlspecialchars($item['url']) ?>" class="sheet-item" <?= !empty($item['target']) ? 'target="'.htmlspecialchars($item['target']).'"' : '' ?>>
60
+ <div class="sheet-icon-wrapper" style="<?php echo isset($item['icon_img']) ? 'width:auto; margin-right:0; margin-left:12px; background:none;' : ''; ?>">
61
+ <?php if (isset($item['icon_img'])): ?>
62
+ <img src="<?= htmlspecialchars($item['icon_img']) ?>" class="menu-svg-icon" alt="<?= htmlspecialchars($item['title']) ?>">
63
+ <?php else: ?>
64
+ <i class="<?= htmlspecialchars($item['icon']) ?>"></i>
65
+ <?php endif; ?>
66
+ </div>
67
+ <?php if (!isset($item['icon_img'])): ?>
68
+ <span class="sheet-label"><?= htmlspecialchars($item['title']) ?></span>
69
+ <?php endif; ?>
70
+ </a>
71
+ <?php endforeach; ?>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ <?php endif; ?>
76
+ </div>
5
77
  <!-- Mobile Navigation Component Ends Here -->
@@ -1,5 +1,190 @@
1
+ <?php
2
+ // Geçerli kullanıcının rolünü alalım (Eğer login değilse misafir varsayalım)
3
+ $userRole = $_SESSION['rol'] ?? 'misafir';
4
+
5
+ // Tüm olası menü ögeleri ve erişim izinleri (Kullanıcı dilediği gibi burayı genişletebilir)
6
+ $allMenuItems = [
7
+ [
8
+ 'title' => 'Anasayfa',
9
+ 'url' => '/',
10
+ 'icon' => 'fa-solid fa-house',
11
+ 'roles' => ['all'],
12
+ 'position' => 'top',
13
+ 'show_in_mobile' => true
14
+ ],
15
+ [
16
+ 'title' => 'Soru Duvarı',
17
+ 'url' => '/soru-duvari',
18
+ 'icon' => 'fa-solid fa-clipboard-question',
19
+ 'roles' => ['all'],
20
+ 'position' => 'top',
21
+ 'show_in_mobile' => true
22
+ ],
23
+ [
24
+ 'title' => 'Gruplar',
25
+ 'url' => '/groups/list',
26
+ 'icon' => 'fa-solid fa-users',
27
+ 'roles' => ['all'],
28
+ 'position' => 'top',
29
+ 'show_in_mobile' => true
30
+ ],
31
+ [
32
+ 'title' => 'Mağaza',
33
+ 'url' => '/magaza/magaza',
34
+ 'icon' => 'fa-solid fa-store',
35
+ 'roles' => ['all'],
36
+ 'position' => 'bottom',
37
+ 'show_in_mobile' => true
38
+ ],
39
+ [
40
+ 'title' => 'Gelişim Takibi',
41
+ 'url' => '/gelisim-takibi',
42
+ 'icon' => 'fa-solid fa-chart-line',
43
+ 'roles' => [1, 0], // Öğrenci ve Admin
44
+ 'position' => 'top',
45
+ 'show_in_mobile' => true
46
+ ],
47
+ [
48
+ 'title' => 'Atama Analizi',
49
+ 'url' => '/atama-analizi',
50
+ 'icon' => 'fa-solid fa-ranking-star',
51
+ 'roles' => [1, 4, 0], // Öğrenci, Mezun ve Admin
52
+ 'position' => 'top',
53
+ 'show_in_mobile' => true
54
+ ],
55
+ [
56
+ 'title' => 'Moderasyon Paneli',
57
+ 'url' => '/admin/u/moderasyon',
58
+ 'icon' => 'fa-solid fa-shield-halved',
59
+ 'roles' => [0], // Admin
60
+ 'position' => 'bottom',
61
+ 'show_in_mobile' => true
62
+ ],
63
+ [
64
+ 'title' => 'Sepetim',
65
+ 'url' => '/magaza/sepet',
66
+ 'icon' => 'fa-solid fa-cart-shopping',
67
+ 'roles' => ['all'],
68
+ 'position' => 'bottom',
69
+ 'show_in_mobile' => true
70
+ ],
71
+ [
72
+ 'title' => 'Cüzdan & Envanter',
73
+ 'url' => '/user/envanter',
74
+ 'icon' => 'fa-solid fa-wallet',
75
+ 'roles' => ['all'],
76
+ 'position' => 'bottom',
77
+ 'show_in_mobile' => true
78
+ ],
79
+ [
80
+ 'title' => 'Ödeme Yöntemleri',
81
+ 'url' => '/magaza/odeme-yontemlerim',
82
+ 'icon' => 'fa-solid fa-credit-card',
83
+ 'roles' => ['all'],
84
+ 'position' => 'bottom',
85
+ 'show_in_mobile' => true
86
+ ],
87
+ [
88
+ 'title' => 'Aboneliklerim',
89
+ 'url' => '/magaza/aboneliklerim',
90
+ 'icon' => 'fa-solid fa-clock-rotate-left',
91
+ 'roles' => ['all'],
92
+ 'position' => 'bottom',
93
+ 'show_in_mobile' => true
94
+ ],
95
+ [
96
+ 'title' => 'Yardım',
97
+ 'url' => 'https://sinavortagim.com/yardim',
98
+ 'icon' => 'fa-regular fa-circle-question',
99
+ 'roles' => ['all'],
100
+ 'position' => 'footer',
101
+ 'show_in_mobile' => true,
102
+ 'target' => '_blank'
103
+ ],
104
+ [
105
+ 'title' => 'Politikalar',
106
+ 'url' => 'https://sinavortagim.com/politikalar',
107
+ 'icon' => 'fa-solid fa-scale-balanced',
108
+ 'roles' => ['all'],
109
+ 'position' => 'footer',
110
+ 'show_in_mobile' => true,
111
+ 'target' => '_blank'
112
+ ]
113
+ ];
114
+
115
+ // RBAC Filtreleme
116
+ $allowedMenuItems = array_filter($allMenuItems, function($item) use ($userRole) {
117
+ return in_array('all', $item['roles']) || in_array($userRole, $item['roles']);
118
+ });
119
+ ?>
1
120
  <!-- Sidebar Component Starts Here -->
2
121
  <aside class="app-sidebar">
3
-
122
+ <div class="sidebar-logo">
123
+ <img src="/assets/images/icon.svg" data-light-src="/assets/images/icon.svg" data-dark-src="/assets/images/icon-dark.svg" alt="Sınav Ortağım İkon" class="logo-icon theme-image">
124
+ <img src="/assets/images/sinavOrtagim.svg" data-light-src="/assets/images/sinavOrtagim.svg" data-dark-src="/assets/images/sinavOrtagim-dark.svg" alt="Sınav Ortağım Logo" class="logo-full theme-image">
125
+ </div>
126
+
127
+ <nav class="sidebar-nav">
128
+ <?php foreach ($allowedMenuItems as $item): ?>
129
+ <?php if ($item['position'] === 'top'): ?>
130
+ <a href="<?= htmlspecialchars($item['url']) ?>" <?= isset($item['target']) ? 'target="' . $item['target'] . '"' : '' ?> class="nav-item <?= ($_SERVER['REQUEST_URI'] == $item['url']) ? 'active' : '' ?>">
131
+ <div class="nav-icon" style="<?php echo isset($item['icon_img']) ? 'width:100%; margin-right:0;' : ''; ?>">
132
+ <?php if (isset($item['icon_img'])): ?>
133
+ <img src="<?= htmlspecialchars($item['icon_img']) ?>" class="menu-svg-icon" alt="<?= htmlspecialchars($item['title']) ?>">
134
+ <?php else: ?>
135
+ <i class="<?= htmlspecialchars($item['icon']) ?>"></i>
136
+ <?php endif; ?>
137
+ </div>
138
+ <?php if (!isset($item['icon_img'])): ?>
139
+ <span class="nav-label"><?= htmlspecialchars($item['title']) ?></span>
140
+ <?php endif; ?>
141
+ </a>
142
+ <?php endif; ?>
143
+ <?php endforeach; ?>
144
+ </nav>
145
+
146
+ <div class="sidebar-footer">
147
+ <?php
148
+ $hasBottom = false;
149
+ foreach ($allowedMenuItems as $item):
150
+ if ($item['position'] === 'bottom'):
151
+ $hasBottom = true;
152
+ ?>
153
+ <a href="<?= htmlspecialchars($item['url']) ?>" <?= isset($item['target']) ? 'target="' . $item['target'] . '"' : '' ?> class="nav-item <?= ($_SERVER['REQUEST_URI'] == $item['url']) ? 'active' : '' ?>">
154
+ <div class="nav-icon" style="<?php echo isset($item['icon_img']) ? 'width:100%; margin-right:0;' : ''; ?>">
155
+ <?php if (isset($item['icon_img'])): ?>
156
+ <img src="<?= htmlspecialchars($item['icon_img']) ?>" class="menu-svg-icon" alt="<?= htmlspecialchars($item['title']) ?>">
157
+ <?php else: ?>
158
+ <i class="<?= htmlspecialchars($item['icon']) ?>"></i>
159
+ <?php endif; ?>
160
+ </div>
161
+ <?php if (!isset($item['icon_img'])): ?>
162
+ <span class="nav-label"><?= htmlspecialchars($item['title']) ?></span>
163
+ <?php endif; ?>
164
+ </a>
165
+ <?php endif; ?>
166
+ <?php endforeach; ?>
167
+
168
+ <?php if ($hasBottom): ?>
169
+ <hr style="border-color: rgba(255,255,255,0.1); margin: 0.5rem 1rem; border-width: 1px; opacity: 1;">
170
+ <?php endif; ?>
171
+
172
+ <?php foreach ($allowedMenuItems as $item): ?>
173
+ <?php if ($item['position'] === 'footer'): ?>
174
+ <a href="<?= htmlspecialchars($item['url']) ?>" <?= isset($item['target']) ? 'target="' . $item['target'] . '"' : '' ?> class="nav-item <?= ($_SERVER['REQUEST_URI'] == $item['url']) ? 'active' : '' ?>">
175
+ <div class="nav-icon" style="<?php echo isset($item['icon_img']) ? 'width:100%; margin-right:0;' : ''; ?>">
176
+ <?php if (isset($item['icon_img'])): ?>
177
+ <img src="<?= htmlspecialchars($item['icon_img']) ?>" class="menu-svg-icon" alt="<?= htmlspecialchars($item['title']) ?>">
178
+ <?php else: ?>
179
+ <i class="<?= htmlspecialchars($item['icon']) ?>"></i>
180
+ <?php endif; ?>
181
+ </div>
182
+ <?php if (!isset($item['icon_img'])): ?>
183
+ <span class="nav-label"><?= htmlspecialchars($item['title']) ?></span>
184
+ <?php endif; ?>
185
+ </a>
186
+ <?php endif; ?>
187
+ <?php endforeach; ?>
188
+ </div>
4
189
  </aside>
5
190
  <!-- Sidebar Component Ends Here -->
@@ -3,3 +3,4 @@
3
3
 
4
4
  </div>
5
5
  <!-- Theme Modal Component Ends Here -->
6
+ <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/report-modal.php'; ?>
@@ -0,0 +1,3 @@
1
+ ["/home/mergen/Masaüstü/projeler/artiframe-cli/db-studio/node_modules/electron/dist/electron",".","/home/mergen/Masaüstü/project","--mode=live"]
2
+ appMode:live
3
+ projectRoot:/home/mergen/Masaüstü/project