Skip to content

Commit a8b259e

Browse files
sametbasbugclaude
andcommitted
Hayalet kabuğu sil, profil sayfasını aç
BaseLayout'ta blog döneminden kalma bir header duruyordu: "Samet Başbuğ" logosu, eski gezinme, bozuk emoji taşıyan bir tema düğmesi. Üretime hiç çıkmıyordu — NewsLayout hem `hideHeader` geçiyor hem de `#main-header { display: none }` yazıyordu, aynı ölü şey iki mekanizmayla saklanıyordu. Ama ölü değil UYUYORDU: denetim sayfasını yazarken BaseLayout'u doğrudan kullandım ve hayalet ekrana geldi. Adı "temel" olan şeyi hangi kabuğun ne çizdiğini bilmeden seçmiştim. Kaldırılan: header markup'ı, betiği (`attachThemeToggle`, `placeThemeSwitch`, başlık kaydırma), stilleri (header/nav/logo/links/dropdown/theme-switch), ve `hideHeader`/`shellLayout` propları. Tek değer alan bir prop prop değil, saklanmış bir karardır. NewsLayout'taki gizleme kuralı da gitti: gizlenecek bir şey kalmadı. DENKLİK ÖLÇÜLDÜ. Beş bilgi sayfasının markup'ı canlıdakiyle karakter karakter aynı (SSR'a özel giriş formu hariç, statik derlemede o yok). Değişen yalnız ölü CSS/JS: BaseLayout 22156 → 15441 bayt. Yeni: `/profil`. Bugün gösterdiği az ama gösterdiği her şey gerçek — kimlik, erişim, adına çalışan ajanlar, çıkış. Denetim bağlantısı burada, çünkü `/denetim` hiçbir yerden bağlanmayan bir adres olarak unutulmaya çok müsaitti. Başlıktaki ad da artık profile gidiyor. Arşiv okumada gövde istenirse limit tavanı 10'a iniyor. Yüz haber gövdesi, çağıran ajanın bağlamına yüzlerce kilobayt boşaltmak demek; sayfalama zaten var. Uygulanan tavan cevapta yazılı, yoksa ajan eksik veriyi "hepsi bu" sanar. 70 vaka. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 6594b0d commit a8b259e

9 files changed

Lines changed: 218 additions & 198 deletions

File tree

