stripe changes

This commit is contained in:
2026-01-05 09:37:20 +01:00
parent d04d9d9887
commit 8f863153cb
5 changed files with 241 additions and 60 deletions

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { X, Info, CheckCircle, AlertTriangle, MessageSquare, Calendar, ChevronDown, ChevronUp, Wallet, ArrowLeft, RefreshCw, CreditCard } from 'lucide-react'; import { X, Info, CheckCircle, AlertTriangle, MessageSquare, Calendar, ChevronDown, ChevronUp, Wallet, ArrowLeft, RefreshCw, CreditCard, Globe } from 'lucide-react';
import { Button } from './Button'; import { Button } from './Button';
interface FeedbackModalProps { interface FeedbackModalProps {
@@ -18,6 +18,7 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
// Approval Flow // Approval Flow
const [approvalConfirmed, setApprovalConfirmed] = useState(false); const [approvalConfirmed, setApprovalConfirmed] = useState(false);
const [approvedDomain, setApprovedDomain] = useState('');
// Revision Flow // Revision Flow
const [designCheckboxes, setDesignCheckboxes] = useState<string[]>([]); const [designCheckboxes, setDesignCheckboxes] = useState<string[]>([]);
@@ -47,9 +48,10 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
setShowPayment(false); setShowPayment(false);
setApprovalConfirmed(false); setApprovalConfirmed(false);
setRevisionConfirmed(false); setRevisionConfirmed(false);
setApprovedDomain(order?.details?.domainName || '');
// Reset other fields if needed // Reset other fields if needed
} }
}, [isOpen]); }, [isOpen, order]);
if (!isOpen) return null; if (!isOpen) return null;
@@ -95,7 +97,8 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
submittedAt: new Date().toISOString(), submittedAt: new Date().toISOString(),
approval: mainDecision === 'approved' ? { approval: mainDecision === 'approved' ? {
confirmed: approvalConfirmed, confirmed: approvalConfirmed,
paymentComplete: showPayment // Flag that payment step was shown paymentComplete: showPayment, // Flag that payment step was shown
domain: approvedDomain // Pass the domain
} : null, } : null,
revision: isRevision ? { revision: isRevision ? {
design: { selected: designCheckboxes, comment: designText }, design: { selected: designCheckboxes, comment: designText },
@@ -270,21 +273,40 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
</div> </div>
{mainDecision === 'approved' && ( {mainDecision === 'approved' && (
<div className="animate-fade-in bg-green-50 p-6 rounded-2xl border-2 border-green-200 shadow-inner"> <div className="space-y-6">
<h3 className="text-green-900 font-black mb-4 flex items-center gap-2 uppercase text-sm tracking-widest"> <div className="animate-fade-in bg-green-50 p-6 rounded-2xl border-2 border-green-200 shadow-inner">
<CheckCircle className="w-5 h-5" /> Megerősítés <h3 className="text-green-900 font-black mb-4 flex items-center gap-2 uppercase text-sm tracking-widest">
</h3> <CheckCircle className="w-5 h-5" /> Megerősítés
<label className="flex items-start cursor-pointer group"> </h3>
<input <label className="flex items-start cursor-pointer group">
type="checkbox" <input
checked={approvalConfirmed} type="checkbox"
onChange={(e) => setApprovalConfirmed(e.target.checked)} checked={approvalConfirmed}
className="mt-1 w-6 h-6 text-green-600 rounded-lg focus:ring-green-500 border-green-300" onChange={(e) => setApprovalConfirmed(e.target.checked)}
/> className="mt-1 w-6 h-6 text-green-600 rounded-lg focus:ring-green-500 border-green-300"
<span className="ml-4 text-sm text-green-800 font-bold leading-relaxed"> />
Tudomásul veszem, hogy a jóváhagyással elfogadom a jelenlegi állapotot, és a folyamat a végleges elszámolással folytatódik. <span className="ml-4 text-sm text-green-800 font-bold leading-relaxed">
</span> Tudomásul veszem, hogy a jóváhagyással elfogadom a jelenlegi állapotot, és a folyamat a végleges elszámolással folytatódik.
</label> </span>
</label>
</div>
<div className="animate-fade-in">
<label className="block text-xs font-black text-gray-900 uppercase tracking-widest mb-2 ml-1">Végleges Domain Név</label>
<div className="relative">
<Globe className="absolute left-4 top-3.5 w-5 h-5 text-gray-400" />
<input
type="text"
value={approvedDomain}
onChange={(e) => setApprovedDomain(e.target.value)}
placeholder="pl. mintaweboldal.hu"
className="w-full pl-12 pr-4 py-3 rounded-xl border border-gray-300 bg-white text-black focus:ring-4 focus:ring-green-100 focus:border-green-500 outline-none transition-all font-bold"
/>
</div>
<p className="text-[10px] text-gray-500 mt-2 ml-1 font-medium leading-relaxed">
Kérlek add meg, milyen domain címen szeretnéd elérni a weboldalt. Átadás előtt ellenőrizzük a foglalhatóságot/elérhetőséget, és ha probléma merül fel, felvesszük veled a kapcsolatot.
</p>
</div>
</div> </div>
)} )}

View File

@@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Menu, X, Code2, User, LogIn, UserPlus, LogOut, LayoutDashboard, ShieldAlert } from 'lucide-react'; import { Menu, X, Code2, User, LogIn, UserPlus, LogOut, LayoutDashboard, ShieldAlert, Crown } from 'lucide-react';
import { Link, useLocation, useNavigate } from 'react-router-dom'; import { Link, useLocation, useNavigate } from 'react-router-dom';
import { Button } from './Button'; import { Button } from './Button';
import { useAuth } from '../context/AuthContext'; import { useAuth } from '../context/AuthContext';
@@ -114,7 +115,11 @@ export const Navbar: React.FC = () => {
aria-label="Felhasználói fiók" aria-label="Felhasználói fiók"
> >
<User className="w-6 h-6" /> <User className="w-6 h-6" />
{isAdmin && <div className="absolute top-1 right-1 w-2.5 h-2.5 bg-red-500 rounded-full border-2 border-white"></div>} {isAdmin && (
<div className="absolute -top-1 -right-1 bg-white rounded-full p-0.5 shadow-sm border border-gray-100">
<Crown className="w-3.5 h-3.5 text-yellow-500 fill-yellow-500" />
</div>
)}
</button> </button>
{isProfileOpen && ( {isProfileOpen && (
@@ -233,4 +238,4 @@ export const Navbar: React.FC = () => {
)} )}
</nav> </nav>
); );
}; };

