|
@@ -5,6 +5,7 @@ import { Badge } from "@/components/ui/badge";
|
|
|
import { PhoneCall, Plus, Settings, AlertTriangle, CheckCircle, Clock, Link, Shield, Loader2 } from "lucide-react";
|
|
import { PhoneCall, Plus, Settings, AlertTriangle, CheckCircle, Clock, Link, Shield, Loader2 } from "lucide-react";
|
|
|
import { API_URL } from "@/lib/config";
|
|
import { API_URL } from "@/lib/config";
|
|
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
|
|
|
+import { useTranslation } from "react-i18next";
|
|
|
|
|
|
|
|
interface PhoneNumber {
|
|
interface PhoneNumber {
|
|
|
id: string;
|
|
id: string;
|
|
@@ -102,6 +103,7 @@ const carriers = [
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
export function PhoneNumbersContent() {
|
|
export function PhoneNumbersContent() {
|
|
|
|
|
+ const { t } = useTranslation();
|
|
|
const [stores, setStores] = useState<Store[]>([]);
|
|
const [stores, setStores] = useState<Store[]>([]);
|
|
|
const [loading, setLoading] = useState(true);
|
|
const [loading, setLoading] = useState(true);
|
|
|
const [error, setError] = useState<string>("");
|
|
const [error, setError] = useState<string>("");
|
|
@@ -156,12 +158,12 @@ export function PhoneNumbersContent() {
|
|
|
|
|
|
|
|
const getStatusBadge = (store: Store) => {
|
|
const getStatusBadge = (store: Store) => {
|
|
|
if (!store.is_active) {
|
|
if (!store.is_active) {
|
|
|
- return { text: "Inactive", color: "bg-red-500" };
|
|
|
|
|
|
|
+ return { text: t('phoneNumbers.table.inactive'), color: "bg-red-500" };
|
|
|
}
|
|
}
|
|
|
if (!store.phone_numbers) {
|
|
if (!store.phone_numbers) {
|
|
|
- return { text: "No Phone Number", color: "bg-yellow-500" };
|
|
|
|
|
|
|
+ return { text: t('phoneNumbers.table.noPhoneNumber'), color: "bg-yellow-500" };
|
|
|
}
|
|
}
|
|
|
- return { text: "Active", color: "bg-green-500" };
|
|
|
|
|
|
|
+ return { text: t('phoneNumbers.table.active'), color: "bg-green-500" };
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const activeStoresCount = stores.filter(s => s.is_active && s.phone_numbers).length;
|
|
const activeStoresCount = stores.filter(s => s.is_active && s.phone_numbers).length;
|
|
@@ -170,23 +172,23 @@ export function PhoneNumbersContent() {
|
|
|
<div className="flex-1 space-y-6 p-8 bg-slate-900">
|
|
<div className="flex-1 space-y-6 p-8 bg-slate-900">
|
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center justify-between">
|
|
|
<div>
|
|
<div>
|
|
|
- <h2 className="text-3xl font-bold tracking-tight text-white">Phone Numbers</h2>
|
|
|
|
|
- <p className="text-slate-400">Manage phone numbers for your webshops</p>
|
|
|
|
|
|
|
+ <h2 className="text-3xl font-bold tracking-tight text-white">{t('phoneNumbers.title')}</h2>
|
|
|
|
|
+ <p className="text-slate-400">{t('phoneNumbers.subtitle')}</p>
|
|
|
</div>
|
|
</div>
|
|
|
<Button
|
|
<Button
|
|
|
className="bg-slate-600 hover:bg-slate-600 text-slate-400 cursor-not-allowed"
|
|
className="bg-slate-600 hover:bg-slate-600 text-slate-400 cursor-not-allowed"
|
|
|
disabled
|
|
disabled
|
|
|
>
|
|
>
|
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
|
- Add Phone Number
|
|
|
|
|
|
|
+ {t('phoneNumbers.addPhoneNumber')}
|
|
|
</Button>
|
|
</Button>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div className="space-y-6">
|
|
<div className="space-y-6">
|
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center justify-between">
|
|
|
- <h3 className="text-xl font-semibold text-white">Webshop Phone Numbers</h3>
|
|
|
|
|
|
|
+ <h3 className="text-xl font-semibold text-white">{t('phoneNumbers.webshopPhoneNumbers')}</h3>
|
|
|
<p className="text-slate-400">
|
|
<p className="text-slate-400">
|
|
|
- {loading ? "Loading..." : `${stores.length} webshop${stores.length !== 1 ? 's' : ''} • ${activeStoresCount} active number${activeStoresCount !== 1 ? 's' : ''}`}
|
|
|
|
|
|
|
+ {loading ? t('common.loading') : `${stores.length} ${stores.length !== 1 ? t('phoneNumbers.webshopsCountPlural') : t('phoneNumbers.webshopsCount')} • ${activeStoresCount} ${activeStoresCount !== 1 ? t('phoneNumbers.activeNumberPlural') : t('phoneNumbers.activeNumber')}`}
|
|
|
</p>
|
|
</p>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -204,7 +206,7 @@ export function PhoneNumbersContent() {
|
|
|
<CardContent className="p-8">
|
|
<CardContent className="p-8">
|
|
|
<div className="flex items-center justify-center gap-3">
|
|
<div className="flex items-center justify-center gap-3">
|
|
|
<Loader2 className="w-6 h-6 text-cyan-500 animate-spin" />
|
|
<Loader2 className="w-6 h-6 text-cyan-500 animate-spin" />
|
|
|
- <span className="text-slate-400">Loading stores and phone numbers...</span>
|
|
|
|
|
|
|
+ <span className="text-slate-400">{t('phoneNumbers.loadingStores')}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</CardContent>
|
|
</CardContent>
|
|
|
</Card>
|
|
</Card>
|
|
@@ -213,10 +215,10 @@ export function PhoneNumbersContent() {
|
|
|
<CardContent className="p-8">
|
|
<CardContent className="p-8">
|
|
|
<div className="text-center">
|
|
<div className="text-center">
|
|
|
<PhoneCall className="w-12 h-12 text-slate-600 mx-auto mb-4" />
|
|
<PhoneCall className="w-12 h-12 text-slate-600 mx-auto mb-4" />
|
|
|
- <h3 className="text-white text-lg font-semibold mb-2">No webshops connected</h3>
|
|
|
|
|
- <p className="text-slate-400 mb-4">Connect a webshop first to see phone number assignments</p>
|
|
|
|
|
|
|
+ <h3 className="text-white text-lg font-semibold mb-2">{t('phoneNumbers.noWebshopsConnected')}</h3>
|
|
|
|
|
+ <p className="text-slate-400 mb-4">{t('phoneNumbers.noWebshopsSubtitle')}</p>
|
|
|
<Button className="bg-cyan-500 hover:bg-cyan-600 text-white" onClick={() => window.location.href = '/webshops'}>
|
|
<Button className="bg-cyan-500 hover:bg-cyan-600 text-white" onClick={() => window.location.href = '/webshops'}>
|
|
|
- Go to Webshops
|
|
|
|
|
|
|
+ {t('phoneNumbers.goToWebshops')}
|
|
|
</Button>
|
|
</Button>
|
|
|
</div>
|
|
</div>
|
|
|
</CardContent>
|
|
</CardContent>
|
|
@@ -228,12 +230,12 @@ export function PhoneNumbersContent() {
|
|
|
<table className="w-full">
|
|
<table className="w-full">
|
|
|
<thead className="border-b border-slate-700">
|
|
<thead className="border-b border-slate-700">
|
|
|
<tr className="text-left">
|
|
<tr className="text-left">
|
|
|
- <th className="p-4 text-slate-300 font-medium">Webshop</th>
|
|
|
|
|
- <th className="p-4 text-slate-300 font-medium">Phone Number</th>
|
|
|
|
|
- <th className="p-4 text-slate-300 font-medium">Country</th>
|
|
|
|
|
- <th className="p-4 text-slate-300 font-medium">Type</th>
|
|
|
|
|
- <th className="p-4 text-slate-300 font-medium">Status</th>
|
|
|
|
|
- <th className="p-4 text-slate-300 font-medium">Actions</th>
|
|
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.webshop')}</th>
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.phoneNumber')}</th>
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.country')}</th>
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.type')}</th>
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.status')}</th>
|
|
|
|
|
+ <th className="p-4 text-slate-300 font-medium">{t('phoneNumbers.table.actions')}</th>
|
|
|
</tr>
|
|
</tr>
|
|
|
</thead>
|
|
</thead>
|
|
|
<tbody>
|
|
<tbody>
|
|
@@ -253,7 +255,7 @@ export function PhoneNumbersContent() {
|
|
|
<div className="flex items-center gap-2">
|
|
<div className="flex items-center gap-2">
|
|
|
<PhoneCall className="w-4 h-4 text-slate-400" />
|
|
<PhoneCall className="w-4 h-4 text-slate-400" />
|
|
|
<span className={`text-sm ${phoneNumber ? "text-white font-mono" : "text-slate-500 italic"}`}>
|
|
<span className={`text-sm ${phoneNumber ? "text-white font-mono" : "text-slate-500 italic"}`}>
|
|
|
- {phoneNumber ? phoneNumber.phone_number : "Not assigned"}
|
|
|
|
|
|
|
+ {phoneNumber ? phoneNumber.phone_number : t('phoneNumbers.table.notAssigned')}
|
|
|
</span>
|
|
</span>
|
|
|
</div>
|
|
</div>
|
|
|
</td>
|
|
</td>
|
|
@@ -266,7 +268,7 @@ export function PhoneNumbersContent() {
|
|
|
variant={phoneNumber.price === 0 ? "default" : "secondary"}
|
|
variant={phoneNumber.price === 0 ? "default" : "secondary"}
|
|
|
className={phoneNumber.price === 0 ? "bg-green-600 text-white" : "bg-purple-600 text-white"}
|
|
className={phoneNumber.price === 0 ? "bg-green-600 text-white" : "bg-purple-600 text-white"}
|
|
|
>
|
|
>
|
|
|
- {phoneNumber.price === 0 ? "Free" : "Premium"}
|
|
|
|
|
|
|
+ {phoneNumber.price === 0 ? t('phoneNumbers.table.free') : t('phoneNumbers.table.premium')}
|
|
|
</Badge>
|
|
</Badge>
|
|
|
) : (
|
|
) : (
|
|
|
<span className="text-slate-500">-</span>
|
|
<span className="text-slate-500">-</span>
|
|
@@ -295,7 +297,7 @@ export function PhoneNumbersContent() {
|
|
|
disabled
|
|
disabled
|
|
|
>
|
|
>
|
|
|
<Plus className="w-4 h-4 mr-1" />
|
|
<Plus className="w-4 h-4 mr-1" />
|
|
|
- Assign
|
|
|
|
|
|
|
+ {t('phoneNumbers.table.assign')}
|
|
|
</Button>
|
|
</Button>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
@@ -313,10 +315,10 @@ export function PhoneNumbersContent() {
|
|
|
<div className="space-y-4 opacity-60">
|
|
<div className="space-y-4 opacity-60">
|
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center justify-between">
|
|
|
<div>
|
|
<div>
|
|
|
- <h3 className="text-xl font-semibold text-white">Bring Your Own Carrier</h3>
|
|
|
|
|
- <p className="text-slate-400">Feature coming soon - Connect your existing carrier account to use your own phone numbers</p>
|
|
|
|
|
|
|
+ <h3 className="text-xl font-semibold text-white">{t('phoneNumbers.byoc.title')}</h3>
|
|
|
|
|
+ <p className="text-slate-400">{t('phoneNumbers.byoc.subtitle')}</p>
|
|
|
</div>
|
|
</div>
|
|
|
- <Badge variant="outline" className="text-slate-400 border-slate-600">Coming Soon</Badge>
|
|
|
|
|
|
|
+ <Badge variant="outline" className="text-slate-400 border-slate-600">{t('phoneNumbers.byoc.comingSoon')}</Badge>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
<div className="grid gap-6 md:grid-cols-2">
|