@raxonltd/raxon-core
v1.1.8
Published
Raxon e-ticaret altyapısı için React/Next.js SDK — bootstrap, auth, sepet, ödeme hook'ları ve hazır checkout bileşeni.
Maintainers
Readme
@raxonltd/raxon-core
Raxon e-ticaret altyapısı için React / Next.js SDK'sı.
Mağaza bootstrap verisi, kimlik doğrulama, sepet yönetimi, ödeme akışı, ürün listeleme ve analitik olaylarını tek bir pakette sunar. TanStack Query tabanlı hook'lar ve hazır UI bileşenleriyle hızlı entegrasyon sağlar.
İçindekiler
- Özellikler
- Gereksinimler
- Kurulum
- Hızlı Başlangıç
- Paket Yapısı
- RaxonProvider
- useRaxon — Global Context
- Hook'lar
- Hazır Görünümler
- Analitik
- Kimlik Doğrulama
- Sepet Yönetimi
- TypeScript Arayüzleri
- Ortam Değişkenleri
- Next.js Entegrasyonu
- Geliştirme
Özellikler
| Alan | Açıklama | |------|----------| | Bootstrap | Kategori, koleksiyon, kampanya, marka, ödeme/teslimat yöntemleri tek istekle yüklenir | | Kimlik doğrulama | E-posta, misafir ve sosyal giriş; kayıt, şifre sıfırlama | | Sepet | Optimistic güncelleme, debounce'lu miktar değişimi, çoklu ödeme sağlayıcısı | | Ürünler | Listeleme, arama, detay, ilişkili ürünler | | Ödeme | PayTR, Stripe, GarantiPay, kapıda ödeme, havale | | Hazır checkout | Adres, fatura, promo kod ve ödeme adımlarını içeren tam sayfa bileşeni | | Analitik | Ürün görüntüleme/tıklama ve e-posta kampanya takibi | | TypeScript | Tam tip desteği |
Gereksinimler
- React
19.x - Next.js
16.x(App Router —viewmodülü için) - Node.js
20+(geliştirme ortamı)
Paket aşağıdaki bağımlılıkları kendi içinde getirir; ek kurulum gerekmez:
@tanstack/react-query, axios, react-hook-form, zod, rizzui, lucide-react, react-hot-toast
Kurulum
npm install @raxonltd/raxon-coreHızlı Başlangıç
1. Provider'ı sarın
// app/layout.tsx
'use client';
import { RaxonProvider } from '@raxonltd/raxon-core';
import { Toaster } from 'react-hot-toast';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="tr">
<body>
<RaxonProvider
apiKey={process.env.NEXT_PUBLIC_API_KEY!}
apiUrl={process.env.NEXT_PUBLIC_API_URL!}
productPathPrefix="/urunler"
analyticAutoTrack
>
{children}
</RaxonProvider>
<Toaster position="top-right" />
</body>
</html>
);
}2. Bootstrap verisini kullanın
'use client';
import { useRaxon } from '@raxonltd/raxon-core';
export function Header() {
const { category, brand, isLoading, cartTotal, addToCart } = useRaxon();
if (isLoading) return <div>Yükleniyor...</div>;
return (
<header>
<nav>{category.map((c) => <a key={c.id} href={`/kategori/${c.slug}`}>{c.name}</a>)}</nav>
<span>Sepet: {cartTotal} ₺</span>
</header>
);
}3. Hook ile veri çekin
'use client';
import { useProduct } from '@raxonltd/raxon-core/hook';
export function ProductList({ categoryId }: { categoryId: string }) {
const { fetch } = useProduct();
const { data, isLoading } = fetch({ categoryId, page: 1, amount: 24 });
if (isLoading) return <p>Yükleniyor...</p>;
return (
<ul>
{data?.data.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}Paket Yapısı
Paket dört giriş noktası sunar:
| Import yolu | İçerik |
|-------------|--------|
| @raxonltd/raxon-core | RaxonProvider, useRaxon, nexineAxios, analitik |
| @raxonltd/raxon-core/hook | Tüm veri hook'ları |
| @raxonltd/raxon-core/view | Hazır sayfa bileşenleri |
| @raxonltd/raxon-core/interface/* | TypeScript arayüzleri |
// Ana modül
import {
RaxonProvider,
useRaxon,
nexineAxios,
AnalyticEventProvider,
useAnalyticEvent,
} from '@raxonltd/raxon-core';
// Hook'lar
import { useProduct, useCart, useAuth } from '@raxonltd/raxon-core/hook';
// Görünümler
import { CheckoutView } from '@raxonltd/raxon-core/view';
// Tipler
import type { Product, Brand, Order } from '@raxonltd/raxon-core/interface/prisma.interface';
import type { IData } from '@raxonltd/raxon-core/interface/nexine.interface';RaxonProvider
Uygulamanın kökünde bir kez sarılmalıdır. Şunları yapılandırır:
- Axios istemcisi (
nexineAxios) —baseURLvex-api-keyheader - TanStack Query
QueryClient - Bootstrap verisi (
/customer/bootstrap) - Kimlik doğrulama durumu
- Sepet state'i (optimistic)
- Giriş ve bülten modalları
- Analitik sağlayıcı
Props
| Prop | Tip | Zorunlu | Açıklama |
|------|-----|---------|----------|
| apiKey | string | Evet | Mağaza API anahtarı (x-api-key) |
| apiUrl | string | Evet | Backend temel URL'i |
| productPathPrefix | string | Hayır | Ürün URL öneki (analitik için, varsayılan: /urunler) |
| analyticAutoTrack | boolean | Hayır | Otomatik ürün görüntüleme takibi |
<RaxonProvider
apiKey="your-api-key"
apiUrl="https://api.example.com"
productPathPrefix="/urunler"
analyticAutoTrack
>
{children}
</RaxonProvider>Mimari
flowchart TB
subgraph Provider["RaxonProvider"]
QC[QueryClientProvider]
subgraph Inner["RaxonProviderInner"]
Bootstrap["/customer/bootstrap"]
Security[SecurityContext]
Cart[CartState]
Analytics[AnalyticEventProvider]
end
end
QC --> Inner
Bootstrap --> useRaxon
Security --> useRaxon
Cart --> useRaxon
Analytics --> useAnalyticEventuseRaxon — Global Context
RaxonProvider altında useRaxon() ile erişilen merkezi state.
Bootstrap verileri
| Alan | Tip | Açıklama |
|------|-----|----------|
| category | Category[] | Hiyerarşik kategori ağacı |
| flatCategory | Category[] | Düzleştirilmiş kategori listesi |
| collection | Collection[] | Tüm koleksiyonlar |
| banner | Collection[] | banner etiketli koleksiyonlar |
| subHeroCollection | Collection[] | Alt hero koleksiyonları |
| brand | Brand[] | Markalar |
| product | Product[] | Öne çıkan ürünler |
| bestSeller | Product[] | Çok satanlar |
| campaign | Campaign[] | Kampanyalar |
| basketCampaign | Campaign[] | Sepet kampanyaları (koleksiyon hariç) |
| paymentMethod | PaymentMethod[] | Ödeme yöntemleri |
| deliveryMethod | DeliveryMethod[] | Teslimat yöntemleri |
| defaultDeliveryMethod | DeliveryMethod \| null | Varsayılan teslimat |
| bankAccount | BankAccount[] | Havale hesapları |
| article | Article[] | Blog / içerik |
| faq | Faq[] | SSS |
| review | Review[] | Yorumlar |
| feed | Feed[] | Feed verileri |
| material | Material[] | Materyaller |
| holiday | Holiday[] | Tatil günleri |
| dynamicData | DynamicData[] | Dinamik CMS verileri |
| branch | Branch \| null | Şube bilgisi |
| isLoading | boolean | Bootstrap yükleniyor mu |
Kimlik doğrulama
| Alan | Tip | Açıklama |
|------|-----|----------|
| profile | User \| null \| undefined | Oturum açmış kullanıcı |
| authLoading | boolean | Auth kontrolü devam ediyor |
| isAuthenticated | boolean | Giriş yapılmış mı |
| isGuest | boolean | Misafir oturumu mu |
Sepet (CartState)
| Alan / Metod | Açıklama |
|--------------|----------|
| cart | Güncel sepet özeti (BasketSummaryInterface) |
| cartLoading | Sepet yükleniyor |
| cartTotal | Toplam tutar |
| addToCart(productId, quantity, variantId?) | Ürün ekle (optimistic) |
| updateQuantity(itemId, quantity) | Miktar güncelle |
| changeQuantity(itemId, delta) | Miktar artır/azalt |
| removeItem(itemId) | Kalemi kaldır |
| isProductAdding(productId, variantId?) | Ekleme işlemi devam ediyor mu |
| promoCode / setPromoCode | Aktif promo kodu |
Modal referansları
const { modalAuthRef, modalNewsletterVariantProductRef } = useRaxon();
// Giriş modalını aç
modalAuthRef.current?.open();Hook'lar
Tüm hook'lar @raxonltd/raxon-core/hook üzerinden import edilir. Her hook bir nesne döndürür; metodlar useQuery veya useMutation sonucu verir.
Kullanım kalıbı: Hook'u bileşen gövdesinde çağırın, dönen metodu da aynı gövdede çağırın (React kuralları).
const { fetch } = useProduct();
const query = fetch({ categoryId: 'abc', page: 1 }); // useQuery sonucuuseAuth
Kimlik doğrulama işlemleri.
| Metod | Tip | Endpoint | Açıklama |
|-------|-----|----------|----------|
| profile({ isEnabled }) | Query | GET /customer/profile | Profil bilgisi |
| token() | Mutation | GET /auth/token | Token al |
| loginEmail() | Mutation | POST /auth/login/email | E-posta ile giriş |
| loginGuest() | Mutation | POST /auth/login/guest | Misafir girişi |
| loginSocial() | Mutation | GET /auth/login/social | Sosyal giriş URL'i |
| register() | Mutation | POST /auth/register | Kayıt |
| codeSend() | Mutation | POST /auth/code-send | Şifre sıfırlama kodu |
| verifyCode() | Mutation | POST /auth/code-verify | Kod doğrulama |
| resetPassword() | Mutation | POST /auth/reset-password | Şifre sıfırlama |
| logout() | Fonksiyon | — | Token temizle ve yenile |
Olaylar: LOGIN_SUCCESS_EVENT, LOGOUT_EVENT — window üzerinde dinlenebilir.
const { loginEmail, logout } = useAuth();
const login = loginEmail();
login.mutate({ email: '[email protected]', password: '***' });useProduct
Ürün listeleme, arama ve detay.
| Metod | Açıklama |
|-------|----------|
| fetch(params) | Filtrelenmiş ürün listesi |
| searchData(search) | Canlı arama (min. 3 karakter) |
| detail(slug) | Ürün detayı |
| related(productId) | İlişkili ürünler |
fetch parametreleri (öne çıkanlar):
{
categoryId?: string;
subCategoryId?: string;
brandId?: string[];
search?: string;
page?: number;
amount?: number; // varsayılan sayfa boyutu: 24
sortBy?: string;
collectionId?: string;
attributeOptionId?: string[];
minPrice?: number;
maxPrice?: number;
isFavorite?: boolean;
enabled?: boolean;
}useCart
Sepet CRUD ve ödeme mutasyonları.
| Metod | Endpoint | Açıklama |
|-------|----------|----------|
| fetch({ isEnabled, promoCodeId, campaignId, deliveryMethodId }) | GET /customer/basket/me | Sepet özeti |
| insert() | POST /customer/basket/me/item | Ürün ekle |
| updateItem() | PUT /customer/basket/me/item | Miktar güncelle |
| remove() | DELETE /customer/basket/me/item/:id | Kalem sil |
| bulkInsert() | PATCH /customer/basket/me/item | Toplu güncelleme |
| update() | PUT /customer/basket | Adres, ödeme, promo kod |
| pay() | POST /customer/basket/me/pay | Genel ödeme |
| generatePaymentUrl() | POST /customer/basket/pay/paytr | PayTR |
| generateStripePaymentIntent() | POST /customer/basket/pay/stripe | Stripe |
| generateCashOnDeliveryPayment() | POST /customer/basket/pay/cash-on-delivery | Kapıda ödeme |
| createTransferCode() | POST /customer/payment/bank-transfer | Havale kodu |
Günlük sepet işlemleri için
useRaxon()içindekiaddToCart,changeQuantitygibi metodları tercih edin; bunlar optimistic güncelleme içerir.
useBrand
Marka listesi (sadece okuma).
const { fetch } = useBrand();
const { data } = fetch({ page: 1, amount: 50, enabled: true });
// data: IData<Brand> → { data: Brand[], count: number }useCollection
| Metod | Endpoint |
|-------|----------|
| fetch(params?) | GET /customer/collection |
| detail(id) | GET /customer/collection/:id |
useArticle
| Metod | Endpoint |
|-------|----------|
| fetch(params?) | GET /customer/article |
| detail(id) | GET /customer/article/:id |
useFaq
| Metod | Endpoint |
|-------|----------|
| fetch({ page, amount }) | GET /customer/faq |
useAttribute
| Metod | Endpoint |
|-------|----------|
| fetch({ categoryId?, productId?, enabled? }) | GET /customer/attribute |
useAddress
| Metod | Endpoint |
|-------|----------|
| fetch() | GET /customer/address |
| detail(id) | GET /customer/address/:id |
| create() | POST /customer/address |
| update() | PUT /customer/address |
| delete() | DELETE /customer/address/:id |
useAddressAutocomplete
Google Places tabanlı adres arama. Host uygulamada ek route gerekmez; NEXT_PUBLIC_GOOGLE_MAPS_API_KEY yeterlidir.
const { query, setQuery, results, selectPlace, isSearching } = useAddressAutocomplete();useProfile
| Metod | Endpoint |
|-------|----------|
| fetch({ isEnabled }) | GET /customer/profile |
| update() | PUT /customer/profile |
| verifyPhoneNumber() | POST /customer/profile/verify/phone |
| verifyEmail() | POST /customer/profile/verify/email |
| fetchCompany({ enabled }) | GET /customer/profile/company |
| applyCompany() | POST /customer/profile/company |
| uploadCompanyDocument() | POST /customer/profile/company/document |
useOrder
| Metod | Endpoint |
|-------|----------|
| fetch() | GET /customer/order |
| detail(id) | GET /customer/order/:id |
useInvoice
| Metod | Endpoint |
|-------|----------|
| fetch() | GET /customer/invoice |
| detail(id) | GET /customer/invoice/:id |
| download() | GET /customer/invoice/:id/download |
| downloadByOrder() | GET /customer/invoice/order/:orderId/download |
useFavorite
| Metod | Endpoint |
|-------|----------|
| list(params?, options?) | GET /customer/favorite |
| toggle() | POST /customer/favorite |
useNewsletter
| Metod | Endpoint |
|-------|----------|
| subscribe | POST /customer/newsletter/subscribe |
| subscribeByVariant | POST /customer/newsletter/subscribe/variant |
usePromoCode
| Metod | Endpoint |
|-------|----------|
| fetch({ status? }) | GET /customer/promo-code |
| findByCode() | GET /customer/promo-code/:code |
usePaymentMethod
| Metod | Endpoint |
|-------|----------|
| fetch({ enabled? }) | GET /customer/payment/method |
WEB etiketli yöntemlerle etiketsiz yöntemleri birleştirir.
useDeliveryMethod
| Metod | Endpoint |
|-------|----------|
| fetch({ enabled? }) | GET /customer/delivery/method |
useBankAccount
| Metod | Endpoint |
|-------|----------|
| fetch({ enabled? }) | GET /customer/bank-account |
| createTransferCode() | POST /customer/payment/bank-transfer |
useFormSubmit
| Metod | Endpoint |
|-------|----------|
| create() | POST /customer/form/submit |
Hazır Görünümler
@raxonltd/raxon-core/view modülünden import edilir.
CheckoutView
Tam özellikli ödeme sayfası: iletişim, adres, fatura, teslimat/ödeme yöntemi seçimi, promo kod ve ödeme entegrasyonları.
// app/sepet/odeme/page.tsx
'use client';
import { CheckoutView } from '@raxonltd/raxon-core/view';
export default function OdemePage() {
return <CheckoutView webReturnUrl="/sepet/odeme" />;
}| Prop | Tip | Varsayılan | Açıklama |
|------|-----|------------|----------|
| webReturnUrl | string | /sepet/odeme | Ödeme sonrası dönüş URL'i |
Analitik
RaxonProvider içinde AnalyticEventProvider otomatik etkinleşir.
import { useAnalyticEvent } from '@raxonltd/raxon-core';
function ProductCard({ productId, variantId }: { productId: string; variantId?: string }) {
const { trackProductView, trackProductClick } = useAnalyticEvent();
return (
<div
onMouseEnter={() => trackProductView({ productId, variantId })}
onClick={() => trackProductClick({ productId, variantId })}
>
...
</div>
);
}| Metod | Açıklama |
|-------|----------|
| trackProductView | Ürün görüntüleme (2 sn buffer ile toplu gönderim) |
| trackProductClick | Ürün tıklama |
| trackEmailClicked | E-posta kampanya tıklaması (tcx parametresi) |
analyticAutoTrack={true} ile URL'deki ürün sayfaları otomatik izlenir (productPathPrefix ile yapılandırılır).
Kimlik Doğrulama
Token localStorage içinde koksal-token anahtarıyla saklanır. nexineAxios her istekte Authorization: Bearer <token> header'ını otomatik ekler.
Akış:
loginEmail/loginGuest/loginSocialile giriş- Token localStorage'a yazılır
LOGIN_SUCCESS_EVENTtetiklenir- Profil ve sepet sorguları invalidate edilir
- 401 yanıtında token temizlenir ve toast gösterilir
// Giriş sonrası dinleme
useEffect(() => {
const handler = () => router.refresh();
window.addEventListener('intermarkt-login-success', handler);
return () => window.removeEventListener('intermarkt-login-success', handler);
}, []);Sepet Yönetimi
İki katman vardır:
useRaxon()sepet API'si — UI için optimistic, debounce'lu; günlük kullanımda bunu tercih edinuseCart()hook'u — Düşük seviye; checkout ve özel akışlar için
const { addToCart, cart, cartTotal, isProductAdding } = useRaxon();
<button
onClick={() => addToCart(product.id, 1, variantId)}
disabled={isProductAdding(product.id, variantId)}
>
Sepete Ekle
</button>Optimistic güncelleme: kullanıcı arayüzü anında güncellenir, arka planda API çağrısı yapılır; hata durumunda geri alınır.
TypeScript Arayüzleri
import type { Brand, Product, Order, Cart } from '@raxonltd/raxon-core/interface/prisma.interface';
import type { ProductDetail } from '@raxonltd/raxon-core/interface/product.interface';
import type { BasketSummaryInterface } from '@raxonltd/raxon-core/interface/basket.interface';
import type { IData } from '@raxonltd/raxon-core/interface/nexine.interface';IData<T> — Sayfalanmış liste yanıtı
interface IData<T> {
data: T[];
count: number;
}Ortam Değişkenleri
| Değişken | Açıklama |
|----------|----------|
| NEXT_PUBLIC_API_KEY | API anahtarı (SSR / sunucu tarafı istekler için) |
| NEXT_PUBLIC_API_URL | API temel URL'i |
| NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | Google Places API anahtarı (adres otomatik tamamlama için) |
Client tarafında RaxonProvider bu değerleri window.__RAXON_API_KEY__ ve window.__RAXON_API_URL__ üzerinden de ayarlar.
Next.js Entegrasyonu
'use client' zorunluluğu
RaxonProvider, hook'lar ve view bileşenleri client component gerektirir. Server Component içinde doğrudan kullanmayın.
Toast bildirimleri
nexineAxios başarılı/hatalı mutasyonlarda react-hot-toast kullanır. Layout'a <Toaster /> ekleyin.
Adres otomatik tamamlama
useAddressAutocomplete ve CheckoutView Google Places API'yi doğrudan kullanır. Host uygulamanın .env dosyasına NEXT_PUBLIC_GOOGLE_MAPS_API_KEY eklemeniz yeterlidir.
Özel axios istekleri
import { nexineAxios } from '@raxonltd/raxon-core';
const response = await nexineAxios.get('/customer/custom-endpoint');Geliştirme
git clone https://github.com/raxonltd/raxon-core.git
cd raxon-core
npm install
npm run buildYayınlama
npm version patch # veya minor / major
npm run build
npm publishSorun Giderme
| Sorun | Çözüm |
|-------|-------|
| useRaxon must be used within a RaxonProvider | Bileşeni RaxonProvider ile sarın |
| Sepet boş görünüyor | isAuthenticated kontrol edin; misafir girişi gerekebilir |
| Toast görünmüyor | <Toaster /> ekleyin |
| 401 hataları | Token süresi dolmuş; yeniden giriş yapın |
| Hook kuralları hatası | Hook metodlarını koşullu veya döngü içinde çağırmayın |
