Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 098d444b32 |
+2
-1
@@ -153,6 +153,7 @@ export default async function RootLayout({
|
||||
const pathname = headersList.get("x-pathname") || headersList.get("x-invoke-path") || "";
|
||||
const isEmbedRoute = pathname.startsWith("/embed");
|
||||
const isKidsRoute = pathname.startsWith("/kids");
|
||||
const isPresentationRoute = pathname.startsWith("/presentation");
|
||||
|
||||
const locale = await getLocale();
|
||||
const messages = await getMessages();
|
||||
@@ -191,7 +192,7 @@ export default async function RootLayout({
|
||||
<Analytics gaId={process.env.GOOGLE_ANALYTICS_ID} />
|
||||
)}
|
||||
<Providers locale={locale} messages={messages} theme={config.theme} branding={{ ...config.branding, useCloneBranding: config.homepage?.useCloneBranding }}>
|
||||
{isEmbedRoute || isKidsRoute ? (
|
||||
{isEmbedRoute || isKidsRoute || isPresentationRoute ? (
|
||||
children
|
||||
) : (
|
||||
<>
|
||||
|
||||
+505
-211
@@ -1,233 +1,527 @@
|
||||
import { SlideDeck, SlideTitle, SlideContent, SlideHighlight } from "@/components/presentation/SlideDeck";
|
||||
import { MoveRight, Star, GitMerge, FileCode2, Sparkles, MessageSquare, Globe, Users, Code, Zap, Lightbulb } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Blocks,
|
||||
Bot,
|
||||
BrainCircuit,
|
||||
CheckCircle2,
|
||||
CircleDotDashed,
|
||||
ClipboardCheck,
|
||||
Clock3,
|
||||
DatabaseZap,
|
||||
FileText,
|
||||
Filter,
|
||||
GitBranch,
|
||||
Layers3,
|
||||
Lightbulb,
|
||||
MessageSquareText,
|
||||
Network,
|
||||
PackageCheck,
|
||||
Puzzle,
|
||||
RefreshCw,
|
||||
Route,
|
||||
Scissors,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
Target,
|
||||
TimerReset,
|
||||
WandSparkles,
|
||||
} from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import type { ReactNode } from "react";
|
||||
import { SlideContent, SlideDeck, SlideHighlight, SlideTitle } from "@/components/presentation/SlideDeck";
|
||||
|
||||
export const metadata = {
|
||||
title: "Why prompts.chat? | Presentation",
|
||||
description: "Discover why prompts are more important than ever in the agentic era.",
|
||||
title: "Prompt Tasarımı ve Context Yönetimi | Presentation",
|
||||
description: "30 dakikalık Türkçe konuşma: prompt tasarımı, context yönetimi ve prompts.chat.",
|
||||
};
|
||||
|
||||
const speakerNotes = [
|
||||
"Açılışta sunumun amacını netleştir: Bu konuşma prompt ezberlemek değil, bağlamı bilinçli yönetmek üzerine. 30 dakika sonunda herkesin kendi işine uygulayabileceği bir kontrol listesi olacak.",
|
||||
"Konuşmacı slaytı kısa tutulmalı. Kişisel hikaye: Awesome ChatGPT Prompts ile başlayan topluluk deneyimi, prompts.chat ile promptların paylaşılabilir, sürümlenebilir ve geliştirilebilir varlıklara dönüşmesi.",
|
||||
"Akışı anlat: önce zihinsel model, sonra promptun anatomisi, sonra context yönetimi ve ölçüm. prompts.chat bölümünü ürün demosu gibi değil, bu prensiplerin pratik karşılığı olarak konumlandır.",
|
||||
"Ana mesaj: Modeli sadece cevap makinesi gibi değil, sınırlı dikkat alanına sahip bir ekip arkadaşı gibi düşünün. Prompt tasarımı görevi tanımlar; context yönetimi modelin neye bakacağını seçer.",
|
||||
"Prompt tasarımının yalnızca güzel cümle yazmak olmadığını vurgula. Rol, hedef, veri, sınır, örnek ve çıktı sözleşmesi bir araya geldiğinde modelin çalışma alanı oluşur.",
|
||||
"Bu slaytta kötü prompt / iyi prompt farkını canlı okuyarak göster. İyi örneğin daha uzun olduğu için değil, karar yükünü azalttığı için iyi olduğunu söyle.",
|
||||
"Context penceresini dosya dolabı değil, toplantı masası metaforu ile anlat. Masaya her şeyi koymak odak kaybettirir; doğru şeyleri doğru sırayla koymak performansı artırır.",
|
||||
"Bağlam katmanlarını sırayla açıkla. Sistem ve geliştirici talimatlarının politikayı, kullanıcı mesajının amacı, araç sonuçlarının kanıtı, geçmişin ise sürekliliği taşıdığını anlat.",
|
||||
"Önemli ayrım: Context çokluğu kalite demek değildir. Gürültü, eski kararlar ve çelişkili talimatlar modeli kararsızlaştırır. Context tasarrufu aynı zamanda kalite kontrolüdür.",
|
||||
"Kısa bir teknik çerçeve ver: seç, sırala, sıkıştır, doğrula. Bu dört fiil context yönetiminin günlük pratiği olabilir.",
|
||||
"Örnekler model davranışını güçlü biçimde kilitler. Ancak yanlış örnekler de yanlış davranışı kilitler. Örnekleri az ama temsil gücü yüksek seçmek gerektiğini vurgula.",
|
||||
"Çıktı sözleşmesi özellikle ekiplerde önemlidir. JSON, tablo, diff, adım adım plan gibi formatlar otomasyon ve tekrar üretilebilirlik sağlar.",
|
||||
"Araç kullanan ajanlarda prompt, sadece cevap formatını değil yetki sınırını da belirler. Ne zaman arama yapmalı, ne zaman sormalı, ne zaman durmalı gibi kararları açık yazın.",
|
||||
"Context yönetiminin operasyonel tarafı: uzun konuşmalarda özet, dosya tabanlı işlerde ilgili parçalar, arama tabanlı işlerde kaynak ve alıntı. Her şeyi tek mesaja doldurmak yerine akış tasarla.",
|
||||
"Hata modlarını örneklerle anlat: belirsiz hedef, eski bağlam, çelişki, görünmez varsayım, format eksikliği. Bunlar model hatası gibi görünür ama çoğu zaman tasarım hatasıdır.",
|
||||
"Ölçüm slaytında küçük bir test setinin değerini anlat. Aynı promptu birkaç gerçek senaryo ile denemek, tek seferlik iyi cevaptan daha güvenilirdir.",
|
||||
"prompts.chat'i bağlamla ilişkilendir: iyi promptlar tek kişide kalmamalı. Paylaşım, sürümleme ve geri bildirim prompt kalitesini artırır.",
|
||||
"Ekip pratiğine geç: promptlar kod gibi yaşamalı. Sahiplik, değişiklik geçmişi, review ve örnek çıktılar promptun güvenilirliğini artırır.",
|
||||
"Kapanış kontrol listesini yavaş oku. Dinleyicilerin kendi promptlarını bu beş soruyla gözden geçirmesini iste.",
|
||||
"Son slaytta tek cümlelik kapanış: İyi prompt, modele ne yapacağını söyler; iyi context yönetimi, neye dayanarak yapacağını belirler.",
|
||||
];
|
||||
|
||||
type CardProps = {
|
||||
icon: LucideIcon;
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
accent?: string;
|
||||
};
|
||||
|
||||
function Card({ icon: Icon, title, children, accent = "text-primary" }: CardProps) {
|
||||
return (
|
||||
<div className="rounded-3xl border border-border/70 bg-background/70 p-6 shadow-sm backdrop-blur transition-transform duration-300 hover:-translate-y-1">
|
||||
<div className={`mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 ${accent}`}>
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="mb-2 text-2xl font-bold text-foreground">{title}</h3>
|
||||
<p className="text-lg leading-relaxed text-muted-foreground">{children}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Pill({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<span className="inline-flex items-center rounded-full border border-primary/20 bg-primary/10 px-4 py-2 text-base font-semibold text-primary">
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function CodePanel({ children, title = "prompt.md" }: { children: ReactNode; title?: string }) {
|
||||
return (
|
||||
<div className="overflow-hidden rounded-3xl border border-border bg-zinc-950 text-zinc-100 shadow-2xl">
|
||||
<div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-5 py-3">
|
||||
<div className="flex gap-2">
|
||||
<span className="h-3 w-3 rounded-full bg-red-400" />
|
||||
<span className="h-3 w-3 rounded-full bg-yellow-400" />
|
||||
<span className="h-3 w-3 rounded-full bg-green-400" />
|
||||
</div>
|
||||
<span className="font-mono text-xs text-zinc-400">{title}</span>
|
||||
</div>
|
||||
<pre className="whitespace-pre-wrap p-6 font-mono text-sm leading-relaxed md:text-base">{children}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FlowStep({ icon: Icon, title, text }: { icon: LucideIcon; title: string; text: string }) {
|
||||
return (
|
||||
<div className="relative rounded-3xl border border-border/70 bg-background/75 p-5 shadow-sm">
|
||||
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold">{title}</h3>
|
||||
<p className="mt-2 text-lg leading-relaxed text-muted-foreground">{text}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ContextLayer({ label, description, tone }: { label: string; description: string; tone: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
|
||||
<div className={`h-14 w-2 rounded-full ${tone}`} />
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{label}</h3>
|
||||
<p className="text-base text-muted-foreground">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MiniChecklist({ items }: { items: string[] }) {
|
||||
return (
|
||||
<div className="grid gap-3">
|
||||
{items.map((item) => (
|
||||
<div key={item} className="flex items-start gap-3 rounded-2xl border border-border/70 bg-background/70 p-4 text-xl font-semibold">
|
||||
<CheckCircle2 className="mt-1 h-6 w-6 flex-none text-primary" />
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PresentationPage() {
|
||||
return (
|
||||
<SlideDeck>
|
||||
{/* 1. Title Slide */}
|
||||
<div className="flex flex-col items-center justify-center text-center h-full">
|
||||
<div className="w-24 h-24 bg-primary/10 rounded-3xl flex items-center justify-center mb-8 rotate-12 transition-transform hover:rotate-0 duration-500">
|
||||
<Sparkles className="w-12 h-12 text-primary" />
|
||||
<SlideDeck notes={speakerNotes}>
|
||||
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
|
||||
<div className="mb-8 flex h-24 w-24 rotate-6 items-center justify-center rounded-[2rem] bg-primary/10 text-primary shadow-xl shadow-primary/10">
|
||||
<WandSparkles className="h-12 w-12" />
|
||||
</div>
|
||||
<SlideTitle className="mb-6">Why prompts.chat?</SlideTitle>
|
||||
<SlideContent className="max-w-3xl mb-12">Discover why prompts are more important than ever in the agentic era.</SlideContent>
|
||||
<p className="text-sm text-muted-foreground animate-pulse mt-8">
|
||||
Use arrow keys <MoveRight className="inline w-4 h-4 mx-1" /> or swipe to navigate
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 2. The Genesis */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Star className="w-12 h-12 text-yellow-500 mb-6" />
|
||||
<SlideTitle>The History of prompts.chat</SlideTitle>
|
||||
<SlideContent>
|
||||
From a simple repository to a full-fledged platform. We started as Awesome ChatGPT Prompts, and evolved to support the entire AI community with typed prompts, workflows, and skills.
|
||||
<SlideTitle className="max-w-5xl">Prompt Tasarımı ve Context Yönetimi</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-3xl">
|
||||
30 dakikalık pratik bir çerçeve: daha iyi talimat, daha temiz bağlam, daha güvenilir AI çıktısı.
|
||||
</SlideContent>
|
||||
<div className="mt-12 p-6 bg-muted/50 rounded-2xl border border-border max-w-2xl">
|
||||
<p className="text-lg text-foreground font-mono">
|
||||
Awesome ChatGPT Prompts → <SlideHighlight>prompts.chat</SlideHighlight>
|
||||
</p>
|
||||
<div className="mt-10 flex flex-wrap justify-center gap-3">
|
||||
<Pill>prompts.chat/presentation</Pill>
|
||||
<Pill>Ok tuşları, boşluk, F, N</Pill>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3. The Paradigm Shift */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Zap className="w-12 h-12 text-blue-500 mb-6" />
|
||||
<SlideTitle>The Agentic Era</SlideTitle>
|
||||
<SlideContent>
|
||||
Why are prompts still important? Because agents need instructions. As AI becomes more autonomous, the quality of instructions determines the quality of the outcome.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 4. The Core Question */}
|
||||
<div className="flex flex-col items-center justify-center text-center h-full">
|
||||
<Lightbulb className="w-16 h-16 text-yellow-400 mb-8" />
|
||||
<SlideTitle className="text-5xl md:text-6xl">Wait, isn't AI getting smarter?</SlideTitle>
|
||||
<SlideContent className="max-w-4xl mt-8">
|
||||
Yes, but <SlideHighlight>smart AI still needs direction.</SlideHighlight>
|
||||
<br /><br />
|
||||
A genius without instructions is just a very capable idle machine.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 5. The Agentic Need */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<SlideTitle>The Agentic Need</SlideTitle>
|
||||
<SlideContent>
|
||||
Agents require precise instructions, constraints, and goal definitions.
|
||||
<ul className="mt-8 space-y-6 list-disc list-inside ml-4 text-foreground/80 text-2xl md:text-3xl">
|
||||
<li>What tools can they use?</li>
|
||||
<li>What are their boundaries?</li>
|
||||
<li>How should they format the output?</li>
|
||||
<li>What tone should they adopt?</li>
|
||||
</ul>
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 6. The SLM Revolution */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Globe className="w-12 h-12 text-green-500 mb-6" />
|
||||
<SlideTitle>Crucial for SLMs</SlideTitle>
|
||||
<SlideContent>
|
||||
Small Language Models (SLMs) are the future of edge computing. They require precise, well-crafted prompts to perform tasks accurately without the massive parameter count of frontier models.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 7. SLM Constraints */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<SlideTitle>SLM Constraints</SlideTitle>
|
||||
<SlideContent>
|
||||
Smaller models lack the vast "common sense" of 1T+ parameter models.
|
||||
<br /><br />
|
||||
They require <SlideHighlight>highly optimized, battle-tested prompts</SlideHighlight> to punch above their weight class and run efficiently on local devices.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 8. The New Primitive */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<FileCode2 className="w-12 h-12 text-purple-500 mb-6" />
|
||||
<SlideTitle>Prompts are New Code Snippets</SlideTitle>
|
||||
<SlideContent>
|
||||
Just as developers copy/paste code snippets from StackOverflow, AI practitioners now share prompt templates. Prompts are the new primitive of programming.
|
||||
</SlideContent>
|
||||
<div className="mt-12 flex items-center gap-4 text-xl md:text-2xl font-mono text-muted-foreground bg-muted p-6 rounded-xl border max-w-fit">
|
||||
<span>const codeSnippet = "..."</span>
|
||||
<MoveRight className="w-6 h-6 text-primary mx-2" />
|
||||
<span className="text-primary">const promptTemplate = "..."</span>
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-[1fr_0.95fr]">
|
||||
<div className="relative order-2 lg:order-1">
|
||||
<div className="absolute -left-8 top-10 h-72 w-72 rounded-full bg-primary/20 blur-3xl" />
|
||||
<div className="relative mx-auto w-full max-w-[34rem]">
|
||||
<div className="absolute -inset-4 -rotate-3 rounded-[3rem] bg-gradient-to-br from-primary/30 via-primary/10 to-transparent" />
|
||||
<div className="relative overflow-hidden rounded-[3rem] border border-border bg-background shadow-2xl">
|
||||
<Image
|
||||
src="https://github.com/f.png"
|
||||
alt="Fatih Kadir Akın profil fotoğrafı"
|
||||
width={900}
|
||||
height={900}
|
||||
priority
|
||||
unoptimized
|
||||
className="aspect-square w-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 via-black/45 to-transparent p-8 text-white">
|
||||
<p className="text-sm font-bold uppercase tracking-[0.35em] text-white/70">Konuşmacı</p>
|
||||
<h2 className="mt-2 text-5xl font-black tracking-tight">Fatih Kadir Akın</h2>
|
||||
<p className="mt-3 max-w-md text-lg font-semibold leading-snug text-white/85">
|
||||
WordPress Developer Advocate, Automattic - Creator of prompts.chat
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order-1 lg:order-2">
|
||||
<SlideTitle className="mb-5">Merhaba, ben Fatih.</SlideTitle>
|
||||
<SlideContent className="max-w-2xl">
|
||||
Geliştiricilerin hayatını kolaylaştıran uygulamalar geliştiriyorum; bunlardan biri de{" "}
|
||||
<SlideHighlight>prompts.chat</SlideHighlight>.
|
||||
</SlideContent>
|
||||
<div className="mt-10 flex flex-wrap items-center gap-5">
|
||||
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
|
||||
<Image
|
||||
src="https://cdn.simpleicons.org/wordpress/21759B"
|
||||
alt="WordPress"
|
||||
width={40}
|
||||
height={40}
|
||||
unoptimized
|
||||
className="h-10 w-10"
|
||||
/>
|
||||
<span className="text-xl font-bold text-foreground">WordPress</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
|
||||
<Image
|
||||
src="https://cdn.simpleicons.org/automattic/000000"
|
||||
alt="Automattic"
|
||||
width={40}
|
||||
height={40}
|
||||
unoptimized
|
||||
className="h-10 w-10 dark:invert"
|
||||
/>
|
||||
<span className="text-xl font-bold text-foreground">Automattic</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 9. Open Source AI */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Users className="w-12 h-12 text-indigo-500 mb-6" />
|
||||
<SlideTitle>Community Sharing</SlideTitle>
|
||||
<SlideContent>
|
||||
Nobody learns in isolation. By sharing prompts, we accelerate the collective understanding of how to communicate with AI. It's the open-source movement for human-AI interaction.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 10. Collective Intelligence */}
|
||||
<div className="flex flex-col items-center justify-center text-center h-full">
|
||||
<SlideTitle className="text-5xl md:text-6xl">Collective Intelligence</SlideTitle>
|
||||
<SlideContent className="max-w-4xl mt-8">
|
||||
We are building the <SlideHighlight>largest open repository</SlideHighlight> of human-AI interaction patterns.
|
||||
<br /><br />
|
||||
Tested, versioned, and peer-reviewed.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 11. Feature - Typed Prompts */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Code className="w-12 h-12 text-red-500 mb-6" />
|
||||
<SlideTitle>Feature: Typed Prompts</SlideTitle>
|
||||
<SlideContent>
|
||||
Natural language is ambiguous. <SlideHighlight>Typed Prompts</SlideHighlight> bring structure.
|
||||
<br /><br />
|
||||
Define inputs, outputs, and variables systematically so prompts can be executed predictably via APIs.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 12. Feature - Workflows */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<div className="flex gap-2 mb-6">
|
||||
<div className="w-8 h-8 rounded bg-primary"></div>
|
||||
<MoveRight className="w-8 h-8 text-muted-foreground" />
|
||||
<div className="w-8 h-8 rounded bg-primary/70"></div>
|
||||
<MoveRight className="w-8 h-8 text-muted-foreground" />
|
||||
<div className="w-8 h-8 rounded bg-primary/40"></div>
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Bugünkü rota</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
<FlowStep icon={BrainCircuit} title="Zihinsel model" text="Modelin neyi, ne sırayla ve hangi amaçla görmesi gerektiğini düşünmek." />
|
||||
<FlowStep icon={MessageSquareText} title="Prompt anatomisi" text="Rol, hedef, bağlam, kısıtlar, örnekler ve çıktı sözleşmesi." />
|
||||
<FlowStep icon={Layers3} title="Context yönetimi" text="Sınırlı dikkat alanını seçmek, sıralamak, sıkıştırmak ve temizlemek." />
|
||||
<FlowStep icon={ClipboardCheck} title="Ölçüm ve paylaşım" text="Promptu tek seferlik cümle değil, iyileştirilebilir artefact yapmak." />
|
||||
</div>
|
||||
<SlideTitle>Feature: Workflows</SlideTitle>
|
||||
<SlideContent>
|
||||
Some tasks are too complex for a single prompt.
|
||||
<br /><br />
|
||||
Chain multiple prompts together to create <SlideHighlight>Workflows</SlideHighlight> — dividing and conquering complex agentic tasks.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 13. Feature - Agent Skills */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<SlideTitle>Feature: Agent Skills</SlideTitle>
|
||||
<SlideContent>
|
||||
Equip coding assistants (like Claude, Cursor, Windsurf) with specialized, multi-file capabilities.
|
||||
<br /><br />
|
||||
Give your AI the context and rules it needs to build within your specific tech stack.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 14. Feature - Change Requests */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<GitMerge className="w-12 h-12 text-orange-500 mb-6" />
|
||||
<SlideTitle>Feature: Change Requests</SlideTitle>
|
||||
<SlideContent>
|
||||
Prompts evolve. We've introduced <SlideHighlight>Pull Requests for Prompts.</SlideHighlight>
|
||||
<br /><br />
|
||||
Collaborate, suggest improvements, and refine instructions together as a community.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 15. For Developers */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<SlideTitle>For Developers</SlideTitle>
|
||||
<SlideContent>
|
||||
prompts.chat isn't just for end-users. With features like Agent Skills, Typed Prompts, and API integrations, it's a vital tool for developers building the next generation of AI apps.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 16. For Everyone */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<MessageSquare className="w-12 h-12 text-pink-500 mb-6" />
|
||||
<SlideTitle>For Everyone</SlideTitle>
|
||||
<SlideContent>
|
||||
Discover, collect, and learn from <SlideHighlight>Promptmasters</SlideHighlight>.
|
||||
<br /><br />
|
||||
A beautifully designed, accessible platform to find exactly what you need to make AI work for you.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 17. Self-Hosted */}
|
||||
<div className="flex flex-col justify-center h-full">
|
||||
<Globe className="w-12 h-12 text-teal-500 mb-6" />
|
||||
<SlideTitle>Fully Self-Hosted</SlideTitle>
|
||||
<SlideContent>
|
||||
Your data, your platform.
|
||||
<br /><br />
|
||||
prompts.chat is <SlideHighlight>100% open-source</SlideHighlight> and deployable to any server or cloud provider. Own your organization's prompt library securely.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 18. The Vision */}
|
||||
<div className="flex flex-col items-center justify-center text-center h-full">
|
||||
<SlideTitle className="text-5xl md:text-6xl">The Vision</SlideTitle>
|
||||
<SlideContent className="max-w-4xl mt-8">
|
||||
To create the <SlideHighlight>standard protocol</SlideHighlight> for human-AI interaction.
|
||||
<br /><br />
|
||||
Where every great instruction is shared, improved, and accessible to all.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
{/* 19. Call to Action */}
|
||||
<div className="flex flex-col items-center justify-center text-center h-full">
|
||||
<div className="w-24 h-24 bg-primary/10 rounded-full flex items-center justify-center mb-8">
|
||||
<Users className="w-12 h-12 text-primary" />
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>AI ile çalışmak: çok zeki ama bağlama bağımlı bir ekip arkadaşı</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={Target} title="Amaç net olmalı">
|
||||
Modelin optimizasyon hedefi belirsizse cevap da belirsizleşir.
|
||||
</Card>
|
||||
<Card icon={ShieldCheck} title="Sınırlar görünür olmalı">
|
||||
Ne yapılmayacağı, ne yapılacağı kadar önemlidir.
|
||||
</Card>
|
||||
<Card icon={DatabaseZap} title="Kanıt seçilmeli">
|
||||
Model en son ve en belirgin bağlama fazla ağırlık verir.
|
||||
</Card>
|
||||
</div>
|
||||
<SlideTitle>Join the Community</SlideTitle>
|
||||
<SlideContent className="max-w-2xl mb-12">
|
||||
Start exploring, sharing, and building the future of AI interaction today.
|
||||
<SlideContent className="mt-10 max-w-4xl">
|
||||
İyi prompt <SlideHighlight>ne yapılacağını</SlideHighlight>, iyi context yönetimi ise{" "}
|
||||
<SlideHighlight>neye dayanarak yapılacağını</SlideHighlight> belirler.
|
||||
</SlideContent>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<Link href="/discover">
|
||||
<Button size="lg" className="text-lg px-8 py-6 rounded-xl">Explore Prompts</Button>
|
||||
</Link>
|
||||
<Link href="https://github.com/fka/awesome-chatgpt-prompts" target="_blank">
|
||||
<Button size="lg" variant="outline" className="text-lg px-8 py-6 rounded-xl">Star on GitHub</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Prompt tasarımı cümle süslemek değildir</SlideTitle>
|
||||
<SlideContent>
|
||||
Prompt, modelle aranızdaki <SlideHighlight>çalışma sözleşmesidir</SlideHighlight>.
|
||||
Cevabın amacı, kapsamı, kaynakları, formatı ve kalite barı bu sözleşmede yer alır.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
{[
|
||||
["Rol", "Hangi perspektiften düşünecek?"],
|
||||
["Görev", "Tam olarak neyi üretecek?"],
|
||||
["Bağlam", "Hangi bilgiye dayanacak?"],
|
||||
["Kısıt", "Neyi yapmayacak veya aşmayacak?"],
|
||||
["Çıktı", "Nasıl teslim edecek?"],
|
||||
].map(([label, text]) => (
|
||||
<div key={label} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 font-black text-primary">{label[0]}</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{label}</h3>
|
||||
<p className="text-muted-foreground">{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Kötü prompt / iyi prompt</SlideTitle>
|
||||
<SlideContent>
|
||||
Uzun olan değil, <SlideHighlight>karar yükünü azaltan</SlideHighlight> prompt daha iyidir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="space-y-5">
|
||||
<CodePanel title="belirsiz.prompt">
|
||||
{`Bana context management hakkında iyi bir yazı yaz.`}
|
||||
</CodePanel>
|
||||
<CodePanel title="tasarlanmis.prompt">
|
||||
{`Rol: Kıdemli AI ürün danışmanı.
|
||||
Amaç: Teknik olmayan ürün ekibine context management anlat.
|
||||
Bağlam: 30 dakikalık şirket içi eğitim.
|
||||
Kısıt: Jargon kullanma, 3 örnek ver, riskleri belirt.
|
||||
Çıktı: Başlık, 5 maddelik özet, uygulanabilir kontrol listesi.`}
|
||||
</CodePanel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Context penceresi dosya dolabı değil, toplantı masasıdır</SlideTitle>
|
||||
<SlideContent className="max-w-5xl">
|
||||
Masaya her şeyi koyarsanız ekip odaklanamaz. Doğru belgeleri, doğru sırayla, doğru ayrıntı seviyesinde getirirsiniz.
|
||||
</SlideContent>
|
||||
<div className="mt-10 grid gap-5 md:grid-cols-4">
|
||||
<FlowStep icon={Filter} title="Seç" text="İlgili olanı ayır." />
|
||||
<FlowStep icon={Route} title="Sırala" text="Önceliği görünür yap." />
|
||||
<FlowStep icon={Scissors} title="Sıkıştır" text="Gürültüyü azalt." />
|
||||
<FlowStep icon={CheckCircle2} title="Doğrula" text="Kaynak ve sonucu kontrol et." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.9fr_1.1fr]">
|
||||
<div>
|
||||
<SlideTitle>Bağlam katmanları</SlideTitle>
|
||||
<SlideContent>
|
||||
Model tek bir metni değil, üst üste binmiş talimat ve kanıt katmanlarını yorumlar.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-3">
|
||||
<ContextLayer label="Sistem" description="Kimlik, güvenlik ve en üst kurallar." tone="bg-red-500" />
|
||||
<ContextLayer label="Geliştirici" description="Uygulama davranışı, araç kullanımı, format kuralları." tone="bg-orange-500" />
|
||||
<ContextLayer label="Kullanıcı" description="Anlık amaç, ihtiyaç ve başarı tanımı." tone="bg-primary" />
|
||||
<ContextLayer label="Araç sonuçları" description="Arama, dosya, API veya veritabanından gelen kanıt." tone="bg-emerald-500" />
|
||||
<ContextLayer label="Geçmiş" description="Konuşma sürekliliği ve önceki kararlar." tone="bg-sky-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Daha fazla context her zaman daha iyi değildir</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={CircleDotDashed} title="Gürültü" accent="text-orange-500">
|
||||
Alakasız detaylar, önemli sinyali gömer.
|
||||
</Card>
|
||||
<Card icon={RefreshCw} title="Eski kararlar" accent="text-sky-500">
|
||||
Geçmişte doğru olan bilgi bugün yanlış olabilir.
|
||||
</Card>
|
||||
<Card icon={Puzzle} title="Çelişkiler" accent="text-red-500">
|
||||
Model hangi talimata uyacağını tahmin etmek zorunda kalır.
|
||||
</Card>
|
||||
</div>
|
||||
<SlideContent className="mt-10">
|
||||
Context yönetimi, token tasarrufu değil; <SlideHighlight>dikkat yönetimidir</SlideHighlight>.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Pratik yöntem: seç, sırala, sıkıştır, doğrula</SlideTitle>
|
||||
<div className="grid gap-5 lg:grid-cols-4">
|
||||
<FlowStep icon={Filter} title="Seç" text="Bu görev için gerçekten gerekli bilgi ne?" />
|
||||
<FlowStep icon={Layers3} title="Sırala" text="En önemli talimat ve kanıt en görünür yerde mi?" />
|
||||
<FlowStep icon={Scissors} title="Sıkıştır" text="Tekrar, sohbet gürültüsü ve eski kararlar temizlendi mi?" />
|
||||
<FlowStep icon={ClipboardCheck} title="Doğrula" text="Cevap kaynak, format ve başarı kriteriyle uyuşuyor mu?" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Örnekler davranışı kilitler</SlideTitle>
|
||||
<SlideContent>
|
||||
Few-shot örnekler modele sadece formatı değil, <SlideHighlight>neyi iyi saydığınızı</SlideHighlight> gösterir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
|
||||
<div className="mb-6 flex items-center gap-3">
|
||||
<Lightbulb className="h-7 w-7 text-yellow-500" />
|
||||
<h3 className="text-2xl font-bold">Örnek seçerken</h3>
|
||||
</div>
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"Gerçek kullanım senaryosuna benziyor mu?",
|
||||
"Başarılı ve başarısız örnek ayrımı var mı?",
|
||||
"Format, ton ve ayrıntı seviyesi temsil ediliyor mu?",
|
||||
"Yanlış genelleme yaratacak özel durum var mı?",
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Çıktı sözleşmesi otomasyonun kapısıdır</SlideTitle>
|
||||
<SlideContent>
|
||||
İnsan okuyacaksa okunabilirlik, sistem okuyacaksa <SlideHighlight>şema</SlideHighlight> önemlidir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<CodePanel title="output-contract.json">
|
||||
{`{
|
||||
"summary": "en fazla 3 cümle",
|
||||
"risks": ["kanıta dayalı risk listesi"],
|
||||
"next_actions": [
|
||||
{ "owner": "rol", "task": "yapılacak iş", "priority": "P0 | P1 | P2" }
|
||||
],
|
||||
"confidence": "low | medium | high"
|
||||
}`}
|
||||
</CodePanel>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Ajanlarda prompt = yetki ve durma kuralları</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={Bot} title="Ne zaman araç?" accent="text-sky-500">
|
||||
Bilgi eksikse arama yap; tahminle doldurma.
|
||||
</Card>
|
||||
<Card icon={ShieldCheck} title="Ne zaman sormalı?" accent="text-emerald-500">
|
||||
Kapsam veya risk davranışı etkiliyorsa kullanıcıya dön.
|
||||
</Card>
|
||||
<Card icon={TimerReset} title="Ne zaman durmalı?" accent="text-purple-500">
|
||||
Başarı kriteri tamamlandıysa yeni iş icat etme.
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-[1fr_1.1fr]">
|
||||
<div>
|
||||
<SlideTitle>Uzun işlerde context akışı tasarla</SlideTitle>
|
||||
<SlideContent>
|
||||
Tek dev prompt yerine, işi aşamalara böl: keşif, plan, uygulama, doğrulama, özet.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
{[
|
||||
{ icon: Network, title: "Keşif", text: "Dosya, kaynak ve kısıtları topla." },
|
||||
{ icon: Route, title: "Plan", text: "Kararları ve bağımlılıkları görünür yap." },
|
||||
{ icon: Blocks, title: "Uygulama", text: "Sadece gerekli bağlamı sonraki adıma taşı." },
|
||||
{ icon: ClipboardCheck, title: "Doğrulama", text: "Çıktıyı ölçüt ve kaynakla kontrol et." },
|
||||
].map(({ icon: Icon, title, text }) => (
|
||||
<div key={title} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 text-primary">
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{title}</h3>
|
||||
<p className="text-muted-foreground">{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>En sık görülen hata modları</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
<FlowStep icon={Target} title="Belirsiz hedef" text="Başarı tanımı yoksa model kendi hedefini seçer." />
|
||||
<FlowStep icon={Clock3} title="Eski context" text="Önceki kararlar yeni talimatla çakışır." />
|
||||
<FlowStep icon={Puzzle} title="Görünmez varsayım" text="Sizde açık olan bilgi modelde yoktur." />
|
||||
<FlowStep icon={FileText} title="Format eksikliği" text="Doğru bilgi yanlış biçimde gelirse kullanılamaz." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Promptları ölç: tek iyi cevap yetmez</SlideTitle>
|
||||
<SlideContent>
|
||||
Küçük bir test seti, promptun gerçek hayatta dayanıklı olup olmadığını gösterir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"3 normal senaryo",
|
||||
"2 sınır durum",
|
||||
"1 kasıtlı belirsiz istek",
|
||||
"Beklenen format kontrolü",
|
||||
"İyi cevap nasıl görünür? kısa kontrol listesi",
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[1.05fr_0.95fr]">
|
||||
<div>
|
||||
<SlideTitle>prompts.chat: promptları paylaşılabilir hale getirmek</SlideTitle>
|
||||
<SlideContent>
|
||||
Promptlar kaybolan sohbet parçaları olmamalı. Keşfedilebilir, fork edilebilir, iyileştirilebilir ve tekrar kullanılabilir olmalı.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
<Card icon={Sparkles} title="Keşif">
|
||||
İyi örneği arayıp bulmak, sıfırdan başlamaktan hızlıdır.
|
||||
</Card>
|
||||
<Card icon={GitBranch} title="Değişiklik">
|
||||
Promptlar review ve geri bildirimle olgunlaşır.
|
||||
</Card>
|
||||
<Card icon={PackageCheck} title="Yeniden kullanım">
|
||||
Aynı kaliteyi farklı ekip ve iş akışlarına taşırsınız.
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Promptlar kod gibi yaşamalı</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-4">
|
||||
<FlowStep icon={FileText} title="Sahiplik" text="Kim güncelliyor?" />
|
||||
<FlowStep icon={GitBranch} title="Sürüm" text="Ne değişti?" />
|
||||
<FlowStep icon={ClipboardCheck} title="Review" text="Kalite barı ne?" />
|
||||
<FlowStep icon={DatabaseZap} title="Örnek" text="Hangi veriyle çalıştı?" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.95fr_1.05fr]">
|
||||
<div>
|
||||
<SlideTitle>Kapanış kontrol listesi</SlideTitle>
|
||||
<SlideContent>
|
||||
Bir sonraki promptunuzu göndermeden önce bu beş soruyu sorun.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"Modelin rolü ve hedefi net mi?",
|
||||
"Gerekli context seçildi ve sıralandı mı?",
|
||||
"Kısıtlar ve durma kuralları yazıldı mı?",
|
||||
"Çıktı formatı sözleşmeye bağlandı mı?",
|
||||
"En az birkaç gerçek senaryoyla denendi mi?",
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
|
||||
<div className="mb-8 flex h-24 w-24 items-center justify-center rounded-full bg-primary/10 text-primary">
|
||||
<Sparkles className="h-12 w-12" />
|
||||
</div>
|
||||
<SlideTitle>Teşekkürler</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-4xl">
|
||||
İyi prompt modele <SlideHighlight>ne yapacağını</SlideHighlight> söyler.
|
||||
<br />
|
||||
İyi context yönetimi <SlideHighlight>neye dayanarak yapacağını</SlideHighlight> belirler.
|
||||
</SlideContent>
|
||||
<div className="mt-10 flex flex-wrap justify-center gap-3">
|
||||
<Pill>prompts.chat</Pill>
|
||||
<Pill>Q&A</Pill>
|
||||
</div>
|
||||
</div>
|
||||
</SlideDeck>
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect, useCallback, ReactNode } from "react";
|
||||
import { ChevronLeft, ChevronRight, X } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Children, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ChevronLeft, ChevronRight, Maximize, Minimize, StickyNote, X } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface SlideDeckProps {
|
||||
children: ReactNode[];
|
||||
children: ReactNode;
|
||||
notes?: string[];
|
||||
}
|
||||
|
||||
export function SlideDeck({ children }: SlideDeckProps) {
|
||||
export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
const slides = useMemo(() => Children.toArray(children), [children]);
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
const totalSlides = children.length;
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
const [showNotes, setShowNotes] = useState(false);
|
||||
const swipeStartX = useRef<number | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const totalSlides = slides.length;
|
||||
const currentNote = notes?.[currentSlide];
|
||||
|
||||
const nextSlide = useCallback(() => {
|
||||
setCurrentSlide((prev) => Math.min(prev + 1, totalSlides - 1));
|
||||
@@ -22,89 +29,156 @@ export function SlideDeck({ children }: SlideDeckProps) {
|
||||
setCurrentSlide((prev) => Math.max(prev - 1, 0));
|
||||
}, []);
|
||||
|
||||
const toggleFullscreen = useCallback(() => {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
return;
|
||||
}
|
||||
|
||||
containerRef.current?.requestFullscreen();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "ArrowRight" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
const handleFullscreenChange = () => {
|
||||
setIsFullscreen(Boolean(document.fullscreenElement));
|
||||
};
|
||||
|
||||
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
||||
return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === "ArrowRight" || event.key === " " || event.key === "PageDown") {
|
||||
event.preventDefault();
|
||||
nextSlide();
|
||||
} else if (e.key === "ArrowLeft") {
|
||||
e.preventDefault();
|
||||
} else if (event.key === "ArrowLeft" || event.key === "PageUp") {
|
||||
event.preventDefault();
|
||||
prevSlide();
|
||||
} else if (event.key === "Home") {
|
||||
event.preventDefault();
|
||||
setCurrentSlide(0);
|
||||
} else if (event.key === "End") {
|
||||
event.preventDefault();
|
||||
setCurrentSlide(totalSlides - 1);
|
||||
} else if (event.key === "f" || event.key === "F") {
|
||||
event.preventDefault();
|
||||
toggleFullscreen();
|
||||
} else if (event.key === "n" || event.key === "N") {
|
||||
event.preventDefault();
|
||||
setShowNotes((value) => !value);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [nextSlide, prevSlide]);
|
||||
}, [nextSlide, prevSlide, toggleFullscreen, totalSlides]);
|
||||
|
||||
return (
|
||||
<div className="relative h-screen w-screen overflow-hidden bg-background text-foreground flex flex-col">
|
||||
{/* Top Navigation */}
|
||||
<div className="absolute top-4 right-4 z-50 flex items-center gap-4">
|
||||
<div className="text-sm font-medium text-muted-foreground bg-background/50 backdrop-blur-sm px-3 py-1 rounded-full">
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="relative flex h-[100dvh] w-screen flex-col overflow-hidden bg-background text-foreground"
|
||||
onPointerDown={(event) => {
|
||||
swipeStartX.current = event.clientX;
|
||||
}}
|
||||
onPointerUp={(event) => {
|
||||
if (swipeStartX.current === null) return;
|
||||
|
||||
const deltaX = event.clientX - swipeStartX.current;
|
||||
swipeStartX.current = null;
|
||||
|
||||
if (Math.abs(deltaX) < 64) return;
|
||||
if (deltaX < 0) nextSlide();
|
||||
else prevSlide();
|
||||
}}
|
||||
>
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,var(--primary),transparent_34%),radial-gradient(circle_at_bottom_right,var(--primary),transparent_28%)] opacity-10" />
|
||||
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,var(--border)_1px,transparent_1px),linear-gradient(to_bottom,var(--border)_1px,transparent_1px)] bg-[size:72px_72px] opacity-25" />
|
||||
|
||||
<div className="absolute right-4 top-4 z-50 flex items-center gap-3">
|
||||
<div className="rounded-full border border-border/70 bg-background/70 px-3 py-1 text-sm font-medium text-muted-foreground shadow-sm backdrop-blur">
|
||||
{currentSlide + 1} / {totalSlides}
|
||||
</div>
|
||||
{notes && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setShowNotes((value) => !value)}
|
||||
className={cn(
|
||||
"rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90",
|
||||
showNotes && "text-primary"
|
||||
)}
|
||||
title="Konuşmacı notları (N)"
|
||||
>
|
||||
<StickyNote className="h-5 w-5" />
|
||||
<span className="sr-only">{showNotes ? "Notları gizle" : "Notları göster"}</span>
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={toggleFullscreen}
|
||||
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
title="Tam ekran (F)"
|
||||
>
|
||||
{isFullscreen ? <Minimize className="h-5 w-5" /> : <Maximize className="h-5 w-5" />}
|
||||
<span className="sr-only">{isFullscreen ? "Tam ekrandan çık" : "Tam ekran yap"}</span>
|
||||
</Button>
|
||||
<Link href="/">
|
||||
<Button variant="ghost" size="icon" className="rounded-full bg-background/50 backdrop-blur-sm hover:bg-background/80">
|
||||
<X className="w-5 h-5" />
|
||||
<span className="sr-only">Close</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
<span className="sr-only">Kapat</span>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Slides Container */}
|
||||
<div className="flex-1 relative">
|
||||
{children.map((child, index) => {
|
||||
// Calculate the relative position (-1 is left, 0 is active, 1 is right)
|
||||
<div className="relative flex-1">
|
||||
{slides.map((child, index) => {
|
||||
const offset = index - currentSlide;
|
||||
|
||||
let translateX = "translate-x-full";
|
||||
if (offset === 0) translateX = "translate-x-0";
|
||||
else if (offset < 0) translateX = "-translate-x-full";
|
||||
const translateX = offset === 0 ? "translate-x-0" : offset < 0 ? "-translate-x-full" : "translate-x-full";
|
||||
|
||||
return (
|
||||
<div
|
||||
<section
|
||||
key={index}
|
||||
className={cn(
|
||||
"absolute inset-0 transition-all duration-500 ease-in-out flex items-center justify-center p-8 md:p-16 lg:p-24",
|
||||
"absolute inset-0 flex items-center justify-center p-6 transition-all duration-500 ease-out sm:p-10 md:p-14 lg:p-20",
|
||||
translateX,
|
||||
offset === 0 ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"
|
||||
offset === 0 ? "opacity-100 scale-100" : "pointer-events-none opacity-0 scale-95"
|
||||
)}
|
||||
aria-hidden={offset !== 0}
|
||||
>
|
||||
<div className="w-full max-w-5xl mx-auto">
|
||||
{child}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto w-full max-w-6xl">{child}</div>
|
||||
</section>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Bottom Navigation */}
|
||||
<div className="absolute bottom-8 left-0 right-0 z-50 flex justify-center items-center gap-8">
|
||||
<div className="absolute inset-x-0 bottom-8 z-50 flex items-center justify-center gap-5 px-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={prevSlide}
|
||||
disabled={currentSlide === 0}
|
||||
className="rounded-full w-12 h-12 bg-background/50 backdrop-blur-sm hover:bg-background/80"
|
||||
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<ChevronLeft className="w-6 h-6" />
|
||||
<span className="sr-only">Previous</span>
|
||||
<ChevronLeft className="h-5 w-5" />
|
||||
<span className="sr-only">Önceki</span>
|
||||
</Button>
|
||||
|
||||
{/* Progress Dots */}
|
||||
<div className="flex gap-2">
|
||||
{Array.from({ length: totalSlides }).map((_, i) => (
|
||||
|
||||
<div className="flex max-w-[58vw] items-center gap-1.5 overflow-hidden rounded-full border border-border/60 bg-background/60 px-3 py-2 shadow-sm backdrop-blur">
|
||||
{slides.map((_, index) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => setCurrentSlide(i)}
|
||||
key={index}
|
||||
onClick={() => setCurrentSlide(index)}
|
||||
className={cn(
|
||||
"w-2.5 h-2.5 rounded-full transition-all duration-300",
|
||||
i === currentSlide
|
||||
? "bg-primary w-8"
|
||||
: "bg-muted-foreground/30 hover:bg-muted-foreground/50"
|
||||
"h-2.5 rounded-full transition-all duration-300",
|
||||
index === currentSlide ? "w-8 bg-primary" : "w-2.5 bg-muted-foreground/30 hover:bg-muted-foreground/50"
|
||||
)}
|
||||
aria-label={`Go to slide ${i + 1}`}
|
||||
aria-label={`${index + 1}. slayta git`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -114,16 +188,22 @@ export function SlideDeck({ children }: SlideDeckProps) {
|
||||
size="icon"
|
||||
onClick={nextSlide}
|
||||
disabled={currentSlide === totalSlides - 1}
|
||||
className="rounded-full w-12 h-12 bg-background/50 backdrop-blur-sm hover:bg-background/80"
|
||||
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<ChevronRight className="w-6 h-6" />
|
||||
<span className="sr-only">Next</span>
|
||||
<ChevronRight className="h-5 w-5" />
|
||||
<span className="sr-only">Sonraki</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Progress Bar */}
|
||||
<div className="absolute bottom-0 left-0 right-0 h-1.5 bg-muted">
|
||||
<div
|
||||
{showNotes && (
|
||||
<div className="absolute inset-x-4 bottom-24 z-50 mx-auto max-w-3xl rounded-2xl border border-border bg-background/95 p-4 shadow-2xl backdrop-blur">
|
||||
<div className="mb-1 text-xs font-bold uppercase tracking-[0.24em] text-primary">Konuşmacı notu</div>
|
||||
<p className="text-sm leading-relaxed text-foreground">{currentNote || "Bu slayt için not yok."}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="absolute inset-x-0 bottom-0 h-1.5 bg-muted">
|
||||
<div
|
||||
className="h-full bg-primary transition-all duration-500 ease-out"
|
||||
style={{ width: `${((currentSlide + 1) / totalSlides) * 100}%` }}
|
||||
/>
|
||||
@@ -132,10 +212,14 @@ export function SlideDeck({ children }: SlideDeckProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// Helper components for slide content
|
||||
export function SlideTitle({ children, className }: { children: ReactNode; className?: string }) {
|
||||
return (
|
||||
<h1 className={cn("text-4xl md:text-6xl lg:text-7xl font-bold tracking-tight mb-8 md:mb-12 text-balance leading-tight bg-clip-text text-transparent bg-gradient-to-br from-foreground to-foreground/70", className)}>
|
||||
<h1
|
||||
className={cn(
|
||||
"mb-7 text-balance bg-gradient-to-br from-foreground to-foreground/65 bg-clip-text text-4xl font-bold leading-tight tracking-tight text-transparent md:text-6xl lg:text-7xl",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
@@ -143,16 +227,12 @@ export function SlideTitle({ children, className }: { children: ReactNode; class
|
||||
|
||||
export function SlideContent({ children, className }: { children: ReactNode; className?: string }) {
|
||||
return (
|
||||
<div className={cn("text-xl md:text-3xl lg:text-4xl leading-relaxed text-muted-foreground font-medium", className)}>
|
||||
<div className={cn("text-balance text-xl font-medium leading-relaxed text-muted-foreground md:text-3xl", className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SlideHighlight({ children, className }: { children: ReactNode; className?: string }) {
|
||||
return (
|
||||
<span className={cn("text-primary font-semibold", className)}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
return <span className={cn("font-semibold text-primary", className)}>{children}</span>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user