View File

@@ -9,7 +9,8 @@ import {
AlertTriangle, Archive, Send, Layout, History, MessageCircle, Info, ChevronDown, ChevronUp, AlertTriangle, Archive, Send, Layout, History, MessageCircle, Info, ChevronDown, ChevronUp,
Upload, FileDown, Receipt, CreditCard, DollarSign, Plus, Trash2, Building2, User as UserIcon, Upload, FileDown, Receipt, CreditCard, DollarSign, Plus, Trash2, Building2, User as UserIcon,
Palette, Zap, Lightbulb, Link as LinkIcon, ExternalLink, Target, FileStack, Star, Check, Palette, Zap, Lightbulb, Link as LinkIcon, ExternalLink, Target, FileStack, Star, Check,
Copy, Cpu, Wand2, Eye, EyeOff, ShieldCheck, Calendar, Search, ArrowUpDown, Filter Copy, Cpu, Wand2, Eye, EyeOff, ShieldCheck, Calendar, Search, ArrowUpDown, Filter,
TrendingUp, ArrowRight
} from 'lucide-react'; } from 'lucide-react';
import { Button } from '../components/Button'; import { Button } from '../components/Button';
import { supabase, isSupabaseConfigured } from '../lib/supabaseClient'; import { supabase, isSupabaseConfigured } from '../lib/supabaseClient';
@@ -57,6 +58,7 @@ interface AdminOrder {
status: string; status: string;
date: string; date: string;
amount: string; amount: string;
created_at: string;
details?: any; details?: any;
history?: OrderHistoryEntry[]; history?: OrderHistoryEntry[];
emailLogs?: EmailLogEntry[]; emailLogs?: EmailLogEntry[];
@@ -157,8 +159,8 @@ const getEmailTemplate = (type: string, data: {
body: `<div style="${baseStyle}"> body: `<div style="${baseStyle}">
<div style="${headerStyle}">MotionWeb</div> <div style="${headerStyle}">MotionWeb</div>
<p>Kedves <strong>${data.customer}</strong>!</p> <p>Kedves <strong>${data.customer}</strong>!</p>
<p>Köszönöm a visszajelzését a <strong>${data.package}</strong> demó verziójával kapcsolatban.</p> <p>Köszönöm a visszajelzéseit! Megkezdtem a kért módosítások átvezetését a weboldalon.</p>
<p>A kért módosításokat feldolgoztam, és megkezdtem azok átvezetését a weboldalon. Amint elkészültem a frissített verzióval, e-mailben értesítem.</p> <p>Hamarosan jelentkezem a frissített verzióval.</p>
<div style="${footerStyle}">Üdvözlettel,<br><strong>Balogh Bence Benedek</strong><br>MotionWeb | motionweb.hu</div> <div style="${footerStyle}">Üdvözlettel,<br><strong>Balogh Bence Benedek</strong><br>MotionWeb | motionweb.hu</div>
</div>` </div>`
}, },
@@ -495,9 +497,7 @@ export const Admin: React.FC = () => {
try { try {
if (typeof e === 'string') errorMessage = e; if (typeof e === 'string') errorMessage = e;
else if (e instanceof Error) errorMessage = e.message; else if (e instanceof Error) errorMessage = e.message;
else if (typeof e === 'object' && e !== null) { else if (typeof e === 'object') errorMessage = JSON.stringify(e);
errorMessage = e.message || e.error_description || JSON.stringify(e);
}
} catch (jsonErr) { } catch (jsonErr) {
errorMessage = "Nem szerializálható hiba objektum"; errorMessage = "Nem szerializálható hiba objektum";
} }
@@ -583,22 +583,35 @@ export const Admin: React.FC = () => {
return; return;
} }
// Generate Stripe Link
const { data: checkoutData, error: checkoutError } = await supabase.functions.invoke('create-checkout-session', {
body: {
order_id: sub.order_id,
package_name: 'Maintenance',
payment_type: 'annual',
customer_email: sub.client_email
}
});
if (checkoutError || !checkoutData?.url) {
throw new Error('Nem sikerült generálni a fizetési linket.');
}
const paymentLink = checkoutData.url;
const daysLeft = getDaysRemaining(sub.next_billing_date); const daysLeft = getDaysRemaining(sub.next_billing_date);
const emailType = 'Előfizetés emlékeztető'; const emailType = 'Előfizetés emlékeztető';
const nowIso = new Date().toISOString(); const nowIso = new Date().toISOString();
// Placeholder payment link
const paymentLink = "https://stripe.com/payment_placeholder";
const orderData = sub.order as any; // Cast to avoid TS issues if types aren't perfect const orderData = sub.order as any; // Cast to avoid TS issues if types aren't perfect
const customerName = orderData?.customer_name || 'Ügyfél'; const customerName = orderData?.customer_name || 'Ügyfél';
const customerEmail = sub.client_email || orderData?.customer_email; const customerEmail = sub.client_email || orderData?.customer_email;
const domain = orderData?.details?.domainName; const domain = orderData?.details?.domainName;
const amount = "59 990 Ft"; // Or use orderData.amount if applicable const amount = "59 990 Ft";
const template = getEmailTemplate(emailType, { const template = getEmailTemplate(emailType, {
customer: customerName, customer: customerName,
package: 'Fenntartás', // Dummy package name for template type signature package: 'Fenntartás',
domain: domain, domain: domain,
daysLeft: daysLeft, daysLeft: daysLeft,
paymentLink: paymentLink, paymentLink: paymentLink,
@@ -927,22 +940,162 @@ export const Admin: React.FC = () => {
</div> </div>
<div className="animate-fade-in"> <div className="animate-fade-in">
{activeTab === 'overview' && ( {activeTab === 'overview' && (() => {
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8"> // -- Statistics Logic Calculation inside render for Overview Tab --
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm"> const orderStats = {
<p className="text-xs font-bold text-gray-400 uppercase mb-3 tracking-widest">Látogatók</p> new: orders.filter(o => o.status === 'new').length,
<h3 className="text-4xl md:text-5xl font-black text-gray-900">{visitorStats.month}</h3> inProgress: orders.filter(o => o.status === 'in_progress').length,
feedback: orders.filter(o => ['pending_feedback', 'waiting_feedback'].includes(o.status)).length,
completed: orders.filter(o => o.status === 'completed').length
};
const activeSubs = subscriptions.filter(s => s.status === 'active').length;
// Generate Yearly Chart Data
const currentYear = new Date().getFullYear();
const monthlyOrders = Array(12).fill(0);
orders.forEach(o => {
const d = new Date(o.created_at);
if (d.getFullYear() === currentYear) {
monthlyOrders[d.getMonth()]++;
}
});
const maxOrderCount = Math.max(...monthlyOrders, 1); // Avoid div by zero
const monthLabels = ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'];
return (
<div className="space-y-8">
<div className="flex items-center gap-3 mb-2">
<h3 className="text-xl font-black text-gray-900 tracking-tight">Statisztika & Elemzés</h3>
<div className="h-px bg-gray-200 flex-grow"></div>
</div>
{/* Visitors Section */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="bg-gradient-to-br from-blue-50 to-white p-6 rounded-[28px] border border-blue-100 shadow-sm relative overflow-hidden group">
<div className="absolute right-0 top-0 w-24 h-24 bg-blue-100 rounded-full blur-2xl -mr-10 -mt-10 group-hover:bg-blue-200 transition-colors"></div>
<div className="relative z-10">
<div className="flex items-center gap-3 mb-4">
<div className="p-2 bg-blue-100 rounded-xl text-blue-600"><Users className="w-5 h-5" /></div>
<span className="text-xs font-black text-blue-800 uppercase tracking-widest">Heti Látogatók</span>
</div>
<h3 className="text-4xl font-black text-gray-900">{visitorStats.week}</h3>
<p className="text-[10px] text-gray-400 font-bold mt-2 uppercase tracking-wide">Aktuális hét</p>
</div>
</div>
<div className="bg-gradient-to-br from-purple-50 to-white p-6 rounded-[28px] border border-purple-100 shadow-sm relative overflow-hidden group">
<div className="absolute right-0 top-0 w-24 h-24 bg-purple-100 rounded-full blur-2xl -mr-10 -mt-10 group-hover:bg-purple-200 transition-colors"></div>
<div className="relative z-10">
<div className="flex items-center gap-3 mb-4">
<div className="p-2 bg-purple-100 rounded-xl text-purple-600"><Calendar className="w-5 h-5" /></div>
<span className="text-xs font-black text-purple-800 uppercase tracking-widest">Havi Látogatók</span>
</div>
<h3 className="text-4xl font-black text-gray-900">{visitorStats.month}</h3>
<p className="text-[10px] text-gray-400 font-bold mt-2 uppercase tracking-wide">Becsült aktivitás</p>
</div>
</div>
<div className="bg-gradient-to-br from-gray-50 to-white p-6 rounded-[28px] border border-gray-200 shadow-sm relative overflow-hidden group">
<div className="absolute right-0 top-0 w-24 h-24 bg-gray-100 rounded-full blur-2xl -mr-10 -mt-10 group-hover:bg-gray-200 transition-colors"></div>
<div className="relative z-10">
<div className="flex items-center gap-3 mb-4">
<div className="p-2 bg-gray-200 rounded-xl text-gray-600"><Globe className="w-5 h-5" /></div>
<span className="text-xs font-black text-gray-600 uppercase tracking-widest">Összes Látogató</span>
</div>
<h3 className="text-4xl font-black text-gray-900">{visitorStats.month}</h3>
<p className="text-[10px] text-gray-400 font-bold mt-2 uppercase tracking-wide">Indulás óta</p>
</div>
</div>
</div>
{/* Orders Funnel & Active Subs */}
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
{/* Funnel */}
<div className="lg:col-span-3 bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm">
<h4 className="text-sm font-black text-gray-900 uppercase tracking-widest mb-6 flex items-center gap-2">
<Activity className="w-4 h-4 text-primary" /> Rendelési Folyamat
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div className="p-5 rounded-2xl bg-blue-50 border border-blue-100 flex flex-col justify-between h-32 relative overflow-hidden">
<div className="absolute right-2 top-2 opacity-10"><ShoppingCart className="w-16 h-16 text-blue-600" /></div>
<span className="text-xs font-black text-blue-600 uppercase tracking-widest">Új Rendelés</span>
<div className="flex items-end justify-between">
<h3 className="text-3xl font-black text-blue-900">{orderStats.new}</h3>
<ArrowRight className="w-5 h-5 text-blue-300" />
</div>
</div>
<div className="p-5 rounded-2xl bg-yellow-50 border border-yellow-100 flex flex-col justify-between h-32 relative overflow-hidden">
<div className="absolute right-2 top-2 opacity-10"><RefreshCw className="w-16 h-16 text-yellow-600" /></div>
<span className="text-xs font-black text-yellow-600 uppercase tracking-widest">Folyamatban</span>
<div className="flex items-end justify-between">
<h3 className="text-3xl font-black text-yellow-900">{orderStats.inProgress}</h3>
<ArrowRight className="w-5 h-5 text-yellow-300" />
</div>
</div>
<div className="p-5 rounded-2xl bg-purple-50 border border-purple-100 flex flex-col justify-between h-32 relative overflow-hidden">
<div className="absolute right-2 top-2 opacity-10"><MessageSquare className="w-16 h-16 text-purple-600" /></div>
<span className="text-xs font-black text-purple-600 uppercase tracking-widest">Visszajelzés</span>
<div className="flex items-end justify-between">
<h3 className="text-3xl font-black text-purple-900">{orderStats.feedback}</h3>
<CheckCircle className="w-5 h-5 text-purple-300" />
</div>
</div>
</div>
</div>
{/* Active Subs */}
<div className="bg-[#0f172a] p-8 rounded-[32px] text-white flex flex-col justify-between relative overflow-hidden shadow-xl">
<div className="absolute top-0 right-0 w-32 h-32 bg-primary/20 rounded-full blur-3xl pointer-events-none"></div>
<div>
<div className="flex items-center gap-2 text-primary mb-4">
<ShieldCheck className="w-5 h-5" />
<span className="text-xs font-black uppercase tracking-widest">Aktív Előfizetések</span>
</div>
<h3 className="text-5xl font-black mb-1">{activeSubs}</h3>
<p className="text-xs text-gray-400 font-bold uppercase tracking-wide">Karbantartott oldalak</p>
</div>
<div className="mt-6 pt-6 border-t border-gray-800">
<div className="flex justify-between items-center text-xs font-bold text-gray-300">
<span>Becsült Bevétel (Havi)</span>
<span className="text-primary">{Math.round(activeSubs * (59990/12)).toLocaleString()} Ft</span>
</div>
</div>
</div>
</div>
{/* Yearly Chart */}
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm">
<div className="flex justify-between items-center mb-8">
<h4 className="text-sm font-black text-gray-900 uppercase tracking-widest flex items-center gap-2">
<TrendingUp className="w-4 h-4 text-primary" /> Rendelések alakulása ({currentYear})
</h4>
<div className="bg-gray-100 px-3 py-1 rounded-lg text-[10px] font-bold text-gray-500 uppercase">Havi bontás</div>
</div>
<div className="h-64 w-full flex items-end justify-between gap-2 sm:gap-4 px-2">
{monthlyOrders.map((count, idx) => {
const heightPercentage = maxOrderCount > 0 ? (count / maxOrderCount) * 100 : 0;
return (
<div key={idx} className="flex-1 flex flex-col items-center gap-2 group">
<div className="w-full relative flex items-end justify-center h-48 bg-gray-50 rounded-t-xl rounded-b-md overflow-hidden">
<div
className="w-full bg-primary/80 group-hover:bg-primary transition-all duration-500 rounded-t-lg relative min-h-[4px]"
style={{ height: `${heightPercentage}%` }}
>
{count > 0 && (
<div className="absolute -top-8 left-1/2 -translate-x-1/2 bg-gray-900 text-white text-[10px] font-bold px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity">
{count} db
</div>
)}
</div>
</div>
<span className="text-[10px] font-bold text-gray-400 uppercase tracking-wide group-hover:text-primary transition-colors">{monthLabels[idx]}</span>
</div>
)
})}
</div>
</div>
</div> </div>
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm"> );
<p className="text-xs font-bold text-gray-400 uppercase mb-3 tracking-widest">Rendelések</p> })()}
<h3 className="text-4xl md:text-5xl font-black text-gray-900">{orders.length}</h3>
</div>
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm">
<p className="text-xs font-bold text-gray-400 uppercase mb-3 tracking-widest">Aktív Előfizetések</p>
<h3 className="text-4xl md:text-5xl font-black text-gray-900">{subscriptions.filter(s => s.status === 'active').length}</h3>
</div>
</div>
)}
{activeTab === 'users' && ( {activeTab === 'users' && (
<div className="bg-white rounded-[32px] border border-gray-100 shadow-sm overflow-hidden"> <div className="bg-white rounded-[32px] border border-gray-100 shadow-sm overflow-hidden">

View File

@@ -213,6 +213,18 @@ export const Dashboard: React.FC = () => {
const paymentSummary = currentOrder.details?.payment_summary; const paymentSummary = currentOrder.details?.payment_summary;
const isStandardPackage = ['Landing Page', 'Pro Web'].includes(currentOrder.package); const isStandardPackage = ['Landing Page', 'Pro Web'].includes(currentOrder.package);
// Extract the new domain if provided during approval
const approvedDomain = feedbackData.approval?.domain;
// Construct base updated details
const updatedDetails = {
...(currentOrder.details || {}),
latestFeedback: feedbackData,
feedbackDate: new Date().toISOString(),
// If approved domain is provided, update the main domainName field so it's visible in Admin
...(approvedDomain ? { domainName: approvedDomain } : {})
};
// Check if payment is needed: Approved + Standard Package + Not Custom Price + Has Remaining Balance // Check if payment is needed: Approved + Standard Package + Not Custom Price + Has Remaining Balance
// Note: paymentSummary.remaining > 0 check is implicitly handled by Logic in FeedbackModal (it shows payment button only if true) // Note: paymentSummary.remaining > 0 check is implicitly handled by Logic in FeedbackModal (it shows payment button only if true)
// But we double check here for security. // But we double check here for security.
@@ -240,12 +252,7 @@ export const Dashboard: React.FC = () => {
if (checkoutData?.url) { if (checkoutData?.url) {
// Update details with feedback content BEFORE redirecting // Update details with feedback content BEFORE redirecting
// This ensures we save the "Approval" state even if they drop off payment (status remains pending_feedback though) // This ensures we save the "Approval" and the new domain even if they drop off payment (status remains pending_feedback though)
const updatedDetails = {
...(currentOrder.details || {}),
latestFeedback: feedbackData,
feedbackDate: new Date().toISOString()
};
await supabase.from('orders').update({ details: updatedDetails }).eq('id', selectedOrderId); await supabase.from('orders').update({ details: updatedDetails }).eq('id', selectedOrderId);
// Redirect to Stripe // Redirect to Stripe
@@ -257,12 +264,6 @@ export const Dashboard: React.FC = () => {
} }
// If no payment needed (e.g. revision request, or custom price, or enterprise), update status directly // If no payment needed (e.g. revision request, or custom price, or enterprise), update status directly
const updatedDetails = {
...(currentOrder.details || {}),
latestFeedback: feedbackData,
feedbackDate: new Date().toISOString()
};
const newStatus = 'in_progress'; // Send back to dev in both cases (to finalize or revise) const newStatus = 'in_progress'; // Send back to dev in both cases (to finalize or revise)
const { error: updateError } = await supabase.from('orders').update({ const { error: updateError } = await supabase.from('orders').update({

View File

@@ -51,7 +51,7 @@ serve(async (req) => {
priceId = 'price_1SiIif25dc768V7UqsfSi345'; // Pro Web - Fennmaradó priceId = 'price_1SiIif25dc768V7UqsfSi345'; // Pro Web - Fennmaradó
} }
} else if (pkg === 'Maintenance' || pkg === 'Fenntartás') { } else if (pkg === 'Maintenance' || pkg === 'Fenntartás') {
priceId = 'price_1SiIm025dc768V7UDFMZHDox'; // Éves fenntartás priceId = 'price_1SiMK525dc768V7UDxZugw0Y'; // Éves fenntartás
} }
// 4. Validate Logic // 4. Validate Logic