Add missing translations for LocationsContent, Notifications, KYCFormRussia, TopBar
Some checks failed
Build Docker Image / build (push) Failing after 47s
Some checks failed
Build Docker Image / build (push) Failing after 47s
This commit is contained in:
@@ -4,13 +4,13 @@
|
||||
<!-- Company Section -->
|
||||
<div class="card bg-base-100 border border-base-300 shadow-sm">
|
||||
<div class="card-body gap-4">
|
||||
<h3 class="card-title text-base-content">Company details</h3>
|
||||
<h3 class="card-title text-base-content">{{ t('kycRussia.form.companyDetails') }}</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<!-- Company search with DADATA -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">
|
||||
Organization search
|
||||
{{ t('kycRussia.form.organizationSearch') }}
|
||||
</label>
|
||||
<CompanySearchRussia v-model="formData.company" @select="onCompanySelect" />
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
<!-- Company details (auto-filled from DADATA) -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">INN</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.inn') }}</label>
|
||||
<input
|
||||
v-model="formData.company.inn"
|
||||
class="input input-bordered w-full"
|
||||
@@ -26,7 +26,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">KPP</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.kpp') }}</label>
|
||||
<input
|
||||
v-model="formData.company.kpp"
|
||||
class="input input-bordered w-full"
|
||||
@@ -36,7 +36,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">OGRN</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.ogrn') }}</label>
|
||||
<input
|
||||
v-model="formData.company.ogrn"
|
||||
class="input input-bordered w-full"
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">Address</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.address') }}</label>
|
||||
<textarea
|
||||
v-model="formData.company.address"
|
||||
class="textarea textarea-bordered w-full min-h-[120px]"
|
||||
@@ -60,13 +60,13 @@
|
||||
<!-- Bank Section -->
|
||||
<div class="card bg-base-100 border border-base-300 shadow-sm">
|
||||
<div class="card-body gap-4">
|
||||
<h3 class="card-title text-base-content">Bank details</h3>
|
||||
<h3 class="card-title text-base-content">{{ t('kycRussia.form.bankDetails') }}</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<!-- Bank search with DADATA -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">
|
||||
Bank search
|
||||
{{ t('kycRussia.form.bankSearch') }}
|
||||
</label>
|
||||
<BankSearchRussia v-model="formData.bank" @select="onBankSelect" />
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@
|
||||
<!-- Bank details -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">BIC</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.bic') }}</label>
|
||||
<input
|
||||
v-model="formData.bank.bik"
|
||||
class="input input-bordered w-full"
|
||||
@@ -82,7 +82,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">Corr. account</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.corrAccount') }}</label>
|
||||
<input
|
||||
v-model="formData.bank.correspondentAccount"
|
||||
class="input input-bordered w-full"
|
||||
@@ -97,41 +97,41 @@
|
||||
<!-- Contact Section -->
|
||||
<div class="card bg-base-100 border border-base-300 shadow-sm">
|
||||
<div class="card-body gap-4">
|
||||
<h3 class="card-title text-base-content">Contact details</h3>
|
||||
<h3 class="card-title text-base-content">{{ t('kycRussia.form.contactDetails') }}</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">
|
||||
Contact person *
|
||||
{{ t('kycRussia.form.contactPerson') }} *
|
||||
</label>
|
||||
<input
|
||||
v-model="formData.contact.person"
|
||||
type="text"
|
||||
required
|
||||
class="input input-bordered w-full"
|
||||
placeholder="Full name of company representative"
|
||||
:placeholder="t('kycRussia.form.placeholders.contactPerson')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">Email *</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.email') }} *</label>
|
||||
<input
|
||||
v-model="formData.contact.email"
|
||||
type="email"
|
||||
required
|
||||
class="input input-bordered w-full"
|
||||
placeholder="email@company.ru"
|
||||
:placeholder="t('kycRussia.form.placeholders.email')"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">Phone *</label>
|
||||
<label class="block text-sm font-medium text-base-content mb-2">{{ t('kycRussia.form.phone') }} *</label>
|
||||
<input
|
||||
v-model="formData.contact.phone"
|
||||
type="tel"
|
||||
required
|
||||
class="input input-bordered w-full"
|
||||
placeholder="+7 (xxx) xxx-xx-xx"
|
||||
:placeholder="t('kycRussia.form.placeholders.phone')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -146,7 +146,7 @@
|
||||
:disabled="loading || !isFormValid"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
{{ loading ? 'Sending...' : 'Submit for review' }}
|
||||
{{ loading ? t('kycRussia.form.sending') : t('kycRussia.form.submit') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -154,6 +154,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
|
||||
const emit = defineEmits<{
|
||||
submit: [data: any]
|
||||
}>()
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
<Stack gap="8">
|
||||
<!-- My addresses (for authenticated users) -->
|
||||
<Stack v-if="isAuthenticated && teamAddresses?.length" gap="4">
|
||||
<PageHeader title="My addresses">
|
||||
<PageHeader :title="t('locations.myAddresses')">
|
||||
<template #actions>
|
||||
<NuxtLink
|
||||
:to="localePath('/clientarea/addresses')"
|
||||
class="btn btn-sm btn-ghost gap-2"
|
||||
>
|
||||
<Icon name="lucide:settings" size="16" />
|
||||
Manage
|
||||
{{ t('locations.manage') }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</PageHeader>
|
||||
@@ -26,7 +26,7 @@
|
||||
<Stack direction="row" align="center" gap="2">
|
||||
<Icon name="lucide:map-pin" size="18" class="text-primary" />
|
||||
<Text size="base" weight="semibold">{{ addr.name }}</Text>
|
||||
<Pill v-if="addr.isDefault" variant="outline" size="sm">Default</Pill>
|
||||
<Pill v-if="addr.isDefault" variant="outline" size="sm">{{ t('locations.default') }}</Pill>
|
||||
</Stack>
|
||||
<Text tone="muted" size="sm">{{ addr.address }}</Text>
|
||||
</Stack>
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<!-- Terminals and logistics hubs -->
|
||||
<Stack gap="4">
|
||||
<PageHeader title="Terminals and logistics hubs" />
|
||||
<PageHeader :title="t('locations.terminalsAndHubs')" />
|
||||
|
||||
<div v-if="pending" class="flex items-center justify-center p-8">
|
||||
<span class="loading loading-spinner loading-lg" />
|
||||
@@ -44,15 +44,15 @@
|
||||
|
||||
<Alert v-else-if="error" variant="error">
|
||||
<Stack gap="2">
|
||||
<Heading :level="4" weight="semibold">Load error</Heading>
|
||||
<Button @click="refresh()">Try again</Button>
|
||||
<Heading :level="4" weight="semibold">{{ t('locations.loadError') }}</Heading>
|
||||
<Button @click="refresh()">{{ t('locations.tryAgain') }}</Button>
|
||||
</Stack>
|
||||
</Alert>
|
||||
|
||||
<EmptyState
|
||||
v-else-if="!locationsData?.length"
|
||||
title="No locations"
|
||||
description="Logistics hubs not added yet"
|
||||
:title="t('locations.noLocations')"
|
||||
:description="t('locations.noHubsDescription')"
|
||||
/>
|
||||
|
||||
<Grid v-else :cols="1" :md="2" :lg="3" :gap="4">
|
||||
@@ -71,6 +71,7 @@
|
||||
<script setup lang="ts">
|
||||
import { GetNodesDocument } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
const { t } = useI18n()
|
||||
const searchStore = useSearchStore()
|
||||
const { isAuthenticated } = useAuth()
|
||||
const localePath = useLocalePath()
|
||||
|
||||
@@ -47,14 +47,14 @@
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between px-6 py-4 border-b border-base-300">
|
||||
<h3 class="text-lg font-semibold text-base-content">Notifications</h3>
|
||||
<h3 class="text-lg font-semibold text-base-content">{{ t('notifications.title') }}</h3>
|
||||
<div class="flex items-center gap-3">
|
||||
<button
|
||||
v-if="unreadCount > 0"
|
||||
@click="handleMarkAllAsRead"
|
||||
class="text-sm text-primary hover:text-primary/80 font-medium"
|
||||
>
|
||||
Mark all as read
|
||||
{{ t('notifications.markAllAsRead') }}
|
||||
</button>
|
||||
<button
|
||||
@click="isOpen = false"
|
||||
@@ -82,7 +82,7 @@
|
||||
<svg class="w-12 h-12 text-base-content/30 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6 6 0 10-12 0v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
|
||||
</svg>
|
||||
<p class="text-sm text-base-content/60">No notifications</p>
|
||||
<p class="text-sm text-base-content/60">{{ t('notifications.empty') }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Notification Items -->
|
||||
@@ -107,7 +107,7 @@
|
||||
<!-- Content -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="text-sm text-base-content line-clamp-2">
|
||||
{{ notification.content || notification.payload?.body || 'New notification' }}
|
||||
{{ notification.content || notification.payload?.body || t('notifications.new') }}
|
||||
</p>
|
||||
<p class="mt-1 text-xs text-base-content/60">
|
||||
{{ formatTime(notification.createdAt) }}
|
||||
@@ -125,7 +125,7 @@
|
||||
@click="isOpen = false"
|
||||
class="text-xs text-primary hover:text-primary/80 font-medium"
|
||||
>
|
||||
All notifications
|
||||
{{ t('notifications.viewAll') }}
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,6 +136,8 @@
|
||||
<script setup lang="ts">
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
subscriberId: string
|
||||
}>()
|
||||
@@ -192,10 +194,10 @@ const formatTime = (dateString: string) => {
|
||||
const diffHours = Math.floor(diffMins / 60)
|
||||
const diffDays = Math.floor(diffHours / 24)
|
||||
|
||||
if (diffMins < 1) return 'Just now'
|
||||
if (diffMins < 60) return `${diffMins} min ago`
|
||||
if (diffHours < 24) return `${diffHours} h ago`
|
||||
if (diffDays < 7) return `${diffDays} d ago`
|
||||
if (diffMins < 1) return t('notifications.time.justNow')
|
||||
if (diffMins < 60) return t('notifications.time.minutesAgo', { n: diffMins })
|
||||
if (diffHours < 24) return t('notifications.time.hoursAgo', { n: diffHours })
|
||||
if (diffDays < 7) return t('notifications.time.daysAgo', { n: diffDays })
|
||||
|
||||
return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' })
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
tabindex="0"
|
||||
class="dropdown-content menu bg-base-100 rounded-box z-50 w-72 p-2 shadow-lg border border-base-300 mt-1"
|
||||
>
|
||||
<li class="menu-title"><span>Quick actions</span></li>
|
||||
<li><a @click="navigateToAction('/catalog')">Find materials</a></li>
|
||||
<li><a @click="navigateToAction('/clientarea/orders')">My orders</a></li>
|
||||
<li><a @click="navigateToAction('/clientarea/profile')">Profile settings</a></li>
|
||||
<li class="menu-title"><span>{{ t('topbar.quickActions') }}</span></li>
|
||||
<li><a @click="navigateToAction('/catalog')">{{ t('topbar.findMaterials') }}</a></li>
|
||||
<li><a @click="navigateToAction('/clientarea/orders')">{{ t('topbar.myOrders') }}</a></li>
|
||||
<li><a @click="navigateToAction('/clientarea/profile')">{{ t('topbar.profileSettings') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
<details>
|
||||
<summary>
|
||||
<Icon name="lucide:globe" size="16" />
|
||||
Language
|
||||
{{ t('topbar.language') }}
|
||||
</summary>
|
||||
<ul>
|
||||
<li v-for="loc in locales" :key="loc.code">
|
||||
@@ -161,7 +161,7 @@ defineProps<{
|
||||
}>()
|
||||
|
||||
const localePath = useLocalePath()
|
||||
const { locale, locales } = useI18n()
|
||||
const { t, locale, locales } = useI18n()
|
||||
const switchLocalePath = useSwitchLocalePath()
|
||||
const locationStore = useLocationStore()
|
||||
|
||||
|
||||
@@ -18,6 +18,29 @@
|
||||
"title": "Request sent successfully",
|
||||
"description": "Your verification request has been accepted. Result will be ready within 1-2 business days.",
|
||||
"cta": "View request status →"
|
||||
},
|
||||
"form": {
|
||||
"companyDetails": "Company details",
|
||||
"organizationSearch": "Organization search",
|
||||
"inn": "INN",
|
||||
"kpp": "KPP",
|
||||
"ogrn": "OGRN",
|
||||
"address": "Address",
|
||||
"bankDetails": "Bank details",
|
||||
"bankSearch": "Bank search",
|
||||
"bic": "BIC",
|
||||
"corrAccount": "Corr. account",
|
||||
"contactDetails": "Contact details",
|
||||
"contactPerson": "Contact person",
|
||||
"email": "Email",
|
||||
"phone": "Phone",
|
||||
"sending": "Sending...",
|
||||
"submit": "Submit for review",
|
||||
"placeholders": {
|
||||
"contactPerson": "Full name of company representative",
|
||||
"email": "email@company.ru",
|
||||
"phone": "+7 (xxx) xxx-xx-xx"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
"search_placeholder": "City name",
|
||||
"regions": "Federal Districts",
|
||||
"all_regions": "All Regions",
|
||||
"all_countries": "All countries"
|
||||
"all_countries": "All countries",
|
||||
"myAddresses": "My addresses",
|
||||
"manage": "Manage",
|
||||
"default": "Default",
|
||||
"terminalsAndHubs": "Terminals and logistics hubs",
|
||||
"loadError": "Load error",
|
||||
"tryAgain": "Try again",
|
||||
"noLocations": "No locations",
|
||||
"noHubsDescription": "Logistics hubs not added yet"
|
||||
}
|
||||
}
|
||||
|
||||
15
i18n/locales/en/notifications.json
Normal file
15
i18n/locales/en/notifications.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"markAllAsRead": "Mark all as read",
|
||||
"empty": "No notifications",
|
||||
"viewAll": "All notifications",
|
||||
"new": "New notification",
|
||||
"time": {
|
||||
"justNow": "Just now",
|
||||
"minutesAgo": "{n} min ago",
|
||||
"hoursAgo": "{n} h ago",
|
||||
"daysAgo": "{n} d ago"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
i18n/locales/en/topbar.json
Normal file
9
i18n/locales/en/topbar.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"topbar": {
|
||||
"quickActions": "Quick actions",
|
||||
"findMaterials": "Find materials",
|
||||
"myOrders": "My orders",
|
||||
"profileSettings": "Profile settings",
|
||||
"language": "Language"
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,29 @@
|
||||
"title": "Заявка успешно отправлена",
|
||||
"description": "Ваша заявка на верификацию принята. Результат будет готов в течение 1-2 рабочих дней.",
|
||||
"cta": "Посмотреть статус заявки →"
|
||||
},
|
||||
"form": {
|
||||
"companyDetails": "Данные компании",
|
||||
"organizationSearch": "Поиск организации",
|
||||
"inn": "ИНН",
|
||||
"kpp": "КПП",
|
||||
"ogrn": "ОГРН",
|
||||
"address": "Адрес",
|
||||
"bankDetails": "Банковские реквизиты",
|
||||
"bankSearch": "Поиск банка",
|
||||
"bic": "БИК",
|
||||
"corrAccount": "Корр. счёт",
|
||||
"contactDetails": "Контактные данные",
|
||||
"contactPerson": "Контактное лицо",
|
||||
"email": "Email",
|
||||
"phone": "Телефон",
|
||||
"sending": "Отправка...",
|
||||
"submit": "Отправить на проверку",
|
||||
"placeholders": {
|
||||
"contactPerson": "ФИО представителя компании",
|
||||
"email": "email@company.ru",
|
||||
"phone": "+7 (xxx) xxx-xx-xx"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
"search_placeholder": "Название города",
|
||||
"regions": "Федеральные округа",
|
||||
"all_regions": "Все регионы",
|
||||
"all_countries": "Все страны"
|
||||
"all_countries": "Все страны",
|
||||
"myAddresses": "Мои адреса",
|
||||
"manage": "Управление",
|
||||
"default": "По умолчанию",
|
||||
"terminalsAndHubs": "Терминалы и логистические хабы",
|
||||
"loadError": "Ошибка загрузки",
|
||||
"tryAgain": "Попробовать снова",
|
||||
"noLocations": "Нет локаций",
|
||||
"noHubsDescription": "Логистические хабы ещё не добавлены"
|
||||
}
|
||||
}
|
||||
|
||||
15
i18n/locales/ru/notifications.json
Normal file
15
i18n/locales/ru/notifications.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"notifications": {
|
||||
"title": "Уведомления",
|
||||
"markAllAsRead": "Отметить все как прочитанные",
|
||||
"empty": "Нет уведомлений",
|
||||
"viewAll": "Все уведомления",
|
||||
"new": "Новое уведомление",
|
||||
"time": {
|
||||
"justNow": "Только что",
|
||||
"minutesAgo": "{n} мин назад",
|
||||
"hoursAgo": "{n} ч назад",
|
||||
"daysAgo": "{n} д назад"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
i18n/locales/ru/topbar.json
Normal file
9
i18n/locales/ru/topbar.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"topbar": {
|
||||
"quickActions": "Быстрые действия",
|
||||
"findMaterials": "Найти материалы",
|
||||
"myOrders": "Мои заказы",
|
||||
"profileSettings": "Настройки профиля",
|
||||
"language": "Язык"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user