|
|
@@ -235,7 +235,7 @@ export function ManageStoreDataContent() {
|
|
|
} catch (error) {
|
|
|
console.error('Error fetching website data:', error);
|
|
|
toast({
|
|
|
- title: "Error",
|
|
|
+ title: t('common.error'),
|
|
|
description: "Failed to load website content data",
|
|
|
variant: "destructive"
|
|
|
});
|
|
|
@@ -447,8 +447,8 @@ export function ManageStoreDataContent() {
|
|
|
|
|
|
if (response.ok) {
|
|
|
toast({
|
|
|
- title: "Success",
|
|
|
- description: "Custom URL added successfully",
|
|
|
+ title: t('manageStoreData.website.toast.urlAddSuccess'),
|
|
|
+ description: t('manageStoreData.website.toast.urlAddSuccess'),
|
|
|
});
|
|
|
setNewCustomUrl("");
|
|
|
fetchCustomUrls();
|
|
|
@@ -458,8 +458,8 @@ export function ManageStoreDataContent() {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
toast({
|
|
|
- title: "Error",
|
|
|
- description: error.message || "Failed to add custom URL",
|
|
|
+ title: t('common.error'),
|
|
|
+ description: error.message || t('manageStoreData.website.toast.urlAddError'),
|
|
|
variant: "destructive"
|
|
|
});
|
|
|
}
|
|
|
@@ -487,8 +487,8 @@ export function ManageStoreDataContent() {
|
|
|
|
|
|
if (response.ok) {
|
|
|
toast({
|
|
|
- title: "Success",
|
|
|
- description: `Scheduled scraping ${enabled ? 'enabled' : 'disabled'}`,
|
|
|
+ title: t('common.success'),
|
|
|
+ description: enabled ? t('manageStoreData.website.toast.enableSuccess') : t('manageStoreData.website.toast.disableSuccess'),
|
|
|
});
|
|
|
fetchScraperStatus(); // Refresh status
|
|
|
} else {
|
|
|
@@ -497,8 +497,8 @@ export function ManageStoreDataContent() {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
toast({
|
|
|
- title: "Error",
|
|
|
- description: error.message || "Failed to update scheduling",
|
|
|
+ title: t('common.error'),
|
|
|
+ description: error.message || t('manageStoreData.website.toast.enableError'),
|
|
|
variant: "destructive"
|
|
|
});
|
|
|
}
|
|
|
@@ -600,7 +600,7 @@ export function ManageStoreDataContent() {
|
|
|
}
|
|
|
|
|
|
toast({
|
|
|
- title: "Category Updated",
|
|
|
+ title: t('common.success'),
|
|
|
description: `Category "${categoryName}" ${!currentExcluded ? 'excluded' : 'included'} successfully`,
|
|
|
});
|
|
|
|
|
|
@@ -610,7 +610,7 @@ export function ManageStoreDataContent() {
|
|
|
} catch (error) {
|
|
|
console.error('Error toggling category:', error);
|
|
|
toast({
|
|
|
- title: "Error",
|
|
|
+ title: t('common.error'),
|
|
|
description: 'Failed to update category',
|
|
|
variant: "destructive"
|
|
|
});
|
|
|
@@ -818,7 +818,7 @@ export function ManageStoreDataContent() {
|
|
|
variant={product.exclusion_reason === 'category' ? 'secondary' : 'destructive'}
|
|
|
className="text-xs"
|
|
|
>
|
|
|
- {product.exclusion_reason === 'category' ? 'By Category' : 'Individual'}
|
|
|
+ {product.exclusion_reason === 'category' ? t('manageStoreData.exclusionReasons.byCategory') : t('manageStoreData.exclusionReasons.individual')}
|
|
|
</Badge>
|
|
|
)}
|
|
|
</div>
|
|
|
@@ -906,7 +906,7 @@ export function ManageStoreDataContent() {
|
|
|
</TabsTrigger>
|
|
|
<TabsTrigger value="website" className="data-[state=active]:bg-slate-600 data-[state=active]:text-white">
|
|
|
<Globe className="w-4 h-4 mr-2" />
|
|
|
- Website Content
|
|
|
+ {t('manageStoreData.tabs.website')}
|
|
|
</TabsTrigger>
|
|
|
</TabsList>
|
|
|
|
|
|
@@ -916,7 +916,7 @@ export function ManageStoreDataContent() {
|
|
|
<div className="flex-1 relative">
|
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-slate-400" />
|
|
|
<Input
|
|
|
- placeholder={`Search ${activeTab}...`}
|
|
|
+ placeholder={t('manageStoreData.search.placeholder', { type: t('manageStoreData.search.products') })}
|
|
|
value={searchQuery}
|
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
|
className="pl-10 bg-slate-700 border-slate-600 text-white"
|
|
|
@@ -927,9 +927,9 @@ export function ManageStoreDataContent() {
|
|
|
<SelectValue />
|
|
|
</SelectTrigger>
|
|
|
<SelectContent className="bg-slate-700 border-slate-600 text-white">
|
|
|
- <SelectItem value="all">All Items</SelectItem>
|
|
|
- <SelectItem value="enabled">Enabled Only</SelectItem>
|
|
|
- <SelectItem value="disabled">Disabled Only</SelectItem>
|
|
|
+ <SelectItem value="all">{t('manageStoreData.filters.all')}</SelectItem>
|
|
|
+ <SelectItem value="enabled">{t('manageStoreData.filters.enabled')}</SelectItem>
|
|
|
+ <SelectItem value="disabled">{t('manageStoreData.filters.disabled')}</SelectItem>
|
|
|
</SelectContent>
|
|
|
</Select>
|
|
|
|
|
|
@@ -938,10 +938,10 @@ export function ManageStoreDataContent() {
|
|
|
<Select value={categoryFilter} onValueChange={(value) => setCategoryFilter(value)}>
|
|
|
<SelectTrigger className="w-[200px] bg-slate-700 border-slate-600 text-white">
|
|
|
<Tag className="w-4 h-4 mr-2" />
|
|
|
- <SelectValue placeholder="All Categories" />
|
|
|
+ <SelectValue placeholder={t('manageStoreData.filters.categories.placeholder')} />
|
|
|
</SelectTrigger>
|
|
|
<SelectContent className="bg-slate-700 border-slate-600">
|
|
|
- <SelectItem value="all">All Categories</SelectItem>
|
|
|
+ <SelectItem value="all">{t('manageStoreData.filters.allCategories')}</SelectItem>
|
|
|
{categories.map((cat) => (
|
|
|
<SelectItem key={cat.category_id} value={cat.category_id}>
|
|
|
<div className="flex items-center justify-between w-full gap-2">
|
|
|
@@ -966,7 +966,7 @@ export function ManageStoreDataContent() {
|
|
|
<div className="flex items-center justify-between mb-3">
|
|
|
<h3 className="text-white font-medium flex items-center gap-2">
|
|
|
<Tag className="w-4 h-4" />
|
|
|
- Category Management
|
|
|
+ {t('manageStoreData.categoryManagement.title')}
|
|
|
</h3>
|
|
|
</div>
|
|
|
<div className="flex flex-wrap gap-2">
|
|
|
@@ -988,7 +988,7 @@ export function ManageStoreDataContent() {
|
|
|
className="h-6 px-2 text-xs"
|
|
|
onClick={() => handleToggleCategory(cat.category_id, cat.category_name, cat.is_excluded)}
|
|
|
>
|
|
|
- {cat.is_excluded ? 'Include' : 'Exclude'}
|
|
|
+ {cat.is_excluded ? t('manageStoreData.categoryManagement.include') : t('manageStoreData.categoryManagement.exclude')}
|
|
|
</Button>
|
|
|
</div>
|
|
|
))}
|
|
|
@@ -999,14 +999,14 @@ export function ManageStoreDataContent() {
|
|
|
{/* Bulk Actions - Only show for products tab */}
|
|
|
{activeTab === "products" && selectedItems.size > 0 && (
|
|
|
<div className="flex gap-2 mb-4 p-3 bg-slate-700/50 rounded-lg">
|
|
|
- <span className="text-white mr-4">{selectedItems.size} items selected</span>
|
|
|
+ <span className="text-white mr-4">{t('manageStoreData.bulkActions.selectedCount', { count: selectedItems.size })}</span>
|
|
|
<Button
|
|
|
size="sm"
|
|
|
variant="outline"
|
|
|
onClick={() => handleBulkAction(true)}
|
|
|
className="border-cyan-500 text-cyan-500 hover:bg-cyan-500 hover:text-white"
|
|
|
>
|
|
|
- Enable Selected
|
|
|
+ {t('manageStoreData.bulkActions.enableSelected')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
size="sm"
|
|
|
@@ -1014,7 +1014,7 @@ export function ManageStoreDataContent() {
|
|
|
onClick={() => handleBulkAction(false)}
|
|
|
className="bg-slate-700 border-slate-600 text-white"
|
|
|
>
|
|
|
- Disable Selected
|
|
|
+ {t('manageStoreData.bulkActions.disableSelected')}
|
|
|
</Button>
|
|
|
</div>
|
|
|
)}
|
|
|
@@ -1027,26 +1027,26 @@ export function ManageStoreDataContent() {
|
|
|
variant="outline"
|
|
|
onClick={() => setConfirmDialog({
|
|
|
open: true,
|
|
|
- title: `Enable All ${activeTab}`,
|
|
|
- description: `Are you sure you want to enable all ${activeTab} for AI context? This will also clear all category exclusions.`,
|
|
|
+ title: t('manageStoreData.confirmDialog.enableAllTitle', { type: activeTab }),
|
|
|
+ description: t('manageStoreData.confirmDialog.enableAllDescription', { type: activeTab }),
|
|
|
action: handleEnableAll
|
|
|
})}
|
|
|
className="bg-slate-700 border-slate-600 text-white"
|
|
|
>
|
|
|
- Enable All
|
|
|
+ {t('manageStoreData.bulkActions.enableAll')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
size="sm"
|
|
|
variant="outline"
|
|
|
onClick={() => setConfirmDialog({
|
|
|
open: true,
|
|
|
- title: `Disable All ${activeTab}`,
|
|
|
- description: `Are you sure you want to disable all ${activeTab} from AI context?`,
|
|
|
+ title: t('manageStoreData.confirmDialog.disableAllTitle', { type: activeTab }),
|
|
|
+ description: t('manageStoreData.confirmDialog.disableAllDescription', { type: activeTab }),
|
|
|
action: handleDisableAll
|
|
|
})}
|
|
|
className="bg-slate-700 border-slate-600 text-white"
|
|
|
>
|
|
|
- Disable All
|
|
|
+ {t('manageStoreData.bulkActions.disableAll')}
|
|
|
</Button>
|
|
|
</div>
|
|
|
)}
|
|
|
@@ -1058,7 +1058,7 @@ export function ManageStoreDataContent() {
|
|
|
</div>
|
|
|
) : data.length === 0 ? (
|
|
|
<div className="text-center py-8 text-slate-400">
|
|
|
- No products found
|
|
|
+ {t('manageStoreData.table.noProducts')}
|
|
|
</div>
|
|
|
) : (
|
|
|
<div className="rounded-md border border-slate-700">
|
|
|
@@ -1071,10 +1071,10 @@ export function ManageStoreDataContent() {
|
|
|
onCheckedChange={handleSelectAll}
|
|
|
/>
|
|
|
</TableHead>
|
|
|
- <TableHead className="text-slate-300">Name</TableHead>
|
|
|
- <TableHead className="text-slate-300">SKU</TableHead>
|
|
|
- <TableHead className="text-slate-300">Category</TableHead>
|
|
|
- <TableHead className="text-slate-300">Status</TableHead>
|
|
|
+ <TableHead className="text-slate-300">{t('manageStoreData.table.name')}</TableHead>
|
|
|
+ <TableHead className="text-slate-300">{t('manageStoreData.table.sku')}</TableHead>
|
|
|
+ <TableHead className="text-slate-300">{t('manageStoreData.table.category')}</TableHead>
|
|
|
+ <TableHead className="text-slate-300">{t('manageStoreData.table.status')}</TableHead>
|
|
|
</TableRow>
|
|
|
</TableHeader>
|
|
|
<TableBody className="bg-slate-800">
|
|
|
@@ -1098,13 +1098,13 @@ export function ManageStoreDataContent() {
|
|
|
<CardHeader>
|
|
|
<CardTitle className="text-white flex items-center gap-2">
|
|
|
<Settings className="w-5 h-5" />
|
|
|
- Scraper Status
|
|
|
+ {t('manageStoreData.website.scraperStatus.title')}
|
|
|
</CardTitle>
|
|
|
</CardHeader>
|
|
|
<CardContent>
|
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
|
<div className="bg-slate-700/50 rounded-lg p-3">
|
|
|
- <div className="text-slate-400 text-sm">Status</div>
|
|
|
+ <div className="text-slate-400 text-sm">{t('manageStoreData.website.contentViewer.statusLabels.status')}</div>
|
|
|
<div className="text-white font-medium flex items-center gap-1">
|
|
|
{scraperStatus.status === 'active' ? (
|
|
|
<CheckCircle className="w-4 h-4 text-green-500" />
|
|
|
@@ -1115,22 +1115,22 @@ export function ManageStoreDataContent() {
|
|
|
</div>
|
|
|
</div>
|
|
|
<div className="bg-slate-700/50 rounded-lg p-3">
|
|
|
- <div className="text-slate-400 text-sm">URLs Found</div>
|
|
|
+ <div className="text-slate-400 text-sm">{t('manageStoreData.website.contentViewer.statusLabels.urlsFound')}</div>
|
|
|
<div className="text-white font-medium">{scraperStatus.total_urls_found}</div>
|
|
|
</div>
|
|
|
<div className="bg-slate-700/50 rounded-lg p-3">
|
|
|
- <div className="text-slate-400 text-sm">Content Items</div>
|
|
|
+ <div className="text-slate-400 text-sm">{t('manageStoreData.website.contentViewer.statusLabels.contentItems')}</div>
|
|
|
<div className="text-white font-medium">{scraperStatus.total_content_items}</div>
|
|
|
</div>
|
|
|
<div className="bg-slate-700/50 rounded-lg p-3">
|
|
|
- <div className="text-slate-400 text-sm">Scheduled</div>
|
|
|
+ <div className="text-slate-400 text-sm">{t('manageStoreData.website.contentViewer.statusLabels.scheduled')}</div>
|
|
|
<div className="text-white font-medium flex items-center gap-2">
|
|
|
<Switch
|
|
|
checked={scraperStatus.scheduled_enabled}
|
|
|
onCheckedChange={handleToggleScheduling}
|
|
|
className="data-[state=checked]:bg-cyan-500"
|
|
|
/>
|
|
|
- {scraperStatus.scheduled_enabled ? 'Enabled' : 'Disabled'}
|
|
|
+ {scraperStatus.scheduled_enabled ? t('manageStoreData.website.scraperStatus.enabled') : t('manageStoreData.website.scraperStatus.disabled')}
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1148,7 +1148,7 @@ export function ManageStoreDataContent() {
|
|
|
<div className="flex-1 relative">
|
|
|
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-slate-400" />
|
|
|
<Input
|
|
|
- placeholder="Search website content..."
|
|
|
+ placeholder={t('manageStoreData.website.contentViewer.searchPlaceholder')}
|
|
|
value={searchQuery}
|
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
|
className="pl-10 bg-slate-700 border-slate-600 text-white"
|
|
|
@@ -1159,7 +1159,7 @@ export function ManageStoreDataContent() {
|
|
|
<SelectValue />
|
|
|
</SelectTrigger>
|
|
|
<SelectContent className="bg-slate-700 border-slate-600 text-white">
|
|
|
- <SelectItem value="all">All Content</SelectItem>
|
|
|
+ <SelectItem value="all">{t('manageStoreData.website.contentViewer.filters.allContent')}</SelectItem>
|
|
|
<SelectItem value="faq">FAQ</SelectItem>
|
|
|
<SelectItem value="terms">Terms & Conditions</SelectItem>
|
|
|
<SelectItem value="shipping">Shipping Info</SelectItem>
|
|
|
@@ -1171,12 +1171,12 @@ export function ManageStoreDataContent() {
|
|
|
{/* Custom URLs Section */}
|
|
|
<Card className="bg-slate-800 border-slate-700">
|
|
|
<CardHeader>
|
|
|
- <CardTitle className="text-white">Custom URLs</CardTitle>
|
|
|
+ <CardTitle className="text-white">{t('manageStoreData.website.customUrls.title')}</CardTitle>
|
|
|
</CardHeader>
|
|
|
<CardContent>
|
|
|
<div className="flex gap-2 mb-4">
|
|
|
<Input
|
|
|
- placeholder="Enter custom URL to scrape..."
|
|
|
+ placeholder={t('manageStoreData.website.customUrls.urlPlaceholder')}
|
|
|
value={newCustomUrl}
|
|
|
onChange={(e) => setNewCustomUrl(e.target.value)}
|
|
|
className="flex-1 bg-slate-700 border-slate-600 text-white"
|
|
|
@@ -1198,7 +1198,7 @@ export function ManageStoreDataContent() {
|
|
|
disabled={!newCustomUrl}
|
|
|
>
|
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
|
- Add
|
|
|
+ {t('manageStoreData.website.customUrls.addButton')}
|
|
|
</Button>
|
|
|
</div>
|
|
|
|
|
|
@@ -1212,11 +1212,11 @@ export function ManageStoreDataContent() {
|
|
|
{customUrl.url}
|
|
|
</div>
|
|
|
<div className="text-slate-400 text-xs">
|
|
|
- Type: {customUrl.content_type} | Status: {customUrl.status || 'pending'}
|
|
|
+ {t('manageStoreData.website.customUrls.contentType')}: {customUrl.content_type} | Status: {customUrl.status || 'pending'}
|
|
|
</div>
|
|
|
</div>
|
|
|
<Badge variant={customUrl.enabled ? "default" : "secondary"}>
|
|
|
- {customUrl.enabled ? 'Enabled' : 'Disabled'}
|
|
|
+ {customUrl.enabled ? t('manageStoreData.website.scraperStatus.enabled') : t('manageStoreData.website.scraperStatus.disabled')}
|
|
|
</Badge>
|
|
|
</div>
|
|
|
))}
|
|
|
@@ -1228,12 +1228,12 @@ export function ManageStoreDataContent() {
|
|
|
{/* Scraped Content */}
|
|
|
<Card className="bg-slate-800 border-slate-700">
|
|
|
<CardHeader>
|
|
|
- <CardTitle className="text-white">Scraped Content ({scraperContent.length})</CardTitle>
|
|
|
+ <CardTitle className="text-white">{t('manageStoreData.website.contentViewer.title')} ({scraperContent.length})</CardTitle>
|
|
|
</CardHeader>
|
|
|
<CardContent>
|
|
|
{scraperContent.length === 0 ? (
|
|
|
<div className="text-center py-8 text-slate-400">
|
|
|
- No content found. The scraper will discover content automatically.
|
|
|
+ {t('manageStoreData.website.contentViewer.noContentDescription')}
|
|
|
</div>
|
|
|
) : (
|
|
|
<div className="space-y-4">
|
|
|
@@ -1243,7 +1243,7 @@ export function ManageStoreDataContent() {
|
|
|
<div className="flex-1">
|
|
|
<div className="text-white font-medium flex items-center gap-2">
|
|
|
<ExternalLink className="w-4 h-4" />
|
|
|
- {content.title || 'Untitled'}
|
|
|
+ {content.title || t('manageStoreData.website.contentViewer.untitled')}
|
|
|
</div>
|
|
|
<div className="text-cyan-400 text-sm break-all">{content.url}</div>
|
|
|
</div>
|
|
|
@@ -1256,7 +1256,7 @@ export function ManageStoreDataContent() {
|
|
|
</div>
|
|
|
<div className="text-slate-400 text-xs flex items-center gap-1">
|
|
|
<Clock className="w-3 h-3" />
|
|
|
- Scraped: {new Date(content.scraped_at).toLocaleString()}
|
|
|
+ {t('manageStoreData.website.contentViewer.scraped')}: {new Date(content.scraped_at).toLocaleString()}
|
|
|
</div>
|
|
|
</div>
|
|
|
))}
|
|
|
@@ -1273,7 +1273,7 @@ export function ManageStoreDataContent() {
|
|
|
{totalCount > 0 && (
|
|
|
<div className="flex items-center justify-between mt-6">
|
|
|
<div className="flex items-center gap-4">
|
|
|
- <Label className="text-slate-300">Items per page:</Label>
|
|
|
+ <Label className="text-slate-300">{t('manageStoreData.pagination.itemsPerPage')}</Label>
|
|
|
<Select value={pageSize.toString()} onValueChange={(value) => {
|
|
|
setPageSize(Number(value));
|
|
|
setPage(1);
|
|
|
@@ -1291,7 +1291,7 @@ export function ManageStoreDataContent() {
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
<span className="text-slate-400 text-sm">
|
|
|
- Page {page} of {totalPages} ({totalCount} total)
|
|
|
+ {t('manageStoreData.pagination.page')} {page} {t('manageStoreData.pagination.of')} {totalPages} ({t('manageStoreData.pagination.total', { count: totalCount })})
|
|
|
</span>
|
|
|
<Button
|
|
|
size="sm"
|
|
|
@@ -1328,7 +1328,7 @@ export function ManageStoreDataContent() {
|
|
|
</AlertDialogHeader>
|
|
|
<AlertDialogFooter>
|
|
|
<AlertDialogCancel className="bg-slate-700 text-white border-slate-600">
|
|
|
- Cancel
|
|
|
+ {t('manageStoreData.confirmDialog.cancel')}
|
|
|
</AlertDialogCancel>
|
|
|
<AlertDialogAction
|
|
|
onClick={() => {
|
|
|
@@ -1337,7 +1337,7 @@ export function ManageStoreDataContent() {
|
|
|
}}
|
|
|
className="bg-cyan-500 hover:bg-cyan-600 text-white"
|
|
|
>
|
|
|
- Confirm
|
|
|
+ {t('manageStoreData.confirmDialog.confirm')}
|
|
|
</AlertDialogAction>
|
|
|
</AlertDialogFooter>
|
|
|
</AlertDialogContent>
|