Files
MatchLiveTv/backend/config/locales/admin.en.yml
T
eminuxandCursor cc96c0396a Migliora sessioni admin e rende robusto il logout web.
Aggiunge filtri/colonne (società, orari) e dettaglio leggibile; evita 422 CSRF su logout e non cancella le cover slate custom in sync prod.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 20:41:12 +02:00

501 lines
18 KiB
YAML

en:
admin:
layout:
title: "Match Live TV — Admin"
nav:
dashboard: Dashboard
ops: Ops
announcements: Notices
clubs: Clubs & teams
billing: Billing
youtube: YouTube
sessions: Sessions
stream_nodes: Stream nodes
password: Password
logout: Log out
flash:
login_required: Please log in to continue
login_success: Signed in successfully
invalid_credentials: Invalid username or password
logout_success: Signed out
password_current_incorrect: Current password is incorrect
password_too_short: The new password must be at least 8 characters long
password_too_long: New password cannot exceed 72 characters
password_too_weak: "New password must include at least 3 of: lowercase, uppercase, numbers and symbols"
password_same_as_current: New password must be different from the current password
password_mismatch: Passwords do not match
password_updated: Password updated
ops_acknowledged: Incident acknowledged
ops_resolved: Incident resolved
ops_muted: Notifications muted for 24 hours
stream_node_created: "Lab node %{slug} provisioned."
stream_node_destroyed: "Node %{slug} removed."
stream_node_draining: "Node %{slug} is draining (no new sessions)."
autoscale_kill_on: "Autoscaler kill-switch engaged. No automatic scale-out."
autoscale_kill_off: "Autoscaler kill-switch cleared (still needs STREAM_AUTOSCALE_ENABLED=1)."
comped_granted: "%{plan} complimentary subscription activated for %{club}."
comped_revoked: "Complimentary subscription revoked for %{club}."
session_already_terminated: "Session already ended (%{status})."
session_stopped: Session ended.
session_stop_error: "Error while stopping: %{error}"
session_terminated_no_regia: "Session ended: unable to generate the control link."
session_regia_generated: Control link generated.
invoice_upload_hint: Upload the PDF from the "Payments to invoice" list.
invoice_draft_created: Draft created. Upload the PDF from the Billing page or below.
invoice_issued: "Invoice %{number} issued and sent to %{email}."
invoice_updated: "Invoice %{number} updated."
invoice_uploaded: "Invoice uploaded and sent to %{email}."
youtube_not_configured: Configure YOUTUBE_CLIENT_ID and YOUTUBE_CLIENT_SECRET in .env
announcement_created: Notice saved
announcement_updated: Notice updated
announcement_destroyed: Notice deleted
common:
free_plan: Free
yes: "Yes"
no: "No"
dash: "—"
live_page: Live page
auth:
new:
title: Admin login
username_label: Username
password_label: Password
submit: Log in
initial_credentials_html: "Initial credentials: <code>admin</code> / <code>AdminPass123</code>. Change the password after the first login."
passwords:
edit:
title: Change password
current_password_label: Current password
new_password_label: "New password (min. 8, at least 3 character types)"
confirm_password_label: Confirm new password
submit: Save password
cancel: Cancel
dashboard:
kpi:
active_sessions: Active sessions
active_sessions_sub: live right now
today: Streamed today
today_sub: "%{duration} of streaming"
month: Streamed this month
month_sub: "%{duration} total"
teams: Teams
teams_sub: "%{count} users"
cpu: CPU
cpu_sub: "load %{one} / %{five} / %{fifteen}"
ram: RAM
ram_sub: "%{used} / %{total}"
network: Bandwidth (total)
network_sub: "↑ %{tx} · ↓ %{rx}"
recordings: Recordings in archive
recordings_sub: "%{count} recordings"
charts:
cpu: CPU (%)
ram: RAM (%)
ops_panel:
title: Platform status (Ops)
critical: "%{count} critical incident(s) open"
view_dashboard: View Ops dashboard
warnings: "%{count} warning(s)"
dashboard_link: Ops dashboard
none_html: "No open incidents. %{link}"
disk:
system_title: System disk
free_label: "Free: %{free} (%{percent}% used)"
not_available: Disk metrics not available
recordings_title: Recordings archive
recordings_content: "Recordings content: %{size}"
recordings_not_mounted: "Path %{path} not mounted"
sessions:
title: Active sessions
table:
match: Match
status: Status
ingest: Ingest
start: Start
link: Link
none: No active session right now.
detail: Details
stop: Stop
stop_confirm: End this session?
regia: Control
teams:
title: Teams
matches_count: "%{count} matches"
view_all: "View clubs (%{count} teams)"
stream_nodes:
title: Streaming nodes
providers: "Cloud: %{cloud} · DNS: %{dns}"
actions_title: Actions
table_title: Registered nodes
empty: No nodes registered.
free_slots:
one: "%{count} free"
other: "%{count} free"
kpi:
autoscaler: Autoscaler
kill_switch: KILL
kind: "%{kind} mode"
free_slots: Free slots
soft_slots: "soft threshold ≤ %{soft}"
spare: Spare
warm_spare: warm spares ready
overflow: Overflow
overflow_nodes: cloud/lab nodes
budget: Estimated budget
budget_of: "of €%{budget}/mo (%{ok})"
autoscale: "Autoscaler %{enabled} · free_slots=%{free} (soft≤%{soft}) · spare=%{spare}/%{warm} · overflow=%{overflow}/%{max} · kind=%{kind}"
autoscale_budget: "budget €%{eur}/€%{budget} (%{ok})"
kill_switch_active: "KILL-SWITCH ACTIVE"
engage_kill_switch: "Kill-switch ON"
clear_kill_switch: "Kill-switch OFF"
kill_switch_confirm: "Immediately block the autoscaler? Existing nodes stay up."
provision_lab: Provision lab
provision_cloud: Provision Hetzner
provision_cloud_confirm: "Create a Hetzner Cloud server + DNS record on mltv-stream.net? Billing applies until destroyed."
hetzner_token_missing: "Set HCLOUD_TOKEN to enable Cloud provisioning."
drain: Drain
destroy: Delete
destroy_confirm: "Delete node %{slug}?"
hosts_title: Lab DNS records (/etc/hosts snippet)
col:
slug: Slug
role: Role
status: Status
slots: Slots
hostname: Hostname
provider: Provider
ops:
kpi:
critical: Critical open
warning: Warnings open
total: Total open
open:
title: Open incidents
table:
severity: Severity
kind: Type
title: Title
occurrences: Occ.
last_seen: Last seen
none: No open incidents. The platform looks healthy.
actions:
acknowledge: Acknowledge
resolve: Resolve
mute: Mute 24h
resolved:
title: Resolved (last 30 days)
table:
resolved_at: Resolved
none: No incidents resolved recently.
clubs:
index:
title: Clubs & teams
subtitle_html: "Complimentary subscriptions (sponsors / promotions) and YouTube status per team. Stripe payments: %{billing_link}."
billing_link: Billing
table:
club: Club
plan: Plan
teams: Teams
comped: Comp
stripe: Stripe
manage: Manage
invoices: Invoices
show:
back: "← Clubs & teams"
sport_label: "Sport: %{sport}"
recordings_archive: Recordings archive
billing_link: Payments & invoices
youtube_platform_link: Platform YouTube channel
youtube_club_label: "Club YouTube:"
youtube_connected: (connected)
youtube_premium_full_not_connected: Premium Full — club channel not connected (using Match Live TV)
no_channel_hint_html: "Without a connected channel, the app uses the Match Live TV channel. %{link}."
link_channel: Connect channel (club page)
teams_title: Teams
no_teams: No teams registered.
table:
team: Team
sport: Sport
matches_and_details: Matches & details
replay: Replays
comped:
title: Complimentary subscription
description: "Sponsor or promotion: grant Premium Light/Full without a Stripe payment. Revocable at any time."
active_label: "Active:"
since_label_html: "Since %{date}"
by_admin: "· admin %{username}"
stripe_note: "Note: a linked Stripe subscription also exists; the comp takes priority over the plan."
revoke_button: Revoke comp (revert to Free or restore Stripe)
revoke_confirm: "Revoke the complimentary subscription for %{club}?"
current_plan: "Current plan: %{plan}"
stripe_active: "· active Stripe payment"
plan_label: Plan
reason_label: "Reason (e.g. 2026 sponsor)"
reason_placeholder: "Sponsor, promotion…"
grant_button: Grant comp
teams:
show:
back: "← %{club}"
sport_label: "Sport: %{sport}"
club_label_html: "Club: %{club} · %{replay_link} · %{billing_link}"
replay_link: Team replays
billing_link: Payments & invoices
youtube_label: "YouTube:"
youtube_platform_default_no_oauth: ", default without club OAuth"
youtube_platform_channel: "(platform channel%{suffix})"
youtube_club_channel: (club channel)
youtube_not_ready: not ready
no_channel_hint_html: "Without a connected channel, the app uses the Match Live TV channel. %{link}."
link_channel: Connect channel (club page)
matches_title: Matches
sessions:
index:
title: Stream sessions
lead: Search by club, team, opponent or venue. Filter by status, platform, node and date range.
results: "Showing %{shown} of %{total}"
none: No sessions match these filters.
filters:
q: Search
q_placeholder: Club, team, opponent…
status: Status
platform: Platform
club: Club
node: Ingest node
from: From
to: To
any: All
apply: Filter
reset: Reset
table:
club: Club
match: Match
status: Status
started: Started
ended: Ended
duration: Duration
ingest: Ingest
disconnects: Disconnects
link: Link
detail: Details
regia: Control
show:
title: "Session %{id}"
heading: Session details
back: "← Back to sessions"
club_label: "Club:"
summary_title: Summary
timing_title: Timing
ingest_title: Ingest & media
devices_title: Devices
events_title: Events
events_none: No events recorded.
status_label: "Status:"
stop_button: End session
stop_confirm: "End the broadcast? The RTMP path will be removed and the status will move to ended."
match_label: "Match: %{team} vs %{opponent}"
youtube_studio: YouTube Studio
broadcast: Broadcast
open_replays: Open club replays
audio_muted: Audio muted
audio_on: Audio on
ingest_node: "Ingest node:"
rtmp_ingest: "RTMP ingest:"
fields:
id: ID
club: Club
team: Team
opponent: Opponent
operator: Operator
platform: Platform
privacy: Privacy
quality: Quality
min_quality: Min quality
audio: Audio
created: Created
started: Started
ended: Ended
duration: Duration
disconnects: Disconnects
scheduled: Scheduled match
location: Venue
node: Node
rtmp: RTMP ingest
hls: HLS
recording: Replay
devices:
role: Role
network: Network
battery: Battery
bitrate: Bitrate
fps: FPS
last_seen: Last seen
table:
type: Type
when: When
meta: Details
links:
watch_title: Live link
none: No video link available for this session.
regia_title: Control link
terminated: Session ended — control link not available.
regia_label: Control
valid_until: "Valid until %{date}"
active_exists: An active control link already exists (the URL cannot be retrieved). Generate a new one if you need to share it again.
none_active: No active control link. Generate a link to share with whoever manages the score.
generate_button: Generate control link
ingest:
none: "—"
role:
home: Home-lab
lab: Lab
cloud: Hetzner
billing:
index:
title: Payments to invoice
description: Stripe payments that are paid but have no invoice PDF yet. Generate the PDF in your systems, then upload it here — it will be linked to the payment and emailed to the customer.
filter_label: "Filter clubs:"
filter_all: All
incomplete_profile_warning: Billing details incomplete
no_billing_data: No billing details — the customer must complete their profile.
pdf_label: Invoice PDF
upload_button: Upload PDF and send to customer
none_pending: "No payments awaiting an invoice%{club}."
none_pending_for_club: " for %{club}"
uploaded_title: Invoices already uploaded
table:
date: Date
club: Club
description: Description
amount: Amount
invoice: Invoice
status: Status
back_dashboard: "← Dashboard"
billing_invoices:
index:
title: "Billing — %{club}"
back_dashboard: "← Dashboard"
new_invoice: New invoice (no payment)
payments_title: Payments
table:
date: Date
description: Description
amount: Amount
invoice: Invoice
pdf_suffix: " (PDF)"
edit_send_pdf: Edit / send PDF
create_invoice: Create invoice
no_payments: No payments recorded for this club.
all_invoices_title: All invoices
table2:
number: Number
date: Date
amount: Amount
status: Status
payment: Payment
edit: Edit
no_invoices: No invoices.
new:
title: "New invoice — %{club}"
linked_payment: "Linked to the payment of %{date} (%{amount})."
number_label: Invoice number
issued_on_label: Issue date
amount_label: "Amount (€)"
notes_label: Internal notes (optional)
hint: Save the draft, then upload the PDF and send it to the customer from the next screen.
submit: Create invoice draft
back: "← Payments & invoices"
edit:
title: "Invoice %{number} — %{club}"
status_label: "Status:"
sent_at: "· Sent on %{date}"
number_label: Invoice number
issued_on_label: Issue date
amount_label: "Amount (€)"
payment_info: "Payment: %{description} — %{amount}"
pdf_label: Invoice PDF
pdf_already: "PDF already uploaded: %{filename}"
notes_label: Internal notes
save_draft: Save draft
issue_send: Issue and send by email
issue_confirm: "Send the invoice to %{email}?"
back: "← Payments & invoices"
youtube:
platform_token:
title: Match Live TV channel token
page_title: "YouTube token — Match Live TV"
channel_label: "Channel: %{title}"
success: "Connection successful. Copy this line right away:"
env_hint_html: "Add to <code>/opt/matchlivetv/infra/.env</code>:"
not_shown_again_html: "It won't be shown again. Then run: <code>docker compose -f docker-compose.prod.yml restart rails sidekiq</code>"
no_refresh_token_html: "Google did not return a refresh token. In your <a href=\"https://myaccount.google.com/permissions\" target=\"_blank\" rel=\"noopener\">Google account → app access</a>, revoke «Match Live TV», then repeat from <a href=\"/admin/youtube/platform\">/admin/youtube/platform</a>."
back_dashboard: "← Admin dashboard"
club_recordings:
index:
title: "Replays — %{club}"
announcements:
index:
title: Notices
lead: Messages for the apps, the public website and the logged-in area — maintenance, updates or announcements.
new: New notice
table_title: Notices
none: No notices yet. Create one to notify the apps and the website.
new:
title: New notice
edit:
title: Edit notice
table:
status: Status
kind: Type
title: Message
channels: Destinations
window: Window
actions:
edit: Edit
delete: Delete
delete_confirm: Delete this notice? It will no longer appear in the selected destinations.
kind:
info: Information
maintenance: Maintenance
update: App update
severity:
info: Info
warning: Warning
critical: Critical
status:
draft: Draft
published: Published
archived: Archived
channels:
android: Android app
ios: iOS app
web_public: Public website
web_private: Logged-in area
window:
always: Always (while published)
from: "From %{time}"
until: "Until %{time}"
form:
kind: Type
severity: Severity
status: Status
channels: Where to show it
channels_hint: "Select one or more destinations. Android and iOS are independent: create two notices if the copy should differ. The logged-in area is visible after sign-in (club, teams, account)."
title: Title
body: Body
starts_at: Visible from
ends_at: Visible until
window_hint: Leave empty to show immediately while published.
action_url: Link (optional)
action_url_hint: For updates, an empty URL opens that platform's store (Play Store on Android, App Store on iOS).
action_label: Button label
locales_legend: Copy by language
locales_hint: Fill in every app language (Italian, English, French, German, Spanish). Italian is required; missing languages fall back to English, then Italian.
locale_required: required
dismissible: Users can dismiss the notice
dismissible_hint: Uncheck for maintenance notices that should stay visible.
submit_create: Save notice
submit_update: Update notice
cancel: Cancel