mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
feat: remove certificate verification page and related API, update landing page links
This commit is contained in:
@@ -308,27 +308,6 @@ export const licensingApi = baseApi
|
||||
}),
|
||||
|
||||
// ------------------------------------------------------------ licences
|
||||
/**
|
||||
* Public QR-code verification (US-PORTAL-008). No auth required —
|
||||
* the endpoint returns only what a verifier needs to trust the
|
||||
* document, never the holder's contact details.
|
||||
*/
|
||||
verifyCertificate: builder.query<
|
||||
{
|
||||
valid: boolean;
|
||||
reason?: string;
|
||||
certificateNumber?: string;
|
||||
licenseType?: string | null;
|
||||
companyName?: string | null;
|
||||
issueDate?: string;
|
||||
expiryDate?: string;
|
||||
status?: string;
|
||||
},
|
||||
string
|
||||
>({
|
||||
query: (code) => ({ url: `/licenses/verify/${code}` }),
|
||||
}),
|
||||
|
||||
/** The licence register for enforcement officers. */
|
||||
getLicenses: builder.query<
|
||||
Paginated<IssuedLicense>,
|
||||
@@ -769,7 +748,6 @@ export const licensingApi = baseApi
|
||||
});
|
||||
|
||||
export const {
|
||||
useVerifyCertificateQuery,
|
||||
useGetLicenseTypesQuery,
|
||||
useGetLicenseCategoriesQuery,
|
||||
useUpdateLicenseFeesMutation,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@@ -16,13 +17,14 @@ import {
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconActivity,
|
||||
IconAnchor,
|
||||
IconAward,
|
||||
IconBriefcase,
|
||||
IconCertificate,
|
||||
IconClipboardCheck,
|
||||
IconFileCertificate,
|
||||
IconGavel,
|
||||
IconLanguage,
|
||||
IconMail,
|
||||
IconMapPin,
|
||||
IconPhone,
|
||||
@@ -30,11 +32,11 @@ import {
|
||||
IconShip,
|
||||
IconShieldCheck,
|
||||
IconUserCheck,
|
||||
IconUserCircle,
|
||||
IconUsers,
|
||||
} from '@tabler/icons-react';
|
||||
import { LanguageSwitcher } from '../layout/LanguageSwitcher';
|
||||
import { ColorSchemeToggle } from '../layout/ColorSchemeToggle';
|
||||
import { EmptyState } from '../feedback/EmptyState';
|
||||
import './landing.css';
|
||||
|
||||
export interface LandingPageProps {
|
||||
@@ -45,17 +47,46 @@ export interface LandingPageProps {
|
||||
primaryHref: string;
|
||||
/** Renders the "Create account" CTA only when set. Portal passes '/signup'; backoffice omits it (enableSignup: false). */
|
||||
signupHref?: string;
|
||||
/** Renders the Certificate Verification nav item + quick-access tile only when set. Portal passes '/verify'; backoffice omits it. */
|
||||
verifyHref?: string;
|
||||
supportedLanguages?: readonly string[];
|
||||
}
|
||||
|
||||
const HEADER_HEIGHT = 72;
|
||||
|
||||
// Sections with a nav item, in page order — drives the scrollspy underline.
|
||||
const NAV_SECTION_IDS = ['home', 'about', 'services', 'system', 'contact'] as const;
|
||||
|
||||
/** Tracks which nav section is currently under the sticky header, so the
|
||||
* header can underline it. Native IntersectionObserver — no scroll listener. */
|
||||
function useActiveSection(ids: readonly string[]) {
|
||||
const [active, setActive] = useState<string>(ids[0]);
|
||||
|
||||
useEffect(() => {
|
||||
const elements = ids
|
||||
.map((id) => document.getElementById(id))
|
||||
.filter((el): el is HTMLElement => el !== null);
|
||||
if (!elements.length) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
const visible = entries.filter((entry) => entry.isIntersecting);
|
||||
if (visible.length === 0) return;
|
||||
const topMost = visible.reduce((a, b) => (a.boundingClientRect.top <= b.boundingClientRect.top ? a : b));
|
||||
setActive(topMost.target.id);
|
||||
},
|
||||
// Counts a section only once it has cleared the sticky header, and only
|
||||
// while it's still in the top 30% of the viewport.
|
||||
{ rootMargin: `-${HEADER_HEIGHT}px 0px -70% 0px`, threshold: 0 },
|
||||
);
|
||||
elements.forEach((el) => observer.observe(el));
|
||||
return () => observer.disconnect();
|
||||
}, [ids]);
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
export function LandingPage({
|
||||
primaryHref,
|
||||
signupHref,
|
||||
verifyHref,
|
||||
supportedLanguages = ['en', 'am'],
|
||||
}: LandingPageProps) {
|
||||
const { t } = useTranslation();
|
||||
@@ -90,18 +121,17 @@ export function LandingPage({
|
||||
isAuthed={isAuthed}
|
||||
primaryHref={primaryHref}
|
||||
signupHref={signupHref}
|
||||
verifyHref={verifyHref}
|
||||
supportedLanguages={supportedLanguages}
|
||||
/>
|
||||
|
||||
<main id="main">
|
||||
<Hero primaryHref={primaryHref} isAuthed={isAuthed} />
|
||||
<About />
|
||||
<QuickAccess verifyHref={verifyHref} />
|
||||
<QuickAccess />
|
||||
<Services />
|
||||
<Roles />
|
||||
<HowItWorks />
|
||||
<Notices />
|
||||
<SystemHighlights />
|
||||
<Faq />
|
||||
<Contact />
|
||||
</main>
|
||||
@@ -111,15 +141,29 @@ export function LandingPage({
|
||||
);
|
||||
}
|
||||
|
||||
function NavAnchor({ href, children }: { href: string; children: React.ReactNode }) {
|
||||
function NavAnchor({
|
||||
href,
|
||||
active,
|
||||
children,
|
||||
}: {
|
||||
href: string;
|
||||
active?: boolean;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Anchor
|
||||
href={href}
|
||||
underline="never"
|
||||
c="var(--mantine-color-text)"
|
||||
aria-current={active ? 'true' : undefined}
|
||||
c={active ? 'var(--mantine-primary-color-filled)' : 'var(--mantine-color-text)'}
|
||||
fw={500}
|
||||
fz="sm"
|
||||
style={{ whiteSpace: 'nowrap' }}
|
||||
style={{
|
||||
whiteSpace: 'nowrap',
|
||||
paddingBottom: 4,
|
||||
borderBottom: active ? '2px solid var(--mantine-primary-color-filled)' : '2px solid transparent',
|
||||
transition: 'color 120ms ease, border-color 120ms ease',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Anchor>
|
||||
@@ -130,16 +174,15 @@ function Header({
|
||||
isAuthed,
|
||||
primaryHref,
|
||||
signupHref,
|
||||
verifyHref,
|
||||
supportedLanguages,
|
||||
}: {
|
||||
isAuthed: boolean;
|
||||
primaryHref: string;
|
||||
signupHref?: string;
|
||||
verifyHref?: string;
|
||||
supportedLanguages: readonly string[];
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const activeSection = useActiveSection(NAV_SECTION_IDS);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -155,7 +198,7 @@ function Header({
|
||||
>
|
||||
<Container size="xl" h="100%">
|
||||
<Group h="100%" justify="space-between" wrap="nowrap" gap="md">
|
||||
<Anchor href="#main" underline="never" c="var(--mantine-color-text)">
|
||||
<Anchor href="#home" underline="never" c="var(--mantine-color-text)">
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
<Box component="img" src="/ema-logo.png" alt="" w={34} h={34} style={{ objectFit: 'contain' }} />
|
||||
<Text fw={700} fz="sm" visibleFrom="sm">
|
||||
@@ -165,24 +208,21 @@ function Header({
|
||||
</Anchor>
|
||||
|
||||
<Group gap="lg" wrap="nowrap" visibleFrom="md" component="nav" aria-label={t('landing.nav.home')}>
|
||||
<NavAnchor href="#main">{t('landing.nav.home')}</NavAnchor>
|
||||
<NavAnchor href="#about">{t('landing.nav.about')}</NavAnchor>
|
||||
<NavAnchor href="#services">{t('landing.nav.services')}</NavAnchor>
|
||||
<NavAnchor href="#notices">{t('landing.nav.notices')}</NavAnchor>
|
||||
{verifyHref && (
|
||||
<Anchor
|
||||
component={Link}
|
||||
to={verifyHref}
|
||||
underline="never"
|
||||
c="var(--mantine-color-text)"
|
||||
fw={500}
|
||||
fz="sm"
|
||||
style={{ whiteSpace: 'nowrap' }}
|
||||
>
|
||||
{t('landing.nav.verify')}
|
||||
</Anchor>
|
||||
)}
|
||||
<NavAnchor href="#contact">{t('landing.nav.contact')}</NavAnchor>
|
||||
<NavAnchor href="#home" active={activeSection === 'home'}>
|
||||
{t('landing.nav.home')}
|
||||
</NavAnchor>
|
||||
<NavAnchor href="#about" active={activeSection === 'about'}>
|
||||
{t('landing.nav.about')}
|
||||
</NavAnchor>
|
||||
<NavAnchor href="#services" active={activeSection === 'services'}>
|
||||
{t('landing.nav.services')}
|
||||
</NavAnchor>
|
||||
<NavAnchor href="#system" active={activeSection === 'system'}>
|
||||
{t('landing.nav.system')}
|
||||
</NavAnchor>
|
||||
<NavAnchor href="#contact" active={activeSection === 'contact'}>
|
||||
{t('landing.nav.contact')}
|
||||
</NavAnchor>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
@@ -217,6 +257,8 @@ function Hero({ primaryHref, isAuthed }: { primaryHref: string; isAuthed: boolea
|
||||
|
||||
return (
|
||||
<Box
|
||||
id="home"
|
||||
component="section"
|
||||
style={{
|
||||
background: theme.other?.heroGradient as string,
|
||||
color: 'white',
|
||||
@@ -340,19 +382,13 @@ function QuickAccessCard({
|
||||
);
|
||||
}
|
||||
|
||||
function QuickAccess({ verifyHref }: { verifyHref?: string }) {
|
||||
function QuickAccess() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Box id="quick-access" component="section" py={72} style={{ background: 'var(--mantine-color-default-hover)' }}>
|
||||
<Container size="xl">
|
||||
<SectionHeading title={t('landing.quickAccess.title')} subtitle={t('landing.quickAccess.subtitle')} />
|
||||
<SimpleGrid cols={{ base: 1, sm: 3 }} spacing="lg">
|
||||
<QuickAccessCard
|
||||
icon={IconFileCertificate}
|
||||
title={t('landing.quickAccess.verify.title')}
|
||||
description={t('landing.quickAccess.verify.description')}
|
||||
href={verifyHref}
|
||||
/>
|
||||
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
|
||||
<QuickAccessCard
|
||||
icon={IconShip}
|
||||
title={t('landing.quickAccess.vesselRegistration.title')}
|
||||
@@ -374,7 +410,6 @@ const SERVICE_ICONS = {
|
||||
vesselRegistration: IconShip,
|
||||
licensing: IconBriefcase,
|
||||
examinations: IconSchool,
|
||||
certificateVerification: IconCertificate,
|
||||
waivers: IconShieldCheck,
|
||||
} as const;
|
||||
|
||||
@@ -474,25 +509,44 @@ function HowItWorks() {
|
||||
);
|
||||
}
|
||||
|
||||
function Notices() {
|
||||
const SYSTEM_ICONS = {
|
||||
secure: IconShieldCheck,
|
||||
bilingual: IconLanguage,
|
||||
tracking: IconActivity,
|
||||
singleAccount: IconUserCircle,
|
||||
} as const;
|
||||
|
||||
function SystemHighlights() {
|
||||
const { t } = useTranslation();
|
||||
const items = Object.keys(SYSTEM_ICONS) as (keyof typeof SYSTEM_ICONS)[];
|
||||
return (
|
||||
<Box id="notices" component="section" py={72} style={{ background: 'var(--mantine-color-default-hover)' }}>
|
||||
<Box id="system" component="section" py={72} style={{ background: 'var(--mantine-color-default-hover)' }}>
|
||||
<Container size="xl">
|
||||
<SectionHeading title={t('landing.notices.title')} subtitle={t('landing.notices.subtitle')} />
|
||||
<Box maw={560} mx="auto">
|
||||
<EmptyState
|
||||
icon={IconAnchor}
|
||||
title={t('landing.notices.emptyTitle')}
|
||||
description={t('landing.notices.emptyDescription')}
|
||||
/>
|
||||
</Box>
|
||||
<SectionHeading title={t('landing.system.title')} subtitle={t('landing.system.subtitle')} />
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
|
||||
{items.map((key) => {
|
||||
const Icon = SYSTEM_ICONS[key];
|
||||
return (
|
||||
<Paper key={key} withBorder radius="lg" p="lg" ta="center">
|
||||
<Stack gap="sm" align="center">
|
||||
<ThemeIcon size={48} radius="xl" variant="light">
|
||||
<Icon size={24} />
|
||||
</ThemeIcon>
|
||||
<Text fw={600}>{t(`landing.system.items.${key}.title`)}</Text>
|
||||
<Text c="dimmed" fz="sm">
|
||||
{t(`landing.system.items.${key}.description`)}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Container>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const FAQ_KEYS = ['whatIsPortal', 'whoCanUse', 'howToApply', 'howToVerify', 'isFree'] as const;
|
||||
const FAQ_KEYS = ['whatIsPortal', 'whoCanUse', 'howToApply', 'isFree'] as const;
|
||||
|
||||
function Faq() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -17,8 +17,7 @@ export const landingEn = {
|
||||
home: 'Home',
|
||||
about: 'About EMA',
|
||||
services: 'Services',
|
||||
notices: 'Maritime Notices',
|
||||
verify: 'Certificate Verification',
|
||||
system: 'Our System',
|
||||
contact: 'Contact',
|
||||
},
|
||||
|
||||
@@ -52,10 +51,6 @@ export const landingEn = {
|
||||
quickAccess: {
|
||||
title: 'Quick Access',
|
||||
subtitle: 'The most requested services, one click away.',
|
||||
verify: {
|
||||
title: 'Certificate Verification',
|
||||
description: 'Confirm a seafarer certificate or licence is genuine and current.',
|
||||
},
|
||||
vesselRegistration: {
|
||||
title: 'Vessel Registration',
|
||||
description: 'Register a vessel or transfer ownership.',
|
||||
@@ -89,10 +84,6 @@ export const landingEn = {
|
||||
title: 'Examinations',
|
||||
description: 'Sit competency examinations and track your results as part of certification.',
|
||||
},
|
||||
certificateVerification: {
|
||||
title: 'Certificate Verification',
|
||||
description: 'Let employers, port authorities and the public verify any EMA-issued certificate instantly.',
|
||||
},
|
||||
waivers: {
|
||||
title: 'Waivers',
|
||||
description: 'Apply for a maritime waiver where standard requirements do not apply.',
|
||||
@@ -133,11 +124,27 @@ export const landingEn = {
|
||||
},
|
||||
},
|
||||
|
||||
notices: {
|
||||
title: 'Maritime Notices',
|
||||
subtitle: 'Official notices to seafarers, vessel owners and operators.',
|
||||
emptyTitle: 'No notices published yet',
|
||||
emptyDescription: 'Check back here for official updates from EMA.',
|
||||
system: {
|
||||
title: 'A Modern Digital System',
|
||||
subtitle: 'Built to make maritime services faster, safer and accessible from anywhere.',
|
||||
items: {
|
||||
secure: {
|
||||
title: 'Secure & Verified',
|
||||
description: 'Every application and certificate is digitally recorded and verifiable.',
|
||||
},
|
||||
bilingual: {
|
||||
title: 'Bilingual by Design',
|
||||
description: 'Use the system fully in English or Amharic — switch anytime.',
|
||||
},
|
||||
tracking: {
|
||||
title: 'Real-Time Tracking',
|
||||
description: 'Follow your application from submission to approval, step by step.',
|
||||
},
|
||||
singleAccount: {
|
||||
title: 'One Account, Every Service',
|
||||
description: 'Register once and access all EMA licensing and certification services.',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
faq: {
|
||||
@@ -146,7 +153,7 @@ export const landingEn = {
|
||||
whatIsPortal: {
|
||||
question: 'What is the EMA portal?',
|
||||
answer:
|
||||
"The EMA portal is the Ethiopian Maritime Authority's official digital system for seafarer registration, vessel registration, licensing, and certificate verification.",
|
||||
"The EMA portal is the Ethiopian Maritime Authority's official digital system for seafarer registration, vessel registration and licensing.",
|
||||
},
|
||||
whoCanUse: {
|
||||
question: 'Who can use this portal?',
|
||||
@@ -158,11 +165,6 @@ export const landingEn = {
|
||||
answer:
|
||||
'Create an account, select your role, and follow the application wizard for the licence or certificate you need. You can track its status at any time.',
|
||||
},
|
||||
howToVerify: {
|
||||
question: 'How do I verify a certificate?',
|
||||
answer:
|
||||
'Use Certificate Verification and enter the certificate reference or scan its QR code. No account is required.',
|
||||
},
|
||||
isFree: {
|
||||
question: 'Is registration free?',
|
||||
answer:
|
||||
@@ -196,8 +198,7 @@ export const landingAm: LandingCopy = {
|
||||
home: 'ዋና ገጽ',
|
||||
about: 'ስለ ባለስልጣኑ',
|
||||
services: 'አገልግሎቶች',
|
||||
notices: 'የባህር ማስታወቂያዎች',
|
||||
verify: 'የምስክር ወረቀት ማረጋገጫ',
|
||||
system: 'ስርዓታችን',
|
||||
contact: 'እኛን ያግኙ',
|
||||
},
|
||||
|
||||
@@ -231,10 +232,6 @@ export const landingAm: LandingCopy = {
|
||||
quickAccess: {
|
||||
title: 'ፈጣን መዳረሻ',
|
||||
subtitle: 'በብዛት የሚፈለጉ አገልግሎቶች፣ በአንድ ቦታ።',
|
||||
verify: {
|
||||
title: 'የምስክር ወረቀት ማረጋገጫ',
|
||||
description: 'የመርከበኛ ምስክር ወረቀት ወይም ፈቃድ ትክክለኛ እና የሚሰራ መሆኑን ያረጋግጡ።',
|
||||
},
|
||||
vesselRegistration: {
|
||||
title: 'የመርከብ ምዝገባ',
|
||||
description: 'መርከብ ይመዝገቡ ወይም ባለቤትነት ያስተላልፉ።',
|
||||
@@ -266,10 +263,6 @@ export const landingAm: LandingCopy = {
|
||||
title: 'ፈተናዎች',
|
||||
description: 'የብቃት ፈተናዎችን ይውሰዱ እንዲሁም ውጤቶችዎን እንደ ማረጋገጫ ሂደት አካል ይከታተሉ።',
|
||||
},
|
||||
certificateVerification: {
|
||||
title: 'የምስክር ወረቀት ማረጋገጫ',
|
||||
description: 'ቀጣሪዎች፣ የወደብ ባለስልጣናትና ህዝብ ማንኛውንም በባለስልጣኑ የተሰጠ ምስክር ወረቀት ወዲያውኑ እንዲያረጋግጡ ያስችላል።',
|
||||
},
|
||||
waivers: {
|
||||
title: 'ነፃ ፈቃዶች',
|
||||
description: 'መደበኛ መስፈርቶች በማይሟሉበት ጊዜ ለባህር ትራንስፖርት ነፃ ፈቃድ ያመልክቱ።',
|
||||
@@ -310,11 +303,27 @@ export const landingAm: LandingCopy = {
|
||||
},
|
||||
},
|
||||
|
||||
notices: {
|
||||
title: 'የባህር ማስታወቂያዎች',
|
||||
subtitle: 'ለመርከበኞች፣ ለመርከብ ባለቤቶችና ለኦፕሬተሮች የተሰጡ ማስታወቂያዎች።',
|
||||
emptyTitle: 'እስካሁን የወጣ ማስታወቂያ የለም',
|
||||
emptyDescription: 'አዲስ መረጃ ሲኖር እዚህ ያገኙታል።',
|
||||
system: {
|
||||
title: 'ዘመናዊ ዲጂታል ስርዓት',
|
||||
subtitle: 'የባህር አገልግሎቶችን ፈጣን፣ ደህንነቱ የተጠበቀና ከየትኛውም ቦታ ተደራሽ ለማድረግ የተዘጋጀ።',
|
||||
items: {
|
||||
secure: {
|
||||
title: 'ደህንነቱ የተጠበቀ እና የተረጋገጠ',
|
||||
description: 'እያንዳንዱ ማመልከቻና ምስክር ወረቀት በዲጂታል መልኩ ተመዝግቦ ሊረጋገጥ የሚችል ነው።',
|
||||
},
|
||||
bilingual: {
|
||||
title: 'በሁለት ቋንቋ የተዘጋጀ',
|
||||
description: 'ስርዓቱን ሙሉ በሙሉ በአማርኛ ወይም በእንግሊዝኛ ይጠቀሙ — በማንኛውም ጊዜ ይቀይሩ።',
|
||||
},
|
||||
tracking: {
|
||||
title: 'የቀጥታ ሁኔታ ክትትል',
|
||||
description: 'ማመልከቻዎን ከማስገባት እስከ ማጽደቅ ደረጃ በደረጃ ይከታተሉ።',
|
||||
},
|
||||
singleAccount: {
|
||||
title: 'አንድ መለያ፣ ሁሉም አገልግሎት',
|
||||
description: 'አንድ ጊዜ ይመዝገቡና ሁሉንም የEMA ፈቃድና የምስክር ወረቀት አገልግሎቶች ይድረሱ።',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
faq: {
|
||||
@@ -323,7 +332,7 @@ export const landingAm: LandingCopy = {
|
||||
whatIsPortal: {
|
||||
question: 'EMA ፖርታል ምንድን ነው?',
|
||||
answer:
|
||||
'EMA ፖርታል የኢትዮጵያ ማሪታይም ባለስልጣን ለመርከበኛ ምዝገባ፣ ለመርከብ ምዝገባ፣ ፈቃድና ለምስክር ወረቀት ማረጋገጫ የሚጠቀምበት ዲጂታል ስርዓት ነው።',
|
||||
'EMA ፖርታል የኢትዮጵያ ማሪታይም ባለስልጣን ለመርከበኛ ምዝገባ፣ ለመርከብ ምዝገባና ፈቃድ የሚጠቀምበት ዲጂታል ስርዓት ነው።',
|
||||
},
|
||||
whoCanUse: {
|
||||
question: 'ይህን ፖርታል ማን ሊጠቀም ይችላል?',
|
||||
@@ -334,10 +343,6 @@ export const landingAm: LandingCopy = {
|
||||
answer:
|
||||
'መለያ ይፍጠሩ፣ ሚናዎን ይምረጡ፣ እንዲሁም የሚያስፈልግዎትን ፈቃድ ወይም ምስክር ወረቀት ደረጃዎች ይከተሉ። ሁኔታውን በማንኛውም ጊዜ መከታተል ይችላሉ።',
|
||||
},
|
||||
howToVerify: {
|
||||
question: 'ምስክር ወረቀት እንዴት አረጋግጣለሁ?',
|
||||
answer: 'የምስክር ወረቀት ማረጋገጫን ይክፈቱና የምስክር ወረቀቱን ቁጥር ያስገቡ ወይም QR ኮዱን ያንብቡ። መለያ አያስፈልግም።',
|
||||
},
|
||||
isFree: {
|
||||
question: 'ምዝገባ ነፃ ነው?',
|
||||
answer: 'የፖርታል መለያ መክፈት ነፃ ነው። ለተወሰኑ ፈቃዶችና ምስክር ወረቀቶች የመንግስት ክፍያ ይኖራል፣ ማመልከቻ ከማስገባትዎ በፊት ይታያል።',
|
||||
|
||||
Reference in New Issue
Block a user