Kurs ve Paket Vitrin Sayfaları
Kurs detay (course.$id) ve paket vitrin (bundle.$slug) sayfalarının ortak düzeni, PPP fiyatları, affiliate ref, checkout ve kurs sayfasındaki paket upsell bileşenleri.
Öğrenci tarafında tek kurs ve kurs paketi (bundle) satın almadan önce görülen pazarlama / vitrin sayfaları aynı görsel dilde tasarlanmıştır: genişlik max-w-[1340px], koyu gradient hero, iki sütunlu ana grid ve sağda yapışkan fiyat kartı (lg:absolute lg:-top-[360px]). Bu sayfa course.$id.tsx ve bundle.$slug.tsx dosyalarındaki loader mantığı, UI bileşenleri ve GraphQL uçlarını özetler.
Ortak düzen (layout)
Section titled “Ortak düzen (layout)”| Öğe | Açıklama |
|---|---|
| Hero | bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900, üstte başlık / alt başlık / meta (breadcrumb veya kategori). |
| Ana içerik | grid — sol lg:col-span-2 (içerik listesi, müfredat, açıklama vb.), sağ lg:col-span-1 (satın alma kartı). |
| Sağ kart | lg:relative sütun içinde kart lg:absolute lg:-top-[360px] ile hero alanına görsel olarak “binen” konumda; üstte promo video veya kapak (aspect-video), altında fiyat ve aksiyonlar. |
| Mobil | lg: önekli mutlak konum kalkar; kart akışta sol içeriğin altında veya üstünde (DOM sırasına göre) görünür. |
Paket vitrin (bundle.$slug.tsx): Promo video yalnızca sağ kartın üstünde gösterilir (hero üzerinde tam genişlik medya bandı yok). Öncelik: promoVideoId + BUNNY_LIBRARY_ID → Bunny iframe; aksi halde thumbnailUrl; ikisi de yoksa koyu placeholder.
Kurs detay (course.$id.tsx): Promo video veya kapak yine sağ sütun kartının üstünde; hero’da yalnızca metin ve rozetler.
Kurs detay sayfası — app/routes/course.$id.tsx
Section titled “Kurs detay sayfası — app/routes/course.$id.tsx”Loader özeti
Section titled “Loader özeti”- Kurs:
getCourseById(slug veya UUID). - Müfredat:
getCourseCurriculum; önizleme dersleri için imzalı URL (generateSignedVideoUrl) —BUNNY_VIDEO_SECURITY_KEYgerekir. - Paket ilişkisi:
getBundleByCourseId— kurs bir pakete dahilsebundle+bundleRegionalPrice(PPP) hesaplanır. - Bölgesel fiyat:
getRegionalPrice(db, course.priceTierId, country)→regionalPrice. - Affiliate: URL
?ref=...varsaSet-Cookie: coursio_affiliate=...(30 gün, HttpOnly, SameSite=Lax). Detay: Affiliate Programı. - Dil: Loader’a
langeklenir;metave JSON-LD için kullanılır.
Satın alma ve upsell
Section titled “Satın alma ve upsell”- Satın alma:
createStripeCheckoutSession(GraphQL), sepete ekleme, abonelikle kayıt, kayıtlı kart ile checkout yönlendirmesi. - E-posta doğrulama: Satın alma öncesi
emailVerifiedkontrolü; doğrulama e-postası aksiyonu. - FrequentlyBoughtTogether: Kursun dahil olduğu paket için fiyat (PPP’li
bundleRegionalPriceveya ham fiyat), “Paketi sepete ekle” →addBundleToCart. - BundlePromoBox: Paket başlığı, özet fiyat, “Paketi görüntüle” →
/:lang/bundle/:slug.
SEO ve zengin sonuçlar
Section titled “SEO ve zengin sonuçlar”metaexport: Title, description, Open Graph, Twitter Card, canonical, hreflang alternates.- JSON-LD:
Course,Offer, isteğe bağlıAggregateRating. Detay: SEO ve Rich Snippets.
Paket vitrin sayfası — app/routes/bundle.$slug.tsx
Section titled “Paket vitrin sayfası — app/routes/bundle.$slug.tsx”Loader özeti
Section titled “Loader özeti”- Paket:
getBundleBySlug(db, slug); yoksa 404. - Kurs satırı fiyatları: Her kurs için
priceTierIdvarsagetRegionalPriceiledisplayPrice/displayCurrencyzenginleştirilir. - Paket PPP:
getBundleRegionalPrice(db, bundle.id, country)→originalAmount,discountedAmount,currency,discountPercentageuyumu; hata durumunda sessizce düşülür, kurs toplamları kullanılır. - İndirim penceresi:
isBundleDiscountPeriodActive({ discountValidFrom, discountValidUntil })— aktif değilse satın al butonu devre dışı ve uyarı metni gösterilir (~/lib/bundle-discount-window). - Affiliate:
?ref=ile gelindiğindecoursio_affiliatecookie (kurs sayfasıyla aynı mantık).
Checkout
Section titled “Checkout”- Mutation:
createBundleCheckoutSession(bundleId: $bundleId)— dönüş: Stripe Checkout URL; giriş yoksa GraphQL hatası → login yönlendirmesi + toast. - İstemci:
fetch("/api/graphql", { credentials: "include" })— oturum çerezi için.
SEO notu
Section titled “SEO notu”Bu route’ta ayrı bir meta() export’u yok; sayfa başlığı ve sosyal önizleme büyük ölçüde global layout (root.tsx, $lang.tsx) ve varsayılanlar ile sınırlı kalabilir. İleride kurs sayfasıyla aynı seviyede OG/JSON-LD eklenmesi önerilir. Mevcut durum: SEO ve Rich Snippets sayfasındaki global kurallar geçerlidir.
Eğitmen tarafı — paket oluşturma ve medya
Section titled “Eğitmen tarafı — paket oluşturma ve medya”| Route | Açıklama |
|---|---|
/:lang/instructor/bundles | Paket listesi; yeni paket oluşturma (modal). |
/:lang/instructor/bundles/:id/manage | Başlık, açıklama, fiyat, kurs seçimi, kapak görseli ve promo video yükleme (API route’ları ile Bunny / depolama). |
Vitrinde görünen thumbnailUrl ve promoVideoId bu yönetim ekranından beslenir.
GraphQL (özet)
Section titled “GraphQL (özet)”| İşlem | Mutation / kullanım |
|---|---|
| Paket checkout URL | createBundleCheckoutSession(bundleId, affiliateCode?) |
| Sepete paket | addBundleToCart(bundleId) |
Şema: app/graphql/schema.ts. Tam resolver listesi: API Referansı ve GraphQL.
Bölgesel fiyatlandırma (PPP)
Section titled “Bölgesel fiyatlandırma (PPP)”Kurs ve paket fiyatları için getRegionalPrice ve paket toplamı için getBundleRegionalPrice kullanımı Bölgesel Fiyatlandırma (PPP) sayfasında anlatılır.
İlgili dosyalar
Section titled “İlgili dosyalar”app/routes/course.$id.tsx— Kurs vitrin; FrequentlyBoughtTogether, BundlePromoBox, regional + bundle PPP.app/routes/bundle.$slug.tsx— Paket vitrin; promo kart içinde, checkout.app/lib/pricing-engine.ts—getBundleRegionalPrice,getRegionalPrice.app/lib/bundle-discount-window.ts— Paket indirim tarih aralığı kontrolü.app/routes/instructor.bundles._index.tsx,app/routes/instructor.bundles.$id.manage.tsx— Eğitmen paket yönetimi.
| Konu | Kurs detay | Paket vitrin |
|---|---|---|
| Dosya | course.$id.tsx | bundle.$slug.tsx |
| Promo medya | Sağ kart üstü | Sağ kart üstü (hero’da tam genişlik yok) |
| PPP | regionalPrice + isteğe bağlı bundleRegionalPrice | bundleRegionalPrice + kurs satırı displayPrice |
| SEO meta + JSON-LD | Var (meta + script) | Şu an yok; global layout |
| Affiliate cookie | Loader ?ref= | Aynı |
İlgili: Öğrenme Deneyimi (Student Experience) (öğrenme player’ı), Checkout & Webhooks, Route Haritası.