‎astro.config.ssr.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function yayinUclari() {
3939
bir sayfa adaptörsüz derlemede `NoAdapterInstalled` veriyor. Statik
4040
derleme hâlâ geri dönüş yolu (bkz. `wrangler.ssr.jsonc`), yani
4141
kırılması kabul edilebilir değil. */
42+
injectRoute({ pattern: '/profil', entrypoint: './src/server/routes/profil.astro' });
4243
injectRoute({ pattern: '/denetim', entrypoint: './src/server/routes/denetim.astro' });
4344
injectRoute({ pattern: '/images/generated/[...path]', entrypoint: './src/server/routes/hero.ts' });
4445
/* Site haritası statikte `@astrojs/sitemap` tarafından derleme anında

‎public/orbit-actions.json‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@
277277
"type": "integer",
278278
"minimum": 1,
279279
"maximum": 100,
280-
"description": "Varsayılan 20."
280+
"description": "Varsayılan 20, tavan 100. govde:true ise tavan 10."
281281
},
282282
"offset": {
283283
"type": "integer",
@@ -287,7 +287,7 @@
287287
},
288288
"govde": {
289289
"type": "boolean",
290-
"description": "true ise haber metnini de döndürür (markdown)."
290+
"description": "true ise haber metnini de döndürür (markdown). Bu durumda limit tavanı 10'a iner."
291291
}
292292
}
293293
},
@@ -312,6 +312,10 @@
312312
},
313313
"dahaVar": {
314314
"type": "boolean"
315+
},
316+
"limit": {
317+
"type": "integer",
318+
"description": "Uygulanan tavan; istenenden küçük olabilir."
315319
}
316320
}
317321
}

‎src/components/OturumDugmesi.astro‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,13 @@ const donus = Astro.url.pathname + Astro.url.search;
5252

5353
{okuyucu && (
5454
<form class="oturum" method="POST" action="/cikis" data-astro-reload>
55-
<span class="oturum-ad" title={okuyucu.displayName ?? 'Orbit hesabı'}>
55+
{/* Ad artık profile GİDİYOR. Önce düz metindi ve profil sayfası hiçbir
56+
yerden bağlanmıyordu — var olan ama kimsenin bulamayacağı bir adres,
57+
olmayan adresten farksız. Giriş yapmış kullanıcının adına tıklamak
58+
hesap sayfasına gitmenin en beklenen yolu. */}
59+
<a class="oturum-ad" href="/profil/" title={okuyucu.displayName ?? 'Orbit hesabı'}>
5660
{okuyucu.displayName ?? 'Hesabım'}
57-
</span>
61+
</a>
5862
<button type="submit" class="oturum-dugme">Çıkış</button>
5963
</form>
6064
)}
@@ -82,6 +86,12 @@ const donus = Astro.url.pathname + Astro.url.search;
8286
white-space: nowrap;
8387
font-size: 0.8rem;
8488
color: var(--news-muted-strong);
89+
text-decoration: none;
90+
}
91+
92+
.oturum-ad:hover,
93+
.oturum-ad:focus-visible {
94+
text-decoration: underline;
8595
}
8696
.oturum-dugme {
8797
display: inline-flex;

‎src/layouts/BaseLayout.astro‎

Lines changed: 18 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ interface Props {
1111
* adresten sunan sayfalar (arşivin ilk sayfası ile ana sayfa) için. */
1212
canonicalPath?: string;
1313
type?: string;
14-
shellLayout?: boolean;
15-
hideHeader?: boolean;
1614
}
1715
1816
const {
@@ -23,8 +21,6 @@ const {
2321
noindex = false,
2422
canonicalPath,
2523
type = 'website',
26-
shellLayout = false,
27-
hideHeader = false
2824
} = Astro.props;
2925
3026
// SEO Hardening Logic
@@ -33,6 +29,23 @@ const finalOgImage = ogImage && typeof ogImage === 'string' && ogImage.trim() !=
3329
: '/og-default.jpg';
3430
3531
const canonicalURL = new URL(canonicalPath || Astro.url.pathname, Astro.site).toString();
32+
33+
/* Bu kabukta SAYFA BAŞLIĞI YOK ve olmamalı.
34+
*
35+
* Bir dönem burada blog döneminden kalma bir header duruyordu: "Samet Başbuğ"
36+
* logosu, eski gezinme bağlantıları, bozuk emoji taşıyan bir tema düğmesi.
37+
* Üretime hiç çıkmıyordu — `NewsLayout` hem `hideHeader` geçiyor hem de
38+
* `#main-header { display: none }` yazıyordu, yani aynı ölü şey iki ayrı
39+
* mekanizmayla saklanıyordu.
40+
*
41+
* Ama ölü değil UYUYORDU. `BaseLayout`u doğrudan kullanan yeni bir sayfa
42+
* yazdım ve hayalet tasarım ekrana geldi; hangi kabuğun ne çizdiğini bilmeden
43+
* "temel" adını taşıyan şeyi seçmiştim. Header, betiği ve stilleri
44+
* kaldırıldı, `hideHeader`/`shellLayout` propları da: tek değer alan bir prop
45+
* prop değil, saklanmış bir karardır.
46+
*
47+
* Başlık `NewsLayout`un işi. Yeni bir sayfa `InfoPageLayout` kullanır. */
48+
3649
const ogImageURL = new URL(finalOgImage, Astro.site).toString();
3750
// Paylaşım kartlarında görselin alternatif metni. Sayfa içindeki hero
3851
// görselleri aria-hidden bir sarmalayıcıda durduğu ve komşu başlık linkinin
@@ -151,7 +164,7 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
151164
</script>
152165
<ClientRouter />
153166
</head>
154-
<body class={shellLayout ? 'app-shell-layout' : undefined}>
167+
<body>
155168
<div id="progress-bar"></div>
156169

157170
<!-- Back to Top Button -->
@@ -164,32 +177,6 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
164177
<img id="lightbox-img" src="" alt="" />
165178
</div>
166179

167-
{!hideHeader && (
168-
<header transition:persist id="main-header">
169-
<nav>
170-
<div class="logo-area" id="logo-area">
171-
<a href="/" class="logo"><span class="logo-text">Samet Başbuğ</span></a>
172-
</div>
173-
<div class="nav-right" id="nav-right">
174-
<div class="links">
175-
<a href="/">Ana Sayfa</a>
176-
<a href="/hakkimizda/">Hakkımızda</a>
177-
<a href="/yazarlar/">Yazarlar</a>
178-
<a href="/iletisim/">İletişim</a>
179-
<a href="/rss.xml">RSS</a>
180-
</div>
181-
<div class="theme-switch-wrapper" id="theme-switch-wrapper">
182-
<button id="theme-toggle" class="theme-switch" aria-label="Temayı Değiştir">
183-
<div class="switch-handle">
184-
<span class="sun-icon">??</span>
185-
<span class="moon-icon">??</span>
186-
</div>
187-
</button>
188-
</div>
189-
</div>
190-
</nav>
191-
</header>
192-
)}
193180

194181
<main>
195182
<slot />
@@ -215,47 +202,10 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
215202

216203
applyTheme();
217204

218-
function attachThemeToggle() {
219-
const toggle = document.getElementById('theme-toggle');
220-
if (toggle) {
221-
toggle.replaceWith(toggle.cloneNode(true));
222-
const newToggle = document.getElementById('theme-toggle');
223-
newToggle.addEventListener('click', () => {
224-
const currentTheme = document.documentElement.getAttribute('data-theme');
225-
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
226-
setTheme(newTheme);
227-
});
228-
}
229-
}
230-
231-
function placeThemeSwitch() {
232-
const wrapper = document.getElementById('theme-switch-wrapper');
233-
const logoArea = document.getElementById('logo-area');
234-
const navRight = document.getElementById('nav-right');
235-
if (!wrapper || !logoArea || !navRight) return;
236-
237-
const isMobile = window.matchMedia('(max-width: 700px)').matches;
238-
if (isMobile) {
239-
if (wrapper.parentElement !== logoArea) logoArea.appendChild(wrapper);
240-
} else {
241-
if (wrapper.parentElement !== navRight) navRight.appendChild(wrapper);
242-
}
243-
}
244-
245205
// Header Scroll, Reading Progress & Back to Top
246206
function handleScroll() {
247-
const header = document.getElementById('main-header');
248207
const backToTop = document.getElementById('back-to-top');
249208

250-
if (header) {
251-
if (window.scrollY > 20) {
252-
header.classList.add('scrolled');
253-
} else {
254-
header.classList.remove('scrolled');
255-
}
256-
}
257-
258-
259209
if (backToTop) {
260210
if (window.scrollY > 300) {
261211
backToTop.classList.add('visible');
@@ -311,8 +261,6 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
311261

312262
document.addEventListener('astro:page-load', () => {
313263
applyTheme();
314-
placeThemeSwitch();
315-
attachThemeToggle();
316264
initLightbox();
317265
initCopyShare();
318266
initBackToTop();
@@ -323,7 +271,6 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
323271

324272
if (!window.__themeSwitchPlacementBound) {
325273
window.__themeSwitchPlacementBound = true;
326-
window.addEventListener('resize', placeThemeSwitch);
327274
}
328275

329276
document.addEventListener('astro:before-swap', (event) => {
@@ -481,114 +428,6 @@ const fullTitle = title === publicationName ? publicationName : `${publicationNa
481428
to { opacity: 1; transform: translateY(0); }
482429
}
483430
main { animation: fadeInUp 0.5s ease-out forwards; flex: 1; padding: 3rem 1rem; max-width: 850px; margin: 0 auto; width: 100%; }
484-
body.app-shell-layout main { animation: none; max-width: 1240px; padding-top: 0; }
485-
body.app-shell-layout header { display: none; }
486-
487-
header {
488-
padding: 1rem 1.5rem; max-width: 900px; margin: 1rem auto;
489-
width: calc(100% - 2rem); background: var(--card-bg);
490-
border-radius: 1rem; border: 1px solid var(--border);
491-
box-shadow: var(--shadow); backdrop-filter: blur(12px);
492-
position: sticky; top: 1rem; z-index: 50;
493-
display: flex; flex-direction: column; align-items: stretch; gap: 0.75rem;
494-
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
495-
}
496-
497-
header.scrolled { background: rgba(var(--card-bg-rgb), 0.8); max-width: 850px; margin-top: 0.5rem; }
498-
nav { display: flex; justify-content: space-between; align-items: center; width: 100%; gap: 1rem; }
499-
500-
.logo-area { display: inline-flex; align-items: center; gap: 0.7rem; flex-shrink: 0; }
501-
.nav-right { display: flex; align-items: center; gap: 1.5rem; min-width: 0; }
502-
.links { display: flex; align-items: center; gap: 0.5rem; }
503-
504-
.links a, .dropbtn {
505-
text-decoration: none; color: var(--secondary); font-weight: 500; font-size: 0.95rem;
506-
transition: all 0.2s; padding: 0.5rem 0.75rem; border-radius: 0.5rem;
507-
}
508-
.links a:hover, .dropdown:hover .dropbtn { color: var(--accent); background: var(--accent-light); }
509-
510-
/* Mobil Responsive Ayarlar� */
511-
@media (max-width: 700px) {
512-
header {
513-
height: auto;
514-
padding: 1rem;
515-
top: 0.5rem;
516-
}
517-
header.scrolled {
518-
height: auto;
519-
}
520-
nav {
521-
flex-direction: column;
522-
gap: 1rem;
523-
}
524-
.logo-area {
525-
width: 100%;
526-
justify-content: space-between;
527-
}
528-
.logo {
529-
font-size: clamp(1.02rem, 4.6vw, 1.2rem);
530-
}
531-
.nav-right {
532-
width: 100%;
533-
display: flex;
534-
justify-content: center;
535-
}
536-
.links {
537-
display: flex;
538-
flex-wrap: nowrap;
539-
justify-content: space-between;
540-
align-items: center;
541-
gap: 0.3rem;
542-
width: 100%;
543-
}
544-
.links a {
545-
font-size: clamp(0.78rem, 3.2vw, 0.9rem);
546-
padding: 0.3rem 0.2rem;
547-
white-space: nowrap;
548-
line-height: 1.25;
549-
}
550-
551-
.theme-switch-wrapper {
552-
padding-left: 0;
553-
border-left: 0;
554-
margin-left: auto;
555-
}
556-
}
557-
558-
/* Dropdown Stilleri */
559-
.dropdown { position: relative; display: inline-block; }
560-
.dropbtn { background: none; border: none; font-family: inherit; cursor: pointer; display: flex; align-items: center; gap: 0.25rem; }
561-
.chevron-icon { width: 1rem; height: 1rem; transition: transform 0.3s ease; }
562-
.dropdown:hover .chevron-icon { transform: rotate(180deg); }
563-
564-
.dropdown-content {
565-
position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(10px);
566-
background: var(--card-bg); border: 1px solid var(--border); min-width: 140px;
567-
box-shadow: var(--shadow); border-radius: 0.75rem; opacity: 0; visibility: hidden;
568-
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); z-index: 100; padding: 0.5rem; backdrop-filter: blur(10px);
569-
}
570-
.dropdown:hover .dropdown-content { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(5px); }
571-
.dropdown-content a { color: var(--text); padding: 0.6rem 1rem; display: block; font-size: 0.9rem; margin: 0; }
572-
573-
.theme-switch-wrapper { display: inline-flex; align-items: center; border-left: 0; padding-left: 0; }
574-
@media (min-width: 701px) {
575-
.theme-switch-wrapper { border-left: 1px solid var(--border); padding-left: 1.2rem; }
576-
}
577-
.theme-switch { background: var(--muted); border: 1px solid var(--border); width: 3.5rem; height: 1.8rem; border-radius: 2rem; cursor: pointer; position: relative; padding: 0; transition: all 0.3s ease; }
578-
.switch-handle { width: 1.4rem; height: 1.4rem; background: var(--card-bg); border-radius: 50%; position: absolute; left: 0.2rem; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; font-size: 0.8rem; box-shadow: var(--shadow); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
579-
.sun-icon { opacity: 1; } .moon-icon { opacity: 1; }
580-
.switch-handle .sun-icon { display: block; } .switch-handle .moon-icon { display: none; }
581-
[data-theme="dark"] .switch-handle { left: calc(100% - 1.6rem); background: #1e293b; }
582-
[data-theme="dark"] .switch-handle .sun-icon { display: none; } [data-theme="dark"] .switch-handle .moon-icon { display: block; }
583-
584-
@media (prefers-color-scheme: dark) {
585-
:root:not([data-theme="light"]) .switch-handle { left: calc(100% - 1.6rem); background: #1e293b; }
586-
:root:not([data-theme="light"]) .switch-handle .sun-icon { display: none; }
587-
:root:not([data-theme="light"]) .switch-handle .moon-icon { display: block; }
588-
}
589-
590-
.logo { font-size: 1.25rem; font-weight: 800; color: var(--accent); text-decoration: none; }
591-
.logo-text { background: linear-gradient(to right, var(--accent), #818cf8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
592431

593432
h1, h2, h3 { line-height: 1.3; margin-bottom: 1.5rem; color: var(--text); font-weight: 800; }
594433
.hero-title { font-size: 3.5rem; background: linear-gradient(to right, var(--accent), #818cf8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; display: inline-block; }

‎src/layouts/NewsLayout.astro‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const newsHomePath = getNewsHomePath();
5252
const blogHomeHref = isNewsSubdomainEnabled() ? getMainSiteUrl() : '/';
5353
---
5454

55-
<BaseLayout title={title} description={description} hideHeader={true} noindex={noindex} canonicalPath={canonicalPath} ogImage={ogImage} ogImageAlt={ogImageAlt}>
55+
<BaseLayout title={title} description={description} noindex={noindex} canonicalPath={canonicalPath} ogImage={ogImage} ogImageAlt={ogImageAlt}>
5656
<section class="news-app-shell" data-news-home-path={newsHomePath}>
5757
<header class="news-masthead">
5858
<div class="news-masthead-wrap">
@@ -223,9 +223,9 @@ const blogHomeHref = isNewsSubdomainEnabled() ? getMainSiteUrl() : '/';
223223
:global([data-theme='light'] body) {
224224
background: #f6f4ef;
225225
}
226-
:global(#main-header) {
227-
display: none;
228-
}
226+
/* `#main-header` gizleme kuralı KALDIRILDI: gizlenecek bir şey kalmadı.
227+
Blog döneminden kalma header `BaseLayout`tan silindi; burada durması
228+
"hâlâ bir header var ve saklıyoruz" izlenimi verirdi. */
229229
:global(main) {
230230
width: 100% !important;
231231
max-width: none !important;

‎src/server/routes/denetim.astro‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
export const prerender = false;
1818
19-
import BaseLayout from '../../layouts/BaseLayout.astro';
19+
import InfoPageLayout from '../../layouts/InfoPageLayout.astro';
2020
import { getDatabase } from '#runtime-env';
2121
import { oturumCereziVarMi, oturumOku } from '../session';
2222
@@ -83,10 +83,9 @@ const kisa = (value: string | null) => {
8383
};
8484
---
8585

86-
<BaseLayout title="Denetim" description="Ajan eylemlerinin izi." noindex>
87-
<main class="denetim">
88-
<h1>Denetim</h1>
89-
<p class="alt">Ajan eylemlerinin izi. Bu sayfa önbelleğe girmiyor ve arama motorlarına kapalı.</p>
86+
<InfoPageLayout title="Denetim" description="Ajan eylemlerinin izi: yapılanlar, reddedilenler, yayından kaldırmalar." kicker="Hesap" updatedLabel="">
87+
<div class="denetim">
88+
<p class="alt"><a href="/profil/">← Profil</a> · Bu sayfa önbelleğe girmiyor ve arama motorlarına kapalı.</p>
9089

9190
<section>
9291
<h2>Yayıncılar</h2>
@@ -163,12 +162,10 @@ const kisa = (value: string | null) => {
163162
</tbody>
164163
</table>}
165164
</section>
166-
</main>
167-
</BaseLayout>
165+
</div>
166+
</InfoPageLayout>
168167

169168
<style>
170-
.denetim { max-width: 68rem; margin: 0 auto; padding: 2rem 1.25rem 4rem; }
171-
h1 { font-size: 1.75rem; margin: 0 0 .35rem; }
172169
.alt { color: var(--secondary); margin: 0 0 2.5rem; font-size: .95rem; }
173170
section { margin-bottom: 2.75rem; }
174171
h2 { font-size: 1.05rem; margin: 0 0 .75rem; font-weight: 600; }

0 commit comments

Comments
 (0)