@raxonltd/raxon-core 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +758 -0
- package/dist/core/feature/brand/hook/use.brand.d.ts +10 -0
- package/dist/core/feature/brand/hook/use.brand.d.ts.map +1 -0
- package/dist/core/feature/brand/hook/use.brand.js +21 -0
- package/dist/core/view/view.checkout.js +1 -1
- package/dist/hook.d.ts +1 -0
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -4
package/README.md
ADDED
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# @raxonltd/raxon-core
|
|
2
|
+
|
|
3
|
+
**Raxon e-ticaret altyapısı için React / Next.js SDK'sı.**
|
|
4
|
+
|
|
5
|
+
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](https://tanstack.com/query) tabanlı hook'lar ve hazır UI bileşenleriyle hızlı entegrasyon sağlar.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@raxonltd/raxon-core)
|
|
8
|
+
[](https://github.com/raxonltd/raxon-core/blob/main/LICENSE)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## İçindekiler
|
|
13
|
+
|
|
14
|
+
- [Özellikler](#özellikler)
|
|
15
|
+
- [Gereksinimler](#gereksinimler)
|
|
16
|
+
- [Kurulum](#kurulum)
|
|
17
|
+
- [Hızlı Başlangıç](#hızlı-başlangıç)
|
|
18
|
+
- [Paket Yapısı](#paket-yapısı)
|
|
19
|
+
- [RaxonProvider](#raxonprovider)
|
|
20
|
+
- [useRaxon — Global Context](#useraxon--global-context)
|
|
21
|
+
- [Hook'lar](#hooklar)
|
|
22
|
+
- [Hazır Görünümler](#hazır-görünümler)
|
|
23
|
+
- [Analitik](#analitik)
|
|
24
|
+
- [Kimlik Doğrulama](#kimlik-doğrulama)
|
|
25
|
+
- [Sepet Yönetimi](#sepet-yönetimi)
|
|
26
|
+
- [TypeScript Arayüzleri](#typescript-arayüzleri)
|
|
27
|
+
- [Ortam Değişkenleri](#ortam-değişkenleri)
|
|
28
|
+
- [Next.js Entegrasyonu](#nextjs-entegrasyonu)
|
|
29
|
+
- [Geliştirme](#geliştirme)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Özellikler
|
|
34
|
+
|
|
35
|
+
| Alan | Açıklama |
|
|
36
|
+
|------|----------|
|
|
37
|
+
| **Bootstrap** | Kategori, koleksiyon, kampanya, marka, ödeme/teslimat yöntemleri tek istekle yüklenir |
|
|
38
|
+
| **Kimlik doğrulama** | E-posta, misafir ve sosyal giriş; kayıt, şifre sıfırlama |
|
|
39
|
+
| **Sepet** | Optimistic güncelleme, debounce'lu miktar değişimi, çoklu ödeme sağlayıcısı |
|
|
40
|
+
| **Ürünler** | Listeleme, arama, detay, ilişkili ürünler |
|
|
41
|
+
| **Ödeme** | PayTR, Stripe, GarantiPay, kapıda ödeme, havale |
|
|
42
|
+
| **Hazır checkout** | Adres, fatura, promo kod ve ödeme adımlarını içeren tam sayfa bileşeni |
|
|
43
|
+
| **Analitik** | Ürün görüntüleme/tıklama ve e-posta kampanya takibi |
|
|
44
|
+
| **TypeScript** | Tam tip desteği |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Gereksinimler
|
|
49
|
+
|
|
50
|
+
- **React** `19.x`
|
|
51
|
+
- **Next.js** `16.x` (App Router — `view` modülü için)
|
|
52
|
+
- **Node.js** `20+` (geliştirme ortamı)
|
|
53
|
+
|
|
54
|
+
Paket aşağıdaki bağımlılıkları kendi içinde getirir; ek kurulum gerekmez:
|
|
55
|
+
|
|
56
|
+
`@tanstack/react-query`, `axios`, `react-hook-form`, `zod`, `rizzui`, `lucide-react`, `react-hot-toast`
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Kurulum
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install @raxonltd/raxon-core
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Hızlı Başlangıç
|
|
69
|
+
|
|
70
|
+
### 1. Provider'ı sarın
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
// app/layout.tsx
|
|
74
|
+
'use client';
|
|
75
|
+
|
|
76
|
+
import { RaxonProvider } from '@raxonltd/raxon-core';
|
|
77
|
+
import { Toaster } from 'react-hot-toast';
|
|
78
|
+
|
|
79
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
80
|
+
return (
|
|
81
|
+
<html lang="tr">
|
|
82
|
+
<body>
|
|
83
|
+
<RaxonProvider
|
|
84
|
+
apiKey={process.env.NEXT_PUBLIC_API_KEY!}
|
|
85
|
+
apiUrl={process.env.NEXT_PUBLIC_API_URL!}
|
|
86
|
+
productPathPrefix="/urunler"
|
|
87
|
+
analyticAutoTrack
|
|
88
|
+
>
|
|
89
|
+
{children}
|
|
90
|
+
</RaxonProvider>
|
|
91
|
+
<Toaster position="top-right" />
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 2. Bootstrap verisini kullanın
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
'use client';
|
|
102
|
+
|
|
103
|
+
import { useRaxon } from '@raxonltd/raxon-core';
|
|
104
|
+
|
|
105
|
+
export function Header() {
|
|
106
|
+
const { category, brand, isLoading, cartTotal, addToCart } = useRaxon();
|
|
107
|
+
|
|
108
|
+
if (isLoading) return <div>Yükleniyor...</div>;
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<header>
|
|
112
|
+
<nav>{category.map((c) => <a key={c.id} href={`/kategori/${c.slug}`}>{c.name}</a>)}</nav>
|
|
113
|
+
<span>Sepet: {cartTotal} ₺</span>
|
|
114
|
+
</header>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 3. Hook ile veri çekin
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
'use client';
|
|
123
|
+
|
|
124
|
+
import { useProduct } from '@raxonltd/raxon-core/hook';
|
|
125
|
+
|
|
126
|
+
export function ProductList({ categoryId }: { categoryId: string }) {
|
|
127
|
+
const { fetch } = useProduct();
|
|
128
|
+
const { data, isLoading } = fetch({ categoryId, page: 1, amount: 24 });
|
|
129
|
+
|
|
130
|
+
if (isLoading) return <p>Yükleniyor...</p>;
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<ul>
|
|
134
|
+
{data?.data.map((product) => (
|
|
135
|
+
<li key={product.id}>{product.name}</li>
|
|
136
|
+
))}
|
|
137
|
+
</ul>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Paket Yapısı
|
|
145
|
+
|
|
146
|
+
Paket dört giriş noktası sunar:
|
|
147
|
+
|
|
148
|
+
| Import yolu | İçerik |
|
|
149
|
+
|-------------|--------|
|
|
150
|
+
| `@raxonltd/raxon-core` | `RaxonProvider`, `useRaxon`, `nexineAxios`, analitik |
|
|
151
|
+
| `@raxonltd/raxon-core/hook` | Tüm veri hook'ları |
|
|
152
|
+
| `@raxonltd/raxon-core/view` | Hazır sayfa bileşenleri |
|
|
153
|
+
| `@raxonltd/raxon-core/interface/*` | TypeScript arayüzleri |
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
// Ana modül
|
|
157
|
+
import {
|
|
158
|
+
RaxonProvider,
|
|
159
|
+
useRaxon,
|
|
160
|
+
nexineAxios,
|
|
161
|
+
AnalyticEventProvider,
|
|
162
|
+
useAnalyticEvent,
|
|
163
|
+
} from '@raxonltd/raxon-core';
|
|
164
|
+
|
|
165
|
+
// Hook'lar
|
|
166
|
+
import { useProduct, useCart, useAuth } from '@raxonltd/raxon-core/hook';
|
|
167
|
+
|
|
168
|
+
// Görünümler
|
|
169
|
+
import { CheckoutView } from '@raxonltd/raxon-core/view';
|
|
170
|
+
|
|
171
|
+
// Tipler
|
|
172
|
+
import type { Product, Brand, Order } from '@raxonltd/raxon-core/interface/prisma.interface';
|
|
173
|
+
import type { IData } from '@raxonltd/raxon-core/interface/nexine.interface';
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## RaxonProvider
|
|
179
|
+
|
|
180
|
+
Uygulamanın kökünde bir kez sarılmalıdır. Şunları yapılandırır:
|
|
181
|
+
|
|
182
|
+
- Axios istemcisi (`nexineAxios`) — `baseURL` ve `x-api-key` header
|
|
183
|
+
- TanStack Query `QueryClient`
|
|
184
|
+
- Bootstrap verisi (`/customer/bootstrap`)
|
|
185
|
+
- Kimlik doğrulama durumu
|
|
186
|
+
- Sepet state'i (optimistic)
|
|
187
|
+
- Giriş ve bülten modalları
|
|
188
|
+
- Analitik sağlayıcı
|
|
189
|
+
|
|
190
|
+
### Props
|
|
191
|
+
|
|
192
|
+
| Prop | Tip | Zorunlu | Açıklama |
|
|
193
|
+
|------|-----|---------|----------|
|
|
194
|
+
| `apiKey` | `string` | Evet | Mağaza API anahtarı (`x-api-key`) |
|
|
195
|
+
| `apiUrl` | `string` | Evet | Backend temel URL'i |
|
|
196
|
+
| `productPathPrefix` | `string` | Hayır | Ürün URL öneki (analitik için, varsayılan: `/urunler`) |
|
|
197
|
+
| `analyticAutoTrack` | `boolean` | Hayır | Otomatik ürün görüntüleme takibi |
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
<RaxonProvider
|
|
201
|
+
apiKey="your-api-key"
|
|
202
|
+
apiUrl="https://api.example.com"
|
|
203
|
+
productPathPrefix="/urunler"
|
|
204
|
+
analyticAutoTrack
|
|
205
|
+
>
|
|
206
|
+
{children}
|
|
207
|
+
</RaxonProvider>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Mimari
|
|
211
|
+
|
|
212
|
+
```mermaid
|
|
213
|
+
flowchart TB
|
|
214
|
+
subgraph Provider["RaxonProvider"]
|
|
215
|
+
QC[QueryClientProvider]
|
|
216
|
+
subgraph Inner["RaxonProviderInner"]
|
|
217
|
+
Bootstrap["/customer/bootstrap"]
|
|
218
|
+
Security[SecurityContext]
|
|
219
|
+
Cart[CartState]
|
|
220
|
+
Analytics[AnalyticEventProvider]
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
QC --> Inner
|
|
225
|
+
Bootstrap --> useRaxon
|
|
226
|
+
Security --> useRaxon
|
|
227
|
+
Cart --> useRaxon
|
|
228
|
+
Analytics --> useAnalyticEvent
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## useRaxon — Global Context
|
|
234
|
+
|
|
235
|
+
`RaxonProvider` altında `useRaxon()` ile erişilen merkezi state.
|
|
236
|
+
|
|
237
|
+
### Bootstrap verileri
|
|
238
|
+
|
|
239
|
+
| Alan | Tip | Açıklama |
|
|
240
|
+
|------|-----|----------|
|
|
241
|
+
| `category` | `Category[]` | Hiyerarşik kategori ağacı |
|
|
242
|
+
| `flatCategory` | `Category[]` | Düzleştirilmiş kategori listesi |
|
|
243
|
+
| `collection` | `Collection[]` | Tüm koleksiyonlar |
|
|
244
|
+
| `banner` | `Collection[]` | `banner` etiketli koleksiyonlar |
|
|
245
|
+
| `subHeroCollection` | `Collection[]` | Alt hero koleksiyonları |
|
|
246
|
+
| `brand` | `Brand[]` | Markalar |
|
|
247
|
+
| `product` | `Product[]` | Öne çıkan ürünler |
|
|
248
|
+
| `bestSeller` | `Product[]` | Çok satanlar |
|
|
249
|
+
| `campaign` | `Campaign[]` | Kampanyalar |
|
|
250
|
+
| `basketCampaign` | `Campaign[]` | Sepet kampanyaları (koleksiyon hariç) |
|
|
251
|
+
| `paymentMethod` | `PaymentMethod[]` | Ödeme yöntemleri |
|
|
252
|
+
| `deliveryMethod` | `DeliveryMethod[]` | Teslimat yöntemleri |
|
|
253
|
+
| `defaultDeliveryMethod` | `DeliveryMethod \| null` | Varsayılan teslimat |
|
|
254
|
+
| `bankAccount` | `BankAccount[]` | Havale hesapları |
|
|
255
|
+
| `article` | `Article[]` | Blog / içerik |
|
|
256
|
+
| `faq` | `Faq[]` | SSS |
|
|
257
|
+
| `review` | `Review[]` | Yorumlar |
|
|
258
|
+
| `feed` | `Feed[]` | Feed verileri |
|
|
259
|
+
| `material` | `Material[]` | Materyaller |
|
|
260
|
+
| `holiday` | `Holiday[]` | Tatil günleri |
|
|
261
|
+
| `dynamicData` | `DynamicData[]` | Dinamik CMS verileri |
|
|
262
|
+
| `branch` | `Branch \| null` | Şube bilgisi |
|
|
263
|
+
| `isLoading` | `boolean` | Bootstrap yükleniyor mu |
|
|
264
|
+
|
|
265
|
+
### Kimlik doğrulama
|
|
266
|
+
|
|
267
|
+
| Alan | Tip | Açıklama |
|
|
268
|
+
|------|-----|----------|
|
|
269
|
+
| `profile` | `User \| null \| undefined` | Oturum açmış kullanıcı |
|
|
270
|
+
| `authLoading` | `boolean` | Auth kontrolü devam ediyor |
|
|
271
|
+
| `isAuthenticated` | `boolean` | Giriş yapılmış mı |
|
|
272
|
+
| `isGuest` | `boolean` | Misafir oturumu mu |
|
|
273
|
+
|
|
274
|
+
### Sepet (CartState)
|
|
275
|
+
|
|
276
|
+
| Alan / Metod | Açıklama |
|
|
277
|
+
|--------------|----------|
|
|
278
|
+
| `cart` | Güncel sepet özeti (`BasketSummaryInterface`) |
|
|
279
|
+
| `cartLoading` | Sepet yükleniyor |
|
|
280
|
+
| `cartTotal` | Toplam tutar |
|
|
281
|
+
| `addToCart(productId, quantity, variantId?)` | Ürün ekle (optimistic) |
|
|
282
|
+
| `updateQuantity(itemId, quantity)` | Miktar güncelle |
|
|
283
|
+
| `changeQuantity(itemId, delta)` | Miktar artır/azalt |
|
|
284
|
+
| `removeItem(itemId)` | Kalemi kaldır |
|
|
285
|
+
| `isProductAdding(productId, variantId?)` | Ekleme işlemi devam ediyor mu |
|
|
286
|
+
| `promoCode` / `setPromoCode` | Aktif promo kodu |
|
|
287
|
+
|
|
288
|
+
### Modal referansları
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
const { modalAuthRef, modalNewsletterVariantProductRef } = useRaxon();
|
|
292
|
+
|
|
293
|
+
// Giriş modalını aç
|
|
294
|
+
modalAuthRef.current?.open();
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Hook'lar
|
|
300
|
+
|
|
301
|
+
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.
|
|
302
|
+
|
|
303
|
+
> **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ı).
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
const { fetch } = useProduct();
|
|
307
|
+
const query = fetch({ categoryId: 'abc', page: 1 }); // useQuery sonucu
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### `useAuth`
|
|
313
|
+
|
|
314
|
+
Kimlik doğrulama işlemleri.
|
|
315
|
+
|
|
316
|
+
| Metod | Tip | Endpoint | Açıklama |
|
|
317
|
+
|-------|-----|----------|----------|
|
|
318
|
+
| `profile({ isEnabled })` | Query | `GET /customer/profile` | Profil bilgisi |
|
|
319
|
+
| `token()` | Mutation | `GET /auth/token` | Token al |
|
|
320
|
+
| `loginEmail()` | Mutation | `POST /auth/login/email` | E-posta ile giriş |
|
|
321
|
+
| `loginGuest()` | Mutation | `POST /auth/login/guest` | Misafir girişi |
|
|
322
|
+
| `loginSocial()` | Mutation | `GET /auth/login/social` | Sosyal giriş URL'i |
|
|
323
|
+
| `register()` | Mutation | `POST /auth/register` | Kayıt |
|
|
324
|
+
| `codeSend()` | Mutation | `POST /auth/code-send` | Şifre sıfırlama kodu |
|
|
325
|
+
| `verifyCode()` | Mutation | `POST /auth/code-verify` | Kod doğrulama |
|
|
326
|
+
| `resetPassword()` | Mutation | `POST /auth/reset-password` | Şifre sıfırlama |
|
|
327
|
+
| `logout()` | Fonksiyon | — | Token temizle ve yenile |
|
|
328
|
+
|
|
329
|
+
**Olaylar:** `LOGIN_SUCCESS_EVENT`, `LOGOUT_EVENT` — `window` üzerinde dinlenebilir.
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
const { loginEmail, logout } = useAuth();
|
|
333
|
+
const login = loginEmail();
|
|
334
|
+
|
|
335
|
+
login.mutate({ email: 'user@example.com', password: '***' });
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
### `useProduct`
|
|
341
|
+
|
|
342
|
+
Ürün listeleme, arama ve detay.
|
|
343
|
+
|
|
344
|
+
| Metod | Açıklama |
|
|
345
|
+
|-------|----------|
|
|
346
|
+
| `fetch(params)` | Filtrelenmiş ürün listesi |
|
|
347
|
+
| `searchData(search)` | Canlı arama (min. 3 karakter) |
|
|
348
|
+
| `detail(slug)` | Ürün detayı |
|
|
349
|
+
| `related(productId)` | İlişkili ürünler |
|
|
350
|
+
|
|
351
|
+
**`fetch` parametreleri (öne çıkanlar):**
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
{
|
|
355
|
+
categoryId?: string;
|
|
356
|
+
subCategoryId?: string;
|
|
357
|
+
brandId?: string[];
|
|
358
|
+
search?: string;
|
|
359
|
+
page?: number;
|
|
360
|
+
amount?: number; // varsayılan sayfa boyutu: 24
|
|
361
|
+
sortBy?: string;
|
|
362
|
+
collectionId?: string;
|
|
363
|
+
attributeOptionId?: string[];
|
|
364
|
+
minPrice?: number;
|
|
365
|
+
maxPrice?: number;
|
|
366
|
+
isFavorite?: boolean;
|
|
367
|
+
enabled?: boolean;
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### `useCart`
|
|
374
|
+
|
|
375
|
+
Sepet CRUD ve ödeme mutasyonları.
|
|
376
|
+
|
|
377
|
+
| Metod | Endpoint | Açıklama |
|
|
378
|
+
|-------|----------|----------|
|
|
379
|
+
| `fetch({ isEnabled, promoCodeId, campaignId, deliveryMethodId })` | `GET /customer/basket/me` | Sepet özeti |
|
|
380
|
+
| `insert()` | `POST /customer/basket/me/item` | Ürün ekle |
|
|
381
|
+
| `updateItem()` | `PUT /customer/basket/me/item` | Miktar güncelle |
|
|
382
|
+
| `remove()` | `DELETE /customer/basket/me/item/:id` | Kalem sil |
|
|
383
|
+
| `bulkInsert()` | `PATCH /customer/basket/me/item` | Toplu güncelleme |
|
|
384
|
+
| `update()` | `PUT /customer/basket` | Adres, ödeme, promo kod |
|
|
385
|
+
| `pay()` | `POST /customer/basket/me/pay` | Genel ödeme |
|
|
386
|
+
| `generatePaymentUrl()` | `POST /customer/basket/pay/paytr` | PayTR |
|
|
387
|
+
| `generateStripePaymentIntent()` | `POST /customer/basket/pay/stripe` | Stripe |
|
|
388
|
+
| `generateCashOnDeliveryPayment()` | `POST /customer/basket/pay/cash-on-delivery` | Kapıda ödeme |
|
|
389
|
+
| `createTransferCode()` | `POST /customer/payment/bank-transfer` | Havale kodu |
|
|
390
|
+
|
|
391
|
+
> Günlük sepet işlemleri için `useRaxon()` içindeki `addToCart`, `changeQuantity` gibi metodları tercih edin; bunlar optimistic güncelleme içerir.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
### `useBrand`
|
|
396
|
+
|
|
397
|
+
Marka listesi (sadece okuma).
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
const { fetch } = useBrand();
|
|
401
|
+
const { data } = fetch({ page: 1, amount: 50, enabled: true });
|
|
402
|
+
// data: IData<Brand> → { data: Brand[], count: number }
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
### `useCollection`
|
|
408
|
+
|
|
409
|
+
| Metod | Endpoint |
|
|
410
|
+
|-------|----------|
|
|
411
|
+
| `fetch(params?)` | `GET /customer/collection` |
|
|
412
|
+
| `detail(id)` | `GET /customer/collection/:id` |
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
### `useArticle`
|
|
417
|
+
|
|
418
|
+
| Metod | Endpoint |
|
|
419
|
+
|-------|----------|
|
|
420
|
+
| `fetch(params?)` | `GET /customer/article` |
|
|
421
|
+
| `detail(id)` | `GET /customer/article/:id` |
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
### `useFaq`
|
|
426
|
+
|
|
427
|
+
| Metod | Endpoint |
|
|
428
|
+
|-------|----------|
|
|
429
|
+
| `fetch({ page, amount })` | `GET /customer/faq` |
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
### `useAttribute`
|
|
434
|
+
|
|
435
|
+
| Metod | Endpoint |
|
|
436
|
+
|-------|----------|
|
|
437
|
+
| `fetch({ categoryId?, productId?, enabled? })` | `GET /customer/attribute` |
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### `useAddress`
|
|
442
|
+
|
|
443
|
+
| Metod | Endpoint |
|
|
444
|
+
|-------|----------|
|
|
445
|
+
| `fetch()` | `GET /customer/address` |
|
|
446
|
+
| `detail(id)` | `GET /customer/address/:id` |
|
|
447
|
+
| `create()` | `POST /customer/address` |
|
|
448
|
+
| `update()` | `PUT /customer/address` |
|
|
449
|
+
| `delete()` | `DELETE /customer/address/:id` |
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
### `useAddressAutocomplete`
|
|
454
|
+
|
|
455
|
+
Google Places tabanlı adres arama (host uygulamada `/api/places/autocomplete` route'u gerekir).
|
|
456
|
+
|
|
457
|
+
```tsx
|
|
458
|
+
const { query, setQuery, results, selectPlace, isSearching } = useAddressAutocomplete();
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
### `useProfile`
|
|
464
|
+
|
|
465
|
+
| Metod | Endpoint |
|
|
466
|
+
|-------|----------|
|
|
467
|
+
| `fetch({ isEnabled })` | `GET /customer/profile` |
|
|
468
|
+
| `update()` | `PUT /customer/profile` |
|
|
469
|
+
| `verifyPhoneNumber()` | `POST /customer/profile/verify/phone` |
|
|
470
|
+
| `verifyEmail()` | `POST /customer/profile/verify/email` |
|
|
471
|
+
| `fetchCompany({ enabled })` | `GET /customer/profile/company` |
|
|
472
|
+
| `applyCompany()` | `POST /customer/profile/company` |
|
|
473
|
+
| `uploadCompanyDocument()` | `POST /customer/profile/company/document` |
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### `useOrder`
|
|
478
|
+
|
|
479
|
+
| Metod | Endpoint |
|
|
480
|
+
|-------|----------|
|
|
481
|
+
| `fetch()` | `GET /customer/order` |
|
|
482
|
+
| `detail(id)` | `GET /customer/order/:id` |
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
### `useInvoice`
|
|
487
|
+
|
|
488
|
+
| Metod | Endpoint |
|
|
489
|
+
|-------|----------|
|
|
490
|
+
| `fetch()` | `GET /customer/invoice` |
|
|
491
|
+
| `detail(id)` | `GET /customer/invoice/:id` |
|
|
492
|
+
| `download()` | `GET /customer/invoice/:id/download` |
|
|
493
|
+
| `downloadByOrder()` | `GET /customer/invoice/order/:orderId/download` |
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
### `useFavorite`
|
|
498
|
+
|
|
499
|
+
| Metod | Endpoint |
|
|
500
|
+
|-------|----------|
|
|
501
|
+
| `list(params?, options?)` | `GET /customer/favorite` |
|
|
502
|
+
| `toggle()` | `POST /customer/favorite` |
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
### `useNewsletter`
|
|
507
|
+
|
|
508
|
+
| Metod | Endpoint |
|
|
509
|
+
|-------|----------|
|
|
510
|
+
| `subscribe` | `POST /customer/newsletter/subscribe` |
|
|
511
|
+
| `subscribeByVariant` | `POST /customer/newsletter/subscribe/variant` |
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
### `usePromoCode`
|
|
516
|
+
|
|
517
|
+
| Metod | Endpoint |
|
|
518
|
+
|-------|----------|
|
|
519
|
+
| `fetch({ status? })` | `GET /customer/promo-code` |
|
|
520
|
+
| `findByCode()` | `GET /customer/promo-code/:code` |
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
### `usePaymentMethod`
|
|
525
|
+
|
|
526
|
+
| Metod | Endpoint |
|
|
527
|
+
|-------|----------|
|
|
528
|
+
| `fetch({ enabled? })` | `GET /customer/payment/method` |
|
|
529
|
+
|
|
530
|
+
WEB etiketli yöntemlerle etiketsiz yöntemleri birleştirir.
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
### `useDeliveryMethod`
|
|
535
|
+
|
|
536
|
+
| Metod | Endpoint |
|
|
537
|
+
|-------|----------|
|
|
538
|
+
| `fetch({ enabled? })` | `GET /customer/delivery/method` |
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
### `useBankAccount`
|
|
543
|
+
|
|
544
|
+
| Metod | Endpoint |
|
|
545
|
+
|-------|----------|
|
|
546
|
+
| `fetch({ enabled? })` | `GET /customer/bank-account` |
|
|
547
|
+
| `createTransferCode()` | `POST /customer/payment/bank-transfer` |
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
### `useFormSubmit`
|
|
552
|
+
|
|
553
|
+
| Metod | Endpoint |
|
|
554
|
+
|-------|----------|
|
|
555
|
+
| `create()` | `POST /customer/form/submit` |
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Hazır Görünümler
|
|
560
|
+
|
|
561
|
+
`@raxonltd/raxon-core/view` modülünden import edilir.
|
|
562
|
+
|
|
563
|
+
### `CheckoutView`
|
|
564
|
+
|
|
565
|
+
Tam özellikli ödeme sayfası: iletişim, adres, fatura, teslimat/ödeme yöntemi seçimi, promo kod ve ödeme entegrasyonları.
|
|
566
|
+
|
|
567
|
+
```tsx
|
|
568
|
+
// app/sepet/odeme/page.tsx
|
|
569
|
+
'use client';
|
|
570
|
+
|
|
571
|
+
import { CheckoutView } from '@raxonltd/raxon-core/view';
|
|
572
|
+
|
|
573
|
+
export default function OdemePage() {
|
|
574
|
+
return <CheckoutView webReturnUrl="/sepet/odeme" />;
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
| Prop | Tip | Varsayılan | Açıklama |
|
|
579
|
+
|------|-----|------------|----------|
|
|
580
|
+
| `webReturnUrl` | `string` | `/sepet/odeme` | Ödeme sonrası dönüş URL'i |
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Analitik
|
|
585
|
+
|
|
586
|
+
`RaxonProvider` içinde `AnalyticEventProvider` otomatik etkinleşir.
|
|
587
|
+
|
|
588
|
+
```tsx
|
|
589
|
+
import { useAnalyticEvent } from '@raxonltd/raxon-core';
|
|
590
|
+
|
|
591
|
+
function ProductCard({ productId, variantId }: { productId: string; variantId?: string }) {
|
|
592
|
+
const { trackProductView, trackProductClick } = useAnalyticEvent();
|
|
593
|
+
|
|
594
|
+
return (
|
|
595
|
+
<div
|
|
596
|
+
onMouseEnter={() => trackProductView({ productId, variantId })}
|
|
597
|
+
onClick={() => trackProductClick({ productId, variantId })}
|
|
598
|
+
>
|
|
599
|
+
...
|
|
600
|
+
</div>
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
| Metod | Açıklama |
|
|
606
|
+
|-------|----------|
|
|
607
|
+
| `trackProductView` | Ürün görüntüleme (2 sn buffer ile toplu gönderim) |
|
|
608
|
+
| `trackProductClick` | Ürün tıklama |
|
|
609
|
+
| `trackEmailClicked` | E-posta kampanya tıklaması (`tcx` parametresi) |
|
|
610
|
+
|
|
611
|
+
`analyticAutoTrack={true}` ile URL'deki ürün sayfaları otomatik izlenir (`productPathPrefix` ile yapılandırılır).
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## Kimlik Doğrulama
|
|
616
|
+
|
|
617
|
+
Token `localStorage` içinde `koksal-token` anahtarıyla saklanır. `nexineAxios` her istekte `Authorization: Bearer <token>` header'ını otomatik ekler.
|
|
618
|
+
|
|
619
|
+
**Akış:**
|
|
620
|
+
|
|
621
|
+
1. `loginEmail` / `loginGuest` / `loginSocial` ile giriş
|
|
622
|
+
2. Token localStorage'a yazılır
|
|
623
|
+
3. `LOGIN_SUCCESS_EVENT` tetiklenir
|
|
624
|
+
4. Profil ve sepet sorguları invalidate edilir
|
|
625
|
+
5. 401 yanıtında token temizlenir ve toast gösterilir
|
|
626
|
+
|
|
627
|
+
```tsx
|
|
628
|
+
// Giriş sonrası dinleme
|
|
629
|
+
useEffect(() => {
|
|
630
|
+
const handler = () => router.refresh();
|
|
631
|
+
window.addEventListener('intermarkt-login-success', handler);
|
|
632
|
+
return () => window.removeEventListener('intermarkt-login-success', handler);
|
|
633
|
+
}, []);
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## Sepet Yönetimi
|
|
639
|
+
|
|
640
|
+
İki katman vardır:
|
|
641
|
+
|
|
642
|
+
1. **`useRaxon()` sepet API'si** — UI için optimistic, debounce'lu; günlük kullanımda bunu tercih edin
|
|
643
|
+
2. **`useCart()` hook'u** — Düşük seviye; checkout ve özel akışlar için
|
|
644
|
+
|
|
645
|
+
```tsx
|
|
646
|
+
const { addToCart, cart, cartTotal, isProductAdding } = useRaxon();
|
|
647
|
+
|
|
648
|
+
<button
|
|
649
|
+
onClick={() => addToCart(product.id, 1, variantId)}
|
|
650
|
+
disabled={isProductAdding(product.id, variantId)}
|
|
651
|
+
>
|
|
652
|
+
Sepete Ekle
|
|
653
|
+
</button>
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
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.
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## TypeScript Arayüzleri
|
|
661
|
+
|
|
662
|
+
```ts
|
|
663
|
+
import type { Brand, Product, Order, Cart } from '@raxonltd/raxon-core/interface/prisma.interface';
|
|
664
|
+
import type { ProductDetail } from '@raxonltd/raxon-core/interface/product.interface';
|
|
665
|
+
import type { BasketSummaryInterface } from '@raxonltd/raxon-core/interface/basket.interface';
|
|
666
|
+
import type { IData } from '@raxonltd/raxon-core/interface/nexine.interface';
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### `IData<T>` — Sayfalanmış liste yanıtı
|
|
670
|
+
|
|
671
|
+
```ts
|
|
672
|
+
interface IData<T> {
|
|
673
|
+
data: T[];
|
|
674
|
+
count: number;
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
---
|
|
679
|
+
|
|
680
|
+
## Ortam Değişkenleri
|
|
681
|
+
|
|
682
|
+
| Değişken | Açıklama |
|
|
683
|
+
|----------|----------|
|
|
684
|
+
| `NEXT_PUBLIC_API_KEY` | API anahtarı (SSR / sunucu tarafı istekler için) |
|
|
685
|
+
| `NEXT_PUBLIC_API_URL` | API temel URL'i |
|
|
686
|
+
|
|
687
|
+
Client tarafında `RaxonProvider` bu değerleri `window.__RAXON_API_KEY__` ve `window.__RAXON_API_URL__` üzerinden de ayarlar.
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
## Next.js Entegrasyonu
|
|
692
|
+
|
|
693
|
+
### `'use client'` zorunluluğu
|
|
694
|
+
|
|
695
|
+
`RaxonProvider`, hook'lar ve view bileşenleri client component gerektirir. Server Component içinde doğrudan kullanmayın.
|
|
696
|
+
|
|
697
|
+
### Toast bildirimleri
|
|
698
|
+
|
|
699
|
+
`nexineAxios` başarılı/hatalı mutasyonlarda `react-hot-toast` kullanır. Layout'a `<Toaster />` ekleyin.
|
|
700
|
+
|
|
701
|
+
### Adres otomatik tamamlama
|
|
702
|
+
|
|
703
|
+
`useAddressAutocomplete` host uygulamada şu route'u bekler:
|
|
704
|
+
|
|
705
|
+
```
|
|
706
|
+
GET /api/places/autocomplete?input=...&components=country:tr&language=tr
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Özel axios istekleri
|
|
710
|
+
|
|
711
|
+
```ts
|
|
712
|
+
import { nexineAxios } from '@raxonltd/raxon-core';
|
|
713
|
+
|
|
714
|
+
const response = await nexineAxios.get('/customer/custom-endpoint');
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## Geliştirme
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
git clone https://github.com/raxonltd/raxon-core.git
|
|
723
|
+
cd raxon-core
|
|
724
|
+
npm install
|
|
725
|
+
npm run build
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### Yayınlama
|
|
729
|
+
|
|
730
|
+
```bash
|
|
731
|
+
npm version patch # veya minor / major
|
|
732
|
+
npm run build
|
|
733
|
+
npm publish
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
## Sorun Giderme
|
|
739
|
+
|
|
740
|
+
| Sorun | Çözüm |
|
|
741
|
+
|-------|-------|
|
|
742
|
+
| `useRaxon must be used within a RaxonProvider` | Bileşeni `RaxonProvider` ile sarın |
|
|
743
|
+
| Sepet boş görünüyor | `isAuthenticated` kontrol edin; misafir girişi gerekebilir |
|
|
744
|
+
| Toast görünmüyor | `<Toaster />` ekleyin |
|
|
745
|
+
| 401 hataları | Token süresi dolmuş; yeniden giriş yapın |
|
|
746
|
+
| Hook kuralları hatası | Hook metodlarını koşullu veya döngü içinde çağırmayın |
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
## Lisans
|
|
751
|
+
|
|
752
|
+
[ISC](LICENSE)
|
|
753
|
+
|
|
754
|
+
## Bağlantılar
|
|
755
|
+
|
|
756
|
+
- [npm](https://www.npmjs.com/package/@raxonltd/raxon-core)
|
|
757
|
+
- [GitHub](https://github.com/raxonltd/raxon-core)
|
|
758
|
+
- [Sorun bildir](https://github.com/raxonltd/raxon-core/issues)
|