eb47016ae3
CI / check (push) Failing after 31s
Three changes: 1. Confirm-before-close. The header shift button closed the shift directly — a stray click would sign the irreversible Z-report. It now opens a confirm modal showing the live X-report (takings split by source + expected drawer) with Cancel / End-shift. Opening a shift stays immediate (no such risk). 2. Split takings by SOURCE. The report separates Tickets (transient) from Subscriptions (monthly sales + a subscriber's out-of-window charge), so the operator sees subscriber money apart from ticket money. Buckets are derived from the signed payment payload flags (subscriptionSale / subscriptionWindowCharge) and always reconcile to cash + card (a payment with neither flag is a ticket). Computed in #summariseWindow, carried on the signed shift_z_report payload, and shown in the X-report, the close modal, the shift history detail, and the printed Z-report. Reports predating the fields default subscription to 0 (ticket absorbs the whole take), so old shifts still reconcile. 3. Fix dark-theme native <select> popups rendering WHITE on WebKitGTK (the Tauri Linux WebView): set color-scheme dark/light on <html> per theme + explicit <option> colours, so the OS-drawn dropdown list follows the theme. Verified the split on a read-only DB copy: tickets 0, subscriptions 10,200 (10,000 sale + 200 out-of-window), reconciles to cash+card. build+lint 14/14, i18n parity (sq+en). Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
763 lines
31 KiB
TypeScript
763 lines
31 KiB
TypeScript
// Albanian (sq) — the DEFAULT and fallback language. Customer/operator-facing copy.
|
||
// Keys are dot-namespaced by area (common, nav, booth, …). When adding a string,
|
||
// add it here first (the fallback), then mirror the key in en.ts.
|
||
// See wiki/concepts/i18n.md.
|
||
|
||
export const sq = {
|
||
common: {
|
||
loading: "Duke u ngarkuar…",
|
||
logout: "Dil",
|
||
cancel: "Anulo",
|
||
close: "Mbyll",
|
||
save: "Ruaj",
|
||
none: "—",
|
||
themeDark: "errët",
|
||
themeLight: "çelët",
|
||
theme: "Tema",
|
||
today: "Sot",
|
||
yesterday: "Dje",
|
||
// Month names (index 0 = January) — kept in the catalog because the appliance's
|
||
// browser ICU may lack Albanian locale data (Intl falls back to English).
|
||
months: [
|
||
"Janar",
|
||
"Shkurt",
|
||
"Mars",
|
||
"Prill",
|
||
"Maj",
|
||
"Qershor",
|
||
"Korrik",
|
||
"Gusht",
|
||
"Shtator",
|
||
"Tetor",
|
||
"Nëntor",
|
||
"Dhjetor",
|
||
],
|
||
},
|
||
auth: {
|
||
title: "Sistemi i Parkimit",
|
||
username: "Përdoruesi",
|
||
password: "Fjalëkalimi",
|
||
signIn: "Hyr",
|
||
signingIn: "Duke hyrë…",
|
||
},
|
||
update: {
|
||
available: "Përditësim i disponueshëm",
|
||
prompt: "Versioni {{version}} është i disponueshëm. Ta instaloj tani dhe ta rinis?",
|
||
},
|
||
nav: {
|
||
booth: "Kabina",
|
||
shift: "Turni",
|
||
setup: "Konfigurimi",
|
||
devices: "Pajisjet",
|
||
tariff: "Tarifa",
|
||
tariffLab: "Lab Tarife",
|
||
subscriptions: "Abonimet",
|
||
plans: "Planet",
|
||
site: "Park",
|
||
users: "Përdoruesit",
|
||
roles: "Rolet",
|
||
shifts: "Turnet",
|
||
logs: "Loget",
|
||
},
|
||
status: {
|
||
live: "LIVE",
|
||
connecting: "DUKE U LIDHUR",
|
||
offline: "JASHTË LINJE",
|
||
},
|
||
devices: {
|
||
footerTitle: "Pajisjet",
|
||
none: "Asnjë pajisje e konfiguruar.",
|
||
catAccess: "Rele",
|
||
catReader: "Lexuesi",
|
||
catCamera: "Kamera",
|
||
catPrinter: "Printer",
|
||
catVision: "ANPR",
|
||
// Role/direction suffixes for the chip label (e.g. "Lexuesi hyrje").
|
||
role: {
|
||
entry: "hyrje",
|
||
exit: "dalje",
|
||
both: "hyrje/dalje",
|
||
mixed: "hyrje/dalje",
|
||
lane: "në korsi",
|
||
booth: "në kabinë",
|
||
},
|
||
state: {
|
||
ready: "gati",
|
||
degraded: "i dëmtuar",
|
||
offline: "jashtë linje",
|
||
},
|
||
allOk: "të gjitha gati",
|
||
issuesCount: "{{count}} me probleme",
|
||
issuesTitle: "Problemet e pajisjeve",
|
||
clickForIssues: "Kliko për detajet",
|
||
checkedAt: "kontrolluar {{time}}",
|
||
},
|
||
booth: {
|
||
processTicket: "Proceso biletën",
|
||
scanPlaceholder: "Skano ose shkruaj numrin e biletës…",
|
||
open: "Hap",
|
||
occupancy: "Prania",
|
||
occUnavailable: "zënia e padisponueshme",
|
||
inside: "brenda",
|
||
of: "nga",
|
||
uncapped: "pa kufi",
|
||
free: "Vende të lira",
|
||
lotFull: "● parkimi plot",
|
||
liveFeed: "Aktiviteti live",
|
||
events: "Evente",
|
||
noEventsYet: "Asnjë event ende — hyrjet dhe daljet do të shfaqen këtu.",
|
||
activeSessions: "Sesionet aktive",
|
||
insideCount: "brenda",
|
||
noActiveSessions: "Asnjë sesion aktiv.",
|
||
noMatch: "Asnjë rezultat për filtrin.",
|
||
badgeOverstay: "tej afatit",
|
||
badgeOverstayTitle:
|
||
"Sesion i paguar. Klienti nuk doli brënda afatit kohor. Ka filluar një periudhë e re tarifimi.",
|
||
plateTitle: "Targa e njohur nga ANPR",
|
||
// filtra
|
||
filterSearchSessions: "Kërko biletë / abonent / targë…",
|
||
filterSearchFeed: "Kërko event / identitet / targë…",
|
||
filterAll: "Të gjitha",
|
||
fStatusUnpaid: "Papaguar",
|
||
fStatusPaid: "Paguar",
|
||
fStatusExiting: "Duke dalë",
|
||
fStatusOverstay: "Tej afatit",
|
||
fKindTransient: "Kalimtarë",
|
||
fKindSubscription: "Abonentë",
|
||
fDirEntry: "Hyrje",
|
||
fDirExit: "Dalje",
|
||
fSrcBooth: "Kabinë",
|
||
fSrcReader: "Lexues",
|
||
fEvtEntry: "Hyrje",
|
||
fEvtExit: "Dalje",
|
||
fEvtPay: "Pagesë",
|
||
fEvtVoid: "Anulim",
|
||
fEvtAnomaly: "Anomali",
|
||
openPayExit: "Hap pagesën / daljen",
|
||
openBarrier: "Hap barrierën",
|
||
openBarrierTitle: "Hap barrierën manualisht",
|
||
barrierOpened: "barriera u hap",
|
||
openManually: "hape me dorë",
|
||
// session row badges
|
||
badgeExiting: "duke dalë",
|
||
badgePaid: "paguar",
|
||
badgeUnpaid: "papaguar",
|
||
badgeSubscription: "abonim",
|
||
// event types (live feed labels)
|
||
evtEntry: "HYRJE",
|
||
evtExit: "DALJE",
|
||
evtPay: "PAGESË",
|
||
evtVoid: "ANULIM",
|
||
evtOpenCmd: "HAP→",
|
||
evtOpenObserved: "HAP✓",
|
||
evtShiftOpen: "TURN+",
|
||
evtShiftZ: "TURN Z",
|
||
evtCashMovement: "ARKË",
|
||
evtCashIn: "ARKËTIM",
|
||
evtCashOut: "PAGESË",
|
||
evtAnomaly: "ANOMALI",
|
||
// rreshti i detajeve të eventit live + etiketat e klasifikimit (nga payload)
|
||
evtNoReason: "pa arsye të regjistruar",
|
||
badgeEntryRefused: "hyrje e refuzuar",
|
||
badgeExitRefused: "dalje e refuzuar",
|
||
badgeLotFull: "parkimi plot",
|
||
badgeBarrierFailed: "barriera nuk u hap",
|
||
badgeManualOpen: "hapje manuale",
|
||
badgeSubRefused: "abonimi u refuzua",
|
||
badgeSubSale: "shitje abonimi",
|
||
badgeWindowCharge: "jashtë orarit — detyrim",
|
||
badgeNoTicket: "bileta nuk u printua",
|
||
feedSourceBooth: "kabinë",
|
||
feedSourceReader: "lexues",
|
||
// dritarja e detajeve të eventit
|
||
eventDetail: "Detajet e eventit",
|
||
edType: "Lloji",
|
||
edTime: "Ora",
|
||
edIndex: "Indeksi në regjistër",
|
||
edDirection: "Drejtimi",
|
||
edSource: "Burimi",
|
||
edIdentity: "Identiteti",
|
||
edReason: "Arsyeja",
|
||
edSnapshots: "Fotot",
|
||
edPayload: "Të dhënat e nënshkruara",
|
||
edChain: "Zinxhiri",
|
||
edSignature: "Nënshkrimi",
|
||
edKeyId: "Çelësi",
|
||
edPrevHash: "Hash-i i mëparshëm",
|
||
edNoPayload: "Ky event nuk ka të dhëna shtesë.",
|
||
edCopy: "Kopjo",
|
||
edCopied: "U kopjua",
|
||
edDetails: "Detajet",
|
||
edAuditData: "Të dhënat e auditimit (nënshkrimi & zinxhiri)",
|
||
edAmount: "Shuma",
|
||
edTender: "Mënyra e pagesës",
|
||
edSession: "Sesioni",
|
||
edPlate: "Targa",
|
||
edCategory: "Kategoria",
|
||
edOperator: "Operatori",
|
||
edTariffVersion: "Versioni i tarifës",
|
||
edRawPayload: "Të dhënat e papërpunuara të nënshkruara",
|
||
edOccurrence: "ID e hyrjes",
|
||
subscriber: "Abonent",
|
||
edVia: "Mënyra e hyrjes",
|
||
viaQr: "Kod QR",
|
||
viaCard: "Kartë/çip RFID",
|
||
viaPlate: "Targë",
|
||
},
|
||
// Mesazhet e përkthyera për REASON_CODES e nënshkruara (shih @parking/shared).
|
||
// Çelësat përputhen 1:1 me kodet; {{param}} mbushet nga reasonParams i eventit.
|
||
reason: {
|
||
"entry.refused.full": "Hyrja u refuzua — parkimi plot ({{count}}/{{capacity}})",
|
||
"entry.held.noTicket": "Hyrja u mbajt — bileta nuk u printua: {{detail}}",
|
||
"exit.refused.closed": "Dalja u refuzua — sesioni është mbyllur tashmë",
|
||
"exit.refused.noSession": "Dalja u refuzua — biletë e panjohur",
|
||
"exit.refused.unpaid": "Dalja u refuzua — e papaguar (bëj pagesën në fillim)",
|
||
"exit.refused.graceExpired": "Dalja u refuzua — afati i daljes skadoi (kërkohet pagesë shtesë)",
|
||
"exit.open.noBarrier": "Dalja u regjistrua, por nuk ka barrierë daljeje të konfiguruar — hape me dorë",
|
||
"exit.open.unavailable": "Dalja u regjistrua, por barriera është e padisponueshme — hape me dorë",
|
||
"exit.open.failed": "Dalja u regjistrua, por barriera nuk u hap — hape me dorë",
|
||
"exit.freeGrace": "Periudhë pa pagesë në hyrje (pa tarifë)",
|
||
"exit.manualOpen": "Hapje manuale e barrierës (ndërhyrje njerëzore)",
|
||
"sub.refused.notFound": "Abonimi u refuzua — nuk u gjet",
|
||
"sub.refused.outOfWindow": "Abonimi u refuzua — {{status}}/jashtë afatit",
|
||
"sub.refused.noSession": "Dalje me abonim pa sesion të hapur (tashmë jashtë / nuk ka hyrë kurrë)",
|
||
"sub.refused.atCapacity": "Abonimi u refuzua — në kapacitet ({{inUse}}/{{max}} makina brenda)",
|
||
"sub.refused.unpaidWindow": "Dalja u refuzua — detyrim jashtë orarit i papaguar ({{amount}} {{currency}}); paguaje në kabinë",
|
||
},
|
||
tariff: {
|
||
title: "Tarifa",
|
||
noRateCard: "Asnjë tarifë e publikuar — arka nuk mund të faturojë derisa të publikoni një.",
|
||
activeSince: "Aktive që nga {{date}} · {{count}} version(e) në histori. Publikimi krijon një version të ri; sesionet e kaluara ruajnë çmimin origjinal.",
|
||
currency: "Monedha",
|
||
freeEntryGrace: "Periudha pa pagesë në hyrje (min)",
|
||
billingIncrement: "Intervali i faturimit (min)",
|
||
dailyCap: "Kufiri ditor (bosh = pa kufi)",
|
||
dailyCapPh: "p.sh. 12.00",
|
||
lostTicketFee: "Tarifa për biletë të humbur",
|
||
exitGrace: "Periudha e kthimit në dalje (min)",
|
||
rateBlocks: "Blloqet tarifore",
|
||
rateBlocksHint: "Çdo brez zgjat një numër orësh dhe faturohet me çmimin e tij; brezat konsumohen me radhë (orët e para, pastaj orët në vijim). Brezi i fundit është \"më pas\" (i hapur) — çmimi i tij zbatohet pas mbarimit të shkallës. Çmimi është për interval faturimi.",
|
||
bandDuration: "Kohëzgjatja e brezit",
|
||
hoursUnit: "orë",
|
||
egHours: "p.sh. 2",
|
||
pricePerIncrement: "Çmimi / interval",
|
||
thereafter: "më pas (i hapur)",
|
||
remove: "Hiq",
|
||
addBlock: "+ Shto bllok",
|
||
publishNewVersion: "Publiko version të ri",
|
||
publishing: "Duke publikuar…",
|
||
publishedOk: "U publikua versioni i ri i tarifës — tani është tarifa aktive.",
|
||
defaultCard: "Tarifa bazë (gjithmonë aktive)",
|
||
defaultCardHint: "Çmimi bazë i zbatuar kur asnjë nivel kohor/sezonal nuk vlen. Kjo e vetme është mjaftueshëm për shumicën e parkimeve.",
|
||
modeLadder: "Shkallë orësh",
|
||
modeFlat: "Çmim fiks",
|
||
modeStepped: "Sipas kohëzgjatjes (deri-në)",
|
||
steppedHint:
|
||
"Vendos çmimin TOTAL për një qëndrim deri në një kohë të caktuar (p.sh. deri 3 orë = 500). Fiton rreshti i parë me kufi ≥ kohëzgjatjes (kufiri përfshihet). Totali i rreshtit të fundit përsëritet si çmim ditor për qëndrime më të gjata.",
|
||
stepUpTo: "Deri në",
|
||
stepTotal: "Çmimi total",
|
||
addStep: "+ Shto rresht",
|
||
steppedTiersConflict:
|
||
"⚠ Nivelet kohore/sezonale NUK zbatohen kur tarifa bazë është 'Sipas kohëzgjatjes (deri-në)' — motori i shpërfill plotësisht. Hiqi nivelet, ose ndrysho tarifën bazë në 'Shkallë orësh' a 'Çmim fiks'. Publikimi bllokohet derisa kjo të rregullohet.",
|
||
tiersAdvanced: "Të avancuara: nivele kohore & sezonale",
|
||
tiersHint: "Opsionale. Shto nivele tarifore që vlejnë vetëm në orë/ditë/data ose kategori të caktuara (p.sh. orë e lirë, tarifë nate, fundjavë, autobus). Pa nivele, publikohet vetëm tarifa bazë.",
|
||
tierName: "Emri",
|
||
tierPriority: "Përparësia",
|
||
tierCategory: "Kategoria",
|
||
tierCategoryPh: "p.sh. autobus",
|
||
tierDays: "Ditët",
|
||
tierHours: "Orët",
|
||
tierDates: "Datat",
|
||
tierOvernight: "(kalon mesnatën)",
|
||
addTier: "+ Shto nivel",
|
||
dow1: "Hën",
|
||
dow2: "Mar",
|
||
dow3: "Mër",
|
||
dow4: "Enj",
|
||
dow5: "Pre",
|
||
dow6: "Sht",
|
||
dow0: "Die",
|
||
},
|
||
setup: {
|
||
title: "Konfigurimi",
|
||
intro:
|
||
"Shto fillimisht kontrolluesit e barrierave — cakto cili rele është hyrje/dalje dhe në cilin terminal është lidhur butoni i hyrjes. Pastaj shto lexues, kamera dhe printera dhe drejto secilin te barriera që shërben.",
|
||
// Category titles + the singular noun used in buttons/modal titles.
|
||
catControllers: "Kontrolluesit (barrierat + butoni i hyrjes)",
|
||
catReaders: "Lexuesit (QR / RFID)",
|
||
catCameras: "Kamerat (foto + targë)",
|
||
catPrinters: "Printerat (bileta / vouchera)",
|
||
nounController: "kontrollues",
|
||
nounReader: "lexues",
|
||
nounCamera: "kamerë",
|
||
nounPrinter: "printer",
|
||
add: "+ Shto {{noun}}",
|
||
addAnother: "+ Shto edhe një {{noun}}",
|
||
addTitle: "Shto {{noun}}",
|
||
editTitle: "Ndrysho {{noun}}",
|
||
needControllerFirst: "Shto fillimisht një kontrollues — {{noun}} drejtohet te një prej releve të tij.",
|
||
failedToLoad: "Ngarkimi i konfigurimit dështoi: {{error}}",
|
||
loadingCatalog: "Duke ngarkuar katalogun e pajisjeve…",
|
||
// Direction labels (relay direction + inherited binding).
|
||
dirEntry: "Hyrje",
|
||
dirExit: "Dalje",
|
||
dirBoth: "Hyrje + dalje",
|
||
inherits: "trashëgon {{direction}}",
|
||
// Warnings panel.
|
||
warnTitle: "⚠ U ruajt, por nevojitet veprim:",
|
||
dismiss: "Mbyll",
|
||
// Assignment row.
|
||
disabled: "(çaktivizuar)",
|
||
edit: "Ndrysho",
|
||
remove: "Hiq",
|
||
removing: "Duke hequr…",
|
||
confirmRemove: "Të hiqet kjo pajisje {{driver}}?",
|
||
noRelaysSet: "asnjë rele e caktuar",
|
||
unbound: "e palidhur",
|
||
// Device form.
|
||
noDrivers: "Asnjë drejtues i regjistruar.",
|
||
chooseDevice: "Zgjidh një pajisje…",
|
||
scan: "Skano për kontrollues",
|
||
scanning: "Duke skanuar…",
|
||
noControllersFound: "Asnjë kontrollues në LAN.",
|
||
use: "Përdor",
|
||
test: "Testo lidhjen",
|
||
testing: "Duke testuar…",
|
||
saveConfigure: "Ruaj & konfiguro",
|
||
saveChanges: "Ruaj ndryshimet",
|
||
saving: "Duke ruajtur…",
|
||
cancel: "Anulo",
|
||
testFailed: "Testi dështoi: {{error}}",
|
||
saveFailed: "Ruajtja dështoi: {{error}}",
|
||
deviceLabel: "Pajisja:",
|
||
preconditionsOk: "● parakushtet OK",
|
||
autoFixedOnSave: "(rregullohet vetë në ruajtje)",
|
||
backendPushIp: "IP-ja e backend-it",
|
||
chooseAddress: "Zgjidh një adresë…",
|
||
onDeviceSubnet: "— në subnetin e pajisjes",
|
||
noNicOnSubnet: "⚠ asnjë NIC në subnetin e pajisjes — pajisja mund të mos arrijë backend-in",
|
||
backendIpHint: "Adresa te e cila kjo pajisje do të dërgojë eventet e hyrjes.",
|
||
// Relay editor.
|
||
relaysTitle: "Relet në këtë kontrollues",
|
||
relaysHint:
|
||
"Çdo rele hap një barrierë. Cakto drejtimin e saj; për hyrje kalimtare, cakto në cilin terminal hyrës është lidhur butoni i hyrjes.",
|
||
relay: "Rele",
|
||
entryButtonTerminal: "Butoni i hyrjes në terminalin",
|
||
presenceInput: "Sensori i pranisë (terminali)",
|
||
presenceInputHint:
|
||
"Terminali hyrës ku është lidhur sensori/laku i pranisë së automjetit. Kur vendoset, lëshohet vetëm NJË biletë për automjet: butoni printon vetëm kur ka makinë, dhe nuk lëshon biletë të dytë derisa laku të lirohet (makina hyri) dhe një makinë e re ta zërë. Mënyra e preferuar.",
|
||
entryCooldown: "Pritje pas biletës (sek)",
|
||
entryCooldownHint:
|
||
"Kur nuk ka sensor pranie: shtypjet e përsëritura të butonit shtypen për kaq sekonda pas një bilete. Zgjidhje rezervë (jo garanci) — një abuzues mund ta presë afatin.",
|
||
addRelay: "+ Shto rele",
|
||
// Camera ANPR opt-in.
|
||
anpr: "Njohja e targave (ANPR)",
|
||
anprHint:
|
||
"Aktivizo që ky aparat të skanojë targat: shërbimi i vizionit lexon targën nga pamja dhe e dërgon si lexim (vetëm këshillues — nuk hap vetë barrierën). Kërkon shërbimin e vizionit aktiv.",
|
||
// Binding picker.
|
||
whichBarrier: "Cilën barrierë shërben kjo pajisje?",
|
||
controller: "Kontrolluesi",
|
||
choose: "Zgjidh…",
|
||
relayLabel: "Rele {{relay}} ({{direction}})",
|
||
noRelaysConfigured: "Ky kontrollues nuk ka rele të konfiguruar.",
|
||
},
|
||
lab: {
|
||
title: "Lab Tarife",
|
||
intro:
|
||
"Testo tarifat në kohë (dritare ditë/natë, kufi ditor, qëndrim tej afatit) në sekonda, pa pritur orë. Çmimi llogaritet me të njëjtën logjikë si kabina; nuk shkruhet asgjë në ledger.",
|
||
loadTicket: "Ngarko nga një biletë reale",
|
||
loadTicketPh: "Numri i biletës / identiteti",
|
||
load: "Ngarko",
|
||
loaded: "U ngarkua sesioni {{id}}",
|
||
tariffVersion: "Versioni i tarifës",
|
||
activeVersion: "Versioni aktiv (i tanishëm)",
|
||
entered: "Hyrja",
|
||
asOf: "Deri më (tani/dalja)",
|
||
now: "Tani",
|
||
category: "Kategoria",
|
||
categoryPh: "p.sh. bus (bosh = makinë)",
|
||
payment: "Pagesa",
|
||
paid: "u pagua",
|
||
graceMin: "afati (min)",
|
||
price: "Llogarit çmimin",
|
||
pricing: "Duke llogaritur…",
|
||
outcome: "Rezultati",
|
||
amountDue: "Shuma për pagesë",
|
||
billedPeriod: "Periudha e faturuar",
|
||
overstay: "tej afatit",
|
||
settled: "i shlyer",
|
||
periodStart: "Fillimi i periudhës",
|
||
graceExpires: "Afati skadon",
|
||
curve: "Kurba sipas kohëzgjatjes",
|
||
curveHint: "Tarifa nga hyrja për disa kohëzgjatje — shih ku rrafshohet kufiri ditor ose ndryshojnë dritaret.",
|
||
},
|
||
subs: {
|
||
title: "Abonimet",
|
||
unnamed: "(pa emër)",
|
||
unbound: "pa kufizim",
|
||
car_one: "{{count}} makinë",
|
||
car_other: "{{count}} makina",
|
||
cred: "kredencial",
|
||
plates: "{{count}} targë(a)",
|
||
noPrice: "pa çmim",
|
||
perDay: "ditë",
|
||
perWeek: "javë",
|
||
perMonth: "muaj",
|
||
plan: "Plani",
|
||
quantity: "Makina",
|
||
quantityHint: "makina të mbuluara nga ky abonim (çmimi ×N)",
|
||
count: "Sa",
|
||
planNone: "— pa pagesë / falas —",
|
||
planNoneAvail: "Asnjë plan i përcaktuar — admini duhet të krijojë një të parin.",
|
||
version: "Versioni",
|
||
versionCurrent: "aktual",
|
||
versionHint: "Zhvendos këtë abonent në një version tjetër të të njëjtit plan. Çmimi mbetet siç u faturua; ndryshon vetëm orari i lejuar nga këtu e tutje.",
|
||
versionOnlyOne: "vetëm një version i këtij plani",
|
||
everyDay: "çdo ditë",
|
||
allDay: "24/7 (pa orar)",
|
||
quoting: "duke llogaritur…",
|
||
quotePrompt: "zgjidh datën e mbarimit",
|
||
quoteLine: "{{periods}} × {{unit}} · {{amount}} {{currency}}",
|
||
tender: "Paguar me",
|
||
tenderCash: "Para në dorë",
|
||
tenderCard: "Kartë",
|
||
tenderHint: "Regjistrohet si pagesë e nënshkruar (aktiviteti, arka, raporti i turnit).",
|
||
saleRecorded: "Shitja u regjistrua: {{amount}} {{currency}} ({{tender}}).",
|
||
saleNoShift: "⚠ Asnjë turn i hapur — hapni një që arkëtimi të hyjë në një raport turni.",
|
||
edit: "Ndrysho",
|
||
revoke: "Anulo",
|
||
delete: "Fshij",
|
||
noneYet: "Asnjë abonim ende.",
|
||
add: "+ Shto abonim",
|
||
new: "Abonim i ri",
|
||
editTitle: "Ndrysho abonimin",
|
||
holderName: "Emri i mbajtësit",
|
||
contact: "Kontakti",
|
||
carLimit: "Kufiri i makinave",
|
||
limitCarsInAtOnce: "kufizo makinat brenda njëkohësisht",
|
||
validFrom: "Vlen nga",
|
||
validTo: "Vlen deri",
|
||
validToEnd: "Vlen deri (mbarimi)",
|
||
isoDateOptional: "Datë ISO (opsionale)",
|
||
boundPlates: "Targat e lidhura",
|
||
commaSeparatedOptional: "të ndara me presje (opsionale)",
|
||
credentials: "Kredencialet",
|
||
credentialsCardQr: "Kredencialet (kartë / QR)",
|
||
rfCardTag: "Kartë/Tag RF",
|
||
rfCardTagSoon: "Kartë/Tag RF (së shpejti)",
|
||
rfPlaceholder: "numri i kartës (ose lexo kartën)",
|
||
readCard: "Lexo kartën",
|
||
captureChooseReader: "Zgjidh lexuesin, pastaj afro kartën:",
|
||
captureNoReaders: "Asnjë lexues i konfiguruar.",
|
||
captureWaiting: "Afro kartën te lexuesi…",
|
||
captureTimeout: "Skadoi pa lexuar kartë. Provo sërish.",
|
||
captured: "Karta u lexua: {{value}}",
|
||
qr: "QR",
|
||
qrAutoGen: "kodi QR gjenerohet automatikisht në ruajtje",
|
||
credentialValue: "vlera e kredencialit",
|
||
addCredential: "+ kredencial",
|
||
needCredentialOrPlate: "Një abonim kërkon të paktën një kredencial OSE një targë të lidhur.",
|
||
save: "Ruaj",
|
||
cancel: "Anulo",
|
||
saved: "Abonimi u ruajt.",
|
||
savedPrinted: "Abonimi u ruajt — kodi QR u printua.",
|
||
savedPrintFailed: "Abonimi u ruajt, por printimi dështoi ({{error}}). Përdor \"Printo kodin\".",
|
||
printCode: "Printo kodin",
|
||
printedOn: "Kodi u printua te {{printer}}.",
|
||
confirmRevoke: "Të anulohet abonimi për {{name}}? Do të refuzohet te barriera.",
|
||
confirmDelete: "Të fshihet abonimi për {{name}}? (t e kaluara ruhen.)",
|
||
statusActive: "aktiv",
|
||
statusSuspended: "pezulluar",
|
||
statusRevoked: "anuluar",
|
||
},
|
||
plans: {
|
||
title: "Planet e abonimit",
|
||
intro: "Planet i përcakton admini; operatori vetëm shet prej tyre — çmimi merret automatikisht, nuk shkruhet. Ndryshimi i një plani publikon një version të ri; shitjet e mëparshme ruajnë çmimin e tyre.",
|
||
add: "+ Shto plan",
|
||
noneYet: "Asnjë plan ende. Shto një që kabina të shesë abonime.",
|
||
colName: "Emri",
|
||
colPrice: "Çmimi",
|
||
colHours: "Orari",
|
||
colUsedBy: "Përdorur nga",
|
||
colEffective: "Vlen nga",
|
||
allHours: "24/7",
|
||
usedByCount: "{{active}} aktive / {{total}}",
|
||
usedByNone: "asnjë",
|
||
usedByTitle: "Shfaq abonimet në këtë plan",
|
||
subscribers: "Abonentët",
|
||
inForce: "në fuqi",
|
||
retired: "i tërhequr",
|
||
versionCount: "{{count}} versione",
|
||
newVersion: "Version i ri",
|
||
retire: "Tërhiq",
|
||
reactivate: "Riaktivizo",
|
||
delete: "Fshij",
|
||
deleteTitle: "Fshij këtë plan përgjithmonë (vetëm kur asnjë abonim nuk e përdor)",
|
||
reactivated: "“{{name}}” është përsëri i shitshëm.",
|
||
confirmDelete: "Të fshihet plani “{{name}}” përgjithmonë? Kjo s'mund të kthehet.",
|
||
deleted: "Plani “{{name}}” u fshi.",
|
||
deleteInUse: "S'mund të fshihet — abonime ende e përdorin këtë plan. Tërhiqe në vend të kësaj.",
|
||
newTitle: "Plan i ri",
|
||
newVersionTitle: "Publiko version të ri",
|
||
newVersionHint: "Kjo publikon një version TË RI të planit — shitjet ekzistuese ruajnë çmimin origjinal.",
|
||
period: "Periudha",
|
||
pricePer: "Çmimi për periudhë",
|
||
namePlaceholder: "p.sh. Mujor standard, ose Mujor natën, ose Hotel ditor",
|
||
needName: "Emri i planit është i detyrueshëm.",
|
||
needPrice: "Shkruaj një çmim më të madh se zero.",
|
||
saved: "Plani u ruajt.",
|
||
confirmRetire: "Të tërhiqet plani “{{name}}”? Nuk do të jetë më i shitshëm (historiku ruhet).",
|
||
needWindow: "Shkruaj orare të vlefshme (HH:MM).",
|
||
needDays: "Zgjidh të paktën një ditë për intervalin.",
|
||
restrictTimes: "Kufizo oraret e parkimit (tarifë kalimtare jashtë intervalit)",
|
||
days: "Ditët",
|
||
window: "Intervali",
|
||
enterAfter: "hyrje pas",
|
||
exitBefore: "· dalje para",
|
||
grace: "Tolerancë",
|
||
graceHint: "minuta tolerancë rreth kufijve të intervalit",
|
||
timeframesHint: "Një skanim jashtë intervalit të lejuar tarifohet me tarifën normale kalimtare për minutat jashtë intervalit (hyrja e hershme shtyhet në dalje; dalja e vonuar bllokohet derisa paguhet).",
|
||
},
|
||
site: {
|
||
occupancy: "Prania:",
|
||
noCapacitySet: "(pa kapacitet të caktuar)",
|
||
free: "lirë",
|
||
full: "PLOT",
|
||
capacityLabel: "Kapaciteti (bosh = pa kufi):",
|
||
capacityPlaceholder: "p.sh. 120",
|
||
printExitDefault: "Printo biletën e daljes si parazgjedhje",
|
||
printExitHint: "(klienti skanon biletën në dalje)",
|
||
reserveSubs: "Rezervo vendet e abonentëve",
|
||
reserveSubsHint: "Mban një vend për makinat e çdo abonenti aktiv edhe kur nuk janë të parkuar — kalimtarët e shohin 'plot' më shpejt. Joaktiv: numërohen vetëm makinat brenda (mbingarkesa menaxhohet me parkim manual).",
|
||
parkDetails: "Të dhënat e parkimit (opsionale — shfaqen në bileta/fatura)",
|
||
save: "Ruaj",
|
||
saved: "U ruajt.",
|
||
fieldParkName: "Emri i parkimit",
|
||
fieldParkNamePh: "p.sh. Acme Parking",
|
||
fieldOperator: "Operatori (emri ligjor)",
|
||
fieldOperatorPh: "kompania operuese",
|
||
fieldNius: "NIUS",
|
||
fieldNiusPh: "p.sh. L01234567A",
|
||
fieldAddress: "Adresa",
|
||
fieldPhone: "Telefoni",
|
||
fieldEmail: "Email",
|
||
},
|
||
users: {
|
||
title: "Përdoruesit",
|
||
add: "+ Shto përdorues",
|
||
new: "Përdorues i ri",
|
||
none: "Asnjë përdorues.",
|
||
username: "Përdoruesi",
|
||
password: "Fjalëkalimi",
|
||
passwordHint: "Të paktën 8 karaktere.",
|
||
newPassword: "fjalëkalim i ri",
|
||
role: "Roli",
|
||
resetPassword: "Rivendos fjalëkalimin",
|
||
edit: "Ndrysho",
|
||
editTitle: "Ndrysho përdoruesin",
|
||
save: "Ruaj",
|
||
delete: "Fshi",
|
||
confirmDelete: "Të fshihet përdoruesi \"{{name}}\"?",
|
||
// Optional profile metadata.
|
||
detailsSection: "Të dhënat (opsionale)",
|
||
fullName: "Emri i plotë",
|
||
phone: "Telefoni",
|
||
email: "Email",
|
||
address: "Adresa",
|
||
},
|
||
roles: {
|
||
title: "Rolet",
|
||
add: "+ Shto rol",
|
||
new: "Rol i ri",
|
||
editTitle: "Ndrysho rolin",
|
||
name: "Emri",
|
||
permissions: "Lejet",
|
||
builtin: "i integruar",
|
||
edit: "Ndrysho",
|
||
delete: "Fshi",
|
||
confirmDelete: "Të fshihet roli \"{{name}}\"?",
|
||
permCount_one: "{{count}} leje",
|
||
permCount_other: "{{count}} leje",
|
||
userCount_one: "{{count}} përdorues",
|
||
userCount_other: "{{count}} përdorues",
|
||
},
|
||
shift: {
|
||
label: "Turni:",
|
||
open: "hapur",
|
||
notStarted: "i panisur",
|
||
since: "që nga",
|
||
startShift: "Fillo turnin",
|
||
starting: "Duke filluar…",
|
||
endShift: "Mbyll turnin",
|
||
ending: "Duke mbyllur…",
|
||
endConfirm: "Të mbyllet ky turn? Regjistrohet dhe printohet një Raport Z i nënshkruar.",
|
||
drawer: "Arka:",
|
||
openingFloatInherited: "(bilanci fillestar i trashëguar nga turni i mëparshëm)",
|
||
drawerCashAdmin: "Para në arkë (admin) — shto ose hiq bilancin",
|
||
drawerVoucher: "Mandat arke — operatori e hap, admini e autorizon",
|
||
amount: "shuma",
|
||
reasonPlaceholder: "arsyeja (p.sh. bilanci fillestar)",
|
||
load: "Shto +",
|
||
remove: "Hiq −",
|
||
authName: "përdoruesi i adminit",
|
||
authPassword: "fjalëkalimi i adminit",
|
||
authRequired: "Një admin duhet ta autorizojë: shkruaj përdoruesin dhe fjalëkalimin e tij.",
|
||
mandatArketimi: "Arkëtim (hyrje) +",
|
||
mandatPagese: "Pagesë (dalje) −",
|
||
voucherHint: "Mandat Arkëtimi shton para; Mandat Pagese heq para. Arka lëviz vetëm me autorizimin e një admini.",
|
||
voucherRecorded: "Mandati {{no}} u regjistrua. Arka tani {{amount}}.",
|
||
enterPositive: "Shkruaj një shumë pozitive.",
|
||
drawerNow: "Arka tani {{amount}}.",
|
||
zReport: "MBYLLJA E TURNIT",
|
||
viewTakings: "Arkëtimet deri tani",
|
||
xReport: "ARKËTIMET DERI TANI",
|
||
asOf: "deri më",
|
||
xReportHint: "Vetëm për shikim — asgjë nuk regjistrohet. Këto shifra nënshkruhen kur mbyllet turni.",
|
||
payments: "Pagesa:",
|
||
cash: "Para:",
|
||
card: "Kartë:",
|
||
srcTickets: "Bileta:",
|
||
srcSubscriptions: "Abonime:",
|
||
srcSubSales: "shitje",
|
||
srcSubWindow: "jashtë orarit",
|
||
drawerSection: "— Arka —",
|
||
openingFloat: "Bilanci fillestar:",
|
||
cashTaken: "Para të marra:",
|
||
cashAdded: "Para të shtuara:",
|
||
cashRemoved: "Para të hequra:",
|
||
expectedDrawer: "Gjëndje Arke:",
|
||
printedToReceipt: "Printuar te printeri i kabinës.",
|
||
recordedNoPrinter: "Regjistruar (pa printer për të printuar).",
|
||
// Header shift control + the booth shift gate.
|
||
headerNoShift: "Asnjë turn",
|
||
headerOpen: "Hap turnin",
|
||
headerClose: "Mbyll turnin",
|
||
headerHeldBy: "Turn i hapur nga {{operator}}",
|
||
headerHeldByShort: "Turni: {{operator}}",
|
||
gateTitle: "Hap një turn për të proceduar biletat",
|
||
gateBody:
|
||
"Asnjë turn nuk është i hapur. Hap turnin tënd që pagesat dhe daljet të regjistrohen te ky turn.",
|
||
gateOtherTitle: "Turni i hapur i përket një operatori tjetër",
|
||
gateOtherBody:
|
||
"{{operator}} ka një turn të hapur. Vetëm një turn mund të jetë i hapur njëkohësisht — ai duhet të mbyllë turnin para se ti të hapësh tëndin.",
|
||
openNow: "Hap turnin tani",
|
||
opening: "Duke hapur…",
|
||
},
|
||
shifts: {
|
||
title: "Historiku i turneve",
|
||
myTitle: "Turnet e mia",
|
||
none: "Asnjë turn i mbyllur.",
|
||
operator: "Operatori",
|
||
started: "Filloi",
|
||
ended: "Mbaroi",
|
||
payments: "Pagesa",
|
||
cash: "Para",
|
||
card: "Kartë",
|
||
srcTickets: "Bileta",
|
||
srcSubscriptions: "Abonime",
|
||
srcSubSales: "shitje abonimesh",
|
||
srcSubWindow: "jashtë orarit",
|
||
expectedDrawer: "Gjëndje arke",
|
||
// Filter (admin only).
|
||
filterFrom: "Nga",
|
||
filterTo: "Deri",
|
||
allOperators: "Të gjithë operatorët",
|
||
apply: "Apliko",
|
||
clear: "Pastro",
|
||
timeframe: "Periudha",
|
||
preset_yesterday: "Dje",
|
||
preset_week: "Javën e fundit",
|
||
preset_month: "Muajin e fundit",
|
||
preset_all: "Të gjitha",
|
||
preset_custom: "E zgjedhur",
|
||
selectAShift: "Zgjidh një turn për të parë aktivitetin e tij.",
|
||
noActivity: "Asnjë aktivitet në këtë turn.",
|
||
current: "aktual",
|
||
// Expanded drawer detail.
|
||
drawerSection: "Arka",
|
||
openingFloat: "Bilanci fillestar",
|
||
cashTaken: "Para të marra",
|
||
cashAdded: "Para të shtuara",
|
||
cashRemoved: "Para të hequra",
|
||
loadFailed: "Ngarkimi i turneve dështoi.",
|
||
},
|
||
logs: {
|
||
title: "Loget e sistemit",
|
||
refresh: "Rifresko",
|
||
level: "Niveli",
|
||
source: "Burimi",
|
||
since: "Që nga",
|
||
apply: "Apliko",
|
||
clear: "Pastro",
|
||
allLevels: "Të gjitha nivelet",
|
||
allSources: "Të gjitha burimet",
|
||
frontend: "Ndërfaqja",
|
||
backend: "Serveri",
|
||
time: "Koha",
|
||
message: "Mesazhi",
|
||
status: "Statusi",
|
||
path: "Rruga",
|
||
empty: "Asnjë regjistër.",
|
||
},
|
||
pay: {
|
||
ticket: "Bileta",
|
||
entry: "Hyrja",
|
||
now: "Tani",
|
||
duration: "Kohëzgjatja",
|
||
statusLabel: "Statusi",
|
||
paid: "PAGUAR",
|
||
unpaid: "PAPAGUAR",
|
||
overstay: "TEJ AFATIT",
|
||
overstayHint: "Sesion i mëparshëm i paguar. Klienti nuk doli brënda afatit kohor. Kërkohet pagesë për periudhën e re. Totali më poshtë është tarifa e periudhës së re.",
|
||
topUp: "Periudha e re për pagesë",
|
||
total: "Totali",
|
||
noTariff: "pa tarifë",
|
||
tender: "Mënyra",
|
||
cash: "Para",
|
||
card: "Kartë",
|
||
printExitVoucher: "Printo biletë dalje",
|
||
selfExitHint: "(klienti del vetë te dalja)",
|
||
payAndOpen: "Paguaj + hap barrierën",
|
||
payAndVoucher: "Paguaj + printo biletën",
|
||
openBarrier: "Hap barrierën",
|
||
printVoucher: "Printo biletën",
|
||
takingPayment: "Duke marrë pagesën…",
|
||
printingVoucher: "Duke printuar biletën…",
|
||
opening: "Duke hapur…",
|
||
noSessionFound: "Nuk u gjet asnjë sesion për këtë biletë.",
|
||
alreadyClosed: "Ky sesion është mbyllur tashmë (doli {{time}}).",
|
||
lookingUp: "Duke kërkuar…",
|
||
paidBarrierOpened: "Paguar — barriera u hap. Automjeti mund të dalë.",
|
||
paidExitRecorded: "Paguar dhe dalja u regjistrua, por barriera nuk u hap: {{reason}}.",
|
||
subscription: "ABONIM",
|
||
plan: "Plani",
|
||
prepaid: "I PARAPAGUAR",
|
||
subAssistHint: "Abonim i parapaguar. Hap barrierën për të ndihmuar daljen (lexues me defekt / kartë e munguar). S'ka pagesë.",
|
||
assistOpenReveal: "Ndihmë për hapje (lexues me defekt / kartë e humbur)…",
|
||
payWindowCharge: "Merr pagesën",
|
||
windowPaidHint: "Pagesa jashtë orarit u krye. Hap barrierën që abonenti të dalë.",
|
||
windowCharge: "JASHTË ORARIT",
|
||
windowChargeHint: "Ky abonent parkoi jashtë orarit të lejuar të planit. Detyrohet të paguajë tarifën kalimtare për kohën jashtë orarit — merr pagesën, pastaj hap barrierën.",
|
||
subBarrierOpened: "Barriera u hap për abonentin (ndërhyrje e regjistruar).",
|
||
voucherPrinted: "Bileta e daljes u printua në {{printer}}. Klienti del vetë te dalja.",
|
||
// payment receipt (transparency slip)
|
||
receiptPrintFailed: "(fatura nuk u printua — provoni \"Riprinto faturën\".)",
|
||
receiptReprinted: "Fatura u riprintua në {{printer}}.",
|
||
reprintReceipt: "Riprinto faturën",
|
||
reprinting: "duke printuar…",
|
||
// snapshots
|
||
noSnapshots: "asnjë foto",
|
||
loadingSnapshots: "duke ngarkuar fotot…",
|
||
snapEntry: "hyrje",
|
||
snapExit: "dalje",
|
||
snapFailed: "kamera e paarritshme",
|
||
plate: "Targa",
|
||
},
|
||
};
|
||
|
||
// The catalog SHAPE (keys + nesting), with string-typed values — so en.ts must
|
||
// supply every key but may differ in value. (Not `typeof sq` with `as const`, which
|
||
// would pin en.ts to the Albanian literals.)
|
||
type Stringify<T> = { [K in keyof T]: T[K] extends object ? Stringify<T[K]> : string };
|
||
export type Catalog = Stringify<typeof sq>;
|