Files
ihaleist/src/components/CancelSubscriptionModal.jsx
T

120 lines
5.0 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import { X, AlertTriangle, Loader2 } from 'lucide-react';
import { cancelSubscription } from '../services/account';
/**
* Abonelik iptali — nedeni sorar, dönem sonunda iptal eder.
* Erişim ödenen sürenin sonuna kadar sürer; anında kesilmez.
*/
export const CancelSubscriptionModal = ({ planAdi, nedenler = [], onKapat, onIptalEdildi }) => {
const [neden, setNeden] = useState('');
const [aciklama, setAciklama] = useState('');
const [busy, setBusy] = useState(false);
const [hata, setHata] = useState(null);
// "Diğer" seçildiyse açıklama zorunlu — yoksa geri bildirim işe yaramaz.
const digerSecili = neden === 'other';
const gonderilebilir = Boolean(neden) && (!digerSecili || aciklama.trim().length >= 3);
const gonder = async () => {
setBusy(true);
setHata(null);
try {
const out = await cancelSubscription(neden, aciklama.trim());
onIptalEdildi(out);
} catch (e) {
setHata(e.message || 'İptal edilemedi');
} finally {
setBusy(false);
}
};
return (
<div className="fixed inset-0 z-50 bg-slate-900/60 backdrop-blur-xs flex items-center justify-center p-4">
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
<div className="flex items-start justify-between gap-3 p-5 border-b border-slate-100">
<div className="flex gap-3">
<div className="w-10 h-10 rounded-xl bg-amber-100 flex items-center justify-center shrink-0">
<AlertTriangle className="w-5 h-5 text-amber-700" />
</div>
<div>
<h3 className="font-black text-slate-900">Aboneliği iptal et</h3>
<p className="text-xs text-slate-500 mt-0.5">
{planAdi} planınız <strong>dönem sonunda</strong> sona erer. Ödediğiniz sürenin sonuna
kadar tüm özellikler açık kalır, yenileme yapılmaz.
</p>
</div>
</div>
<button onClick={onKapat} className="text-slate-400 hover:text-slate-700 shrink-0" aria-label="Kapat">
<X className="w-5 h-5" />
</button>
</div>
<div className="p-5 space-y-4">
<div>
<p className="text-xs font-bold text-slate-700 mb-2">Ayrılma nedeniniz nedir? <span className="text-red-500">*</span></p>
<div className="space-y-1.5">
{nedenler.map((n) => (
<label
key={n.id}
className={`flex items-center gap-2.5 px-3 py-2 rounded-lg border cursor-pointer text-xs transition-colors ${
neden === n.id
? 'border-blue-500 bg-blue-50 text-blue-900 font-semibold'
: 'border-slate-200 hover:bg-slate-50 text-slate-700'
}`}
>
<input
type="radio"
name="iptal-neden"
value={n.id}
checked={neden === n.id}
onChange={() => setNeden(n.id)}
className="accent-blue-600"
/>
<span>{n.label}</span>
</label>
))}
</div>
</div>
<div>
<label className="text-xs font-bold text-slate-700 block mb-1.5">
Biraz daha anlatır mısınız? {digerSecili ? <span className="text-red-500">*</span> : <span className="font-normal text-slate-400">(isteğe bağlı)</span>}
</label>
<textarea
rows={3}
value={aciklama}
maxLength={500}
onChange={(e) => setAciklama(e.target.value)}
placeholder="Neyi eksik bulduğunuzu yazarsanız düzeltiriz."
className="w-full border border-slate-200 rounded-lg px-3 py-2 text-xs focus:outline-hidden focus:ring-2 focus:ring-blue-500/30 focus:border-blue-400"
/>
<p className="text-[10px] text-slate-400 mt-1 text-right">{aciklama.length}/500</p>
</div>
{hata && (
<div className="bg-red-50 border border-red-200 rounded-lg p-3 text-xs text-red-800">{hata}</div>
)}
</div>
<div className="flex gap-2 p-5 border-t border-slate-100">
<button
onClick={onKapat}
className="flex-1 py-2.5 rounded-xl text-xs font-bold text-slate-700 bg-slate-100 hover:bg-slate-200 transition-colors"
>
Vazgeç, kalıyorum
</button>
<button
onClick={gonder}
disabled={!gonderilebilir || busy}
className="flex-1 py-2.5 rounded-xl text-xs font-extrabold text-white bg-red-600 hover:bg-red-500 transition-colors disabled:opacity-40 disabled:cursor-not-allowed flex items-center justify-center gap-2"
>
{busy && <Loader2 className="w-4 h-4 animate-spin" />}
{busy ? 'İptal ediliyor…' : 'Aboneliği iptal et'}
</button>
</div>
</div>
</div>
);
};