Compare commits
8 commits
bb455f793a
...
b5d52426b6
Author | SHA1 | Date | |
---|---|---|---|
b5d52426b6 | |||
65308f8bda | |||
f7f0ebbb25 | |||
7380d3da3c | |||
a5df93e4b7 | |||
094b0f0324 | |||
9e9d8ffdaf | |||
cf28aa5295 |
17 changed files with 952 additions and 76 deletions
|
@ -83,7 +83,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id={"#{@id}-content"}>
|
<div id={"#{@id}-content"}>
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</div>
|
</div>
|
||||||
</.focus_wrap>
|
</.focus_wrap>
|
||||||
</div>
|
</div>
|
||||||
|
@ -128,9 +128,9 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6">
|
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6">
|
||||||
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
|
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
|
||||||
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
|
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
|
||||||
<%= @title %>
|
{@title}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 text-sm leading-5"><%= msg %></p>
|
<p class="mt-2 text-sm leading-5">{msg}</p>
|
||||||
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}>
|
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}>
|
||||||
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" />
|
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -161,7 +161,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
phx-connected={hide("#client-error")}
|
phx-connected={hide("#client-error")}
|
||||||
hidden
|
hidden
|
||||||
>
|
>
|
||||||
<%= gettext("Attempting to reconnect") %>
|
{gettext("Attempting to reconnect")}
|
||||||
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
|
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
|
||||||
</.flash>
|
</.flash>
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
phx-connected={hide("#server-error")}
|
phx-connected={hide("#server-error")}
|
||||||
hidden
|
hidden
|
||||||
>
|
>
|
||||||
<%= gettext("Hang in there while we get back on track") %>
|
{gettext("Hang in there while we get back on track")}
|
||||||
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
|
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
|
||||||
</.flash>
|
</.flash>
|
||||||
</div>
|
</div>
|
||||||
|
@ -207,12 +207,12 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
~H"""
|
~H"""
|
||||||
<.form :let={f} for={@for} as={@as} {@rest}>
|
<.form :let={f} for={@for} as={@as} {@rest}>
|
||||||
<div class="mt-10 space-y-8 bg-white dark:bg-zinc-950">
|
<div class="mt-10 space-y-8 bg-white dark:bg-zinc-950">
|
||||||
<%= render_slot(@inner_block, f) %>
|
{render_slot(@inner_block, f)}
|
||||||
<div
|
<div
|
||||||
:for={action <- @actions}
|
:for={action <- @actions}
|
||||||
class="mt-2 flex items-center justify-between gap-6 dark:text-zinc-100"
|
class="mt-2 flex items-center justify-between gap-6 dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<%= render_slot(action, f) %>
|
{render_slot(action, f)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</.form>
|
</.form>
|
||||||
|
@ -244,7 +244,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</button>
|
</button>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -328,9 +328,9 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
class="rounded border-zinc-300 text-zinc-900 focus:ring-0"
|
class="rounded border-zinc-300 text-zinc-900 focus:ring-0"
|
||||||
{@rest}
|
{@rest}
|
||||||
/>
|
/>
|
||||||
<%= @label %>
|
{@label}
|
||||||
</label>
|
</label>
|
||||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
<.error :for={msg <- @errors}>{msg}</.error>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -338,7 +338,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
def input(%{type: "select"} = assigns) do
|
def input(%{type: "select"} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<.label for={@id}><%= @label %></.label>
|
<.label for={@id}>{@label}</.label>
|
||||||
<select
|
<select
|
||||||
id={@id}
|
id={@id}
|
||||||
name={@name}
|
name={@name}
|
||||||
|
@ -346,10 +346,10 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
multiple={@multiple}
|
multiple={@multiple}
|
||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
<option :if={@prompt} value=""><%= @prompt %></option>
|
<option :if={@prompt} value="">{@prompt}</option>
|
||||||
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
|
{Phoenix.HTML.Form.options_for_select(@options, @value)}
|
||||||
</select>
|
</select>
|
||||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
<.error :for={msg <- @errors}>{msg}</.error>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -357,7 +357,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
def input(%{type: "textarea"} = assigns) do
|
def input(%{type: "textarea"} = assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<.label for={@id}><%= @label %></.label>
|
<.label for={@id}>{@label}</.label>
|
||||||
<textarea
|
<textarea
|
||||||
id={@id}
|
id={@id}
|
||||||
name={@name}
|
name={@name}
|
||||||
|
@ -368,7 +368,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
||||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
<.error :for={msg <- @errors}>{msg}</.error>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -377,7 +377,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
def input(assigns) do
|
def input(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<.label for={@id}><%= @label %></.label>
|
<.label for={@id}>{@label}</.label>
|
||||||
<input
|
<input
|
||||||
type={@type}
|
type={@type}
|
||||||
name={@name}
|
name={@name}
|
||||||
|
@ -390,7 +390,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
/>
|
/>
|
||||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
<.error :for={msg <- @errors}>{msg}</.error>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -404,7 +404,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
def label(assigns) do
|
def label(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800 dark:text-zinc-200">
|
<label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800 dark:text-zinc-200">
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</label>
|
</label>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -418,7 +418,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
~H"""
|
~H"""
|
||||||
<p class="mt-3 flex gap-3 text-sm leading-6 text-rose-600">
|
<p class="mt-3 flex gap-3 text-sm leading-6 text-rose-600">
|
||||||
<.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" />
|
<.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" />
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -437,13 +437,13 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
<header class={[@actions != [] && "flex items-center justify-between gap-6", @class]}>
|
<header class={[@actions != [] && "flex items-center justify-between gap-6", @class]}>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-lg font-semibold leading-8 text-zinc-800 dark:text-zinc-200">
|
<h1 class="text-lg font-semibold leading-8 text-zinc-800 dark:text-zinc-200">
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</h1>
|
</h1>
|
||||||
<p :if={@subtitle != []} class="mt-2 text-sm leading-6 text-zinc-600 dark:text-zinc-100">
|
<p :if={@subtitle != []} class="mt-2 text-sm leading-6 text-zinc-600 dark:text-zinc-100">
|
||||||
<%= render_slot(@subtitle) %>
|
{render_slot(@subtitle)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-none"><%= render_slot(@actions) %></div>
|
<div class="flex-none">{render_slot(@actions)}</div>
|
||||||
</header>
|
</header>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -484,9 +484,9 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
<table class="w-[40rem] mt-11 sm:w-full">
|
<table class="w-[40rem] mt-11 sm:w-full">
|
||||||
<thead class="text-sm text-left leading-6 text-zinc-500">
|
<thead class="text-sm text-left leading-6 text-zinc-500">
|
||||||
<tr>
|
<tr>
|
||||||
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal"><%= col[:label] %></th>
|
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal">{col[:label]}</th>
|
||||||
<th :if={@action != []} class="relative p-0 pb-4">
|
<th :if={@action != []} class="relative p-0 pb-4">
|
||||||
<span class="sr-only"><%= gettext("Actions") %></span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -504,7 +504,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
<div class="block py-4 pr-6">
|
<div class="block py-4 pr-6">
|
||||||
<span class="absolute -inset-y-px right-0 -left-4 group-hover:bg-zinc-50 sm:rounded-l-xl" />
|
<span class="absolute -inset-y-px right-0 -left-4 group-hover:bg-zinc-50 sm:rounded-l-xl" />
|
||||||
<span class={["relative", i == 0 && "font-semibold text-zinc-900"]}>
|
<span class={["relative", i == 0 && "font-semibold text-zinc-900"]}>
|
||||||
<%= render_slot(col, @row_item.(row)) %>
|
{render_slot(col, @row_item.(row))}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -515,7 +515,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
:for={action <- @action}
|
:for={action <- @action}
|
||||||
class="relative ml-4 font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
|
class="relative ml-4 font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
|
||||||
>
|
>
|
||||||
<%= render_slot(action, @row_item.(row)) %>
|
{render_slot(action, @row_item.(row))}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -545,8 +545,8 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
<div class="mt-14">
|
<div class="mt-14">
|
||||||
<dl class="-my-4 divide-y divide-zinc-100">
|
<dl class="-my-4 divide-y divide-zinc-100">
|
||||||
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
|
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
|
||||||
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt>
|
<dt class="w-1/4 flex-none text-zinc-500">{item.title}</dt>
|
||||||
<dd class="text-zinc-700"><%= render_slot(item) %></dd>
|
<dd class="text-zinc-700">{render_slot(item)}</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
@ -571,7 +571,7 @@ defmodule ExmrWeb.CoreComponents do
|
||||||
class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
|
class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
|
||||||
>
|
>
|
||||||
<.icon name="hero-arrow-left-solid" class="h-3 w-3" />
|
<.icon name="hero-arrow-left-solid" class="h-3 w-3" />
|
||||||
<%= render_slot(@inner_block) %>
|
{render_slot(@inner_block)}
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<img src={~p"/images/logo.svg"} width="36" />
|
<img src={~p"/images/logo.svg"} width="36" />
|
||||||
</a>
|
</a>
|
||||||
<p class="bg-brand/5 text-brand rounded-full px-2 font-medium leading-6">
|
<p class="bg-brand/5 text-brand rounded-full px-2 font-medium leading-6">
|
||||||
v<%= Application.spec(:exmr, :vsn) %>
|
v{Application.spec(:exmr, :vsn)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,6 +13,6 @@
|
||||||
<main class="px-4 py-20 sm:px-6 lg:px-8">
|
<main class="px-4 py-20 sm:px-6 lg:px-8">
|
||||||
<div class="mx-auto max-w-2xl">
|
<div class="mx-auto max-w-2xl">
|
||||||
<.flash_group flash={@flash} />
|
<.flash_group flash={@flash} />
|
||||||
<%= @inner_content %>
|
{@inner_content}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="csrf-token" content={get_csrf_token()} />
|
<meta name="csrf-token" content={get_csrf_token()} />
|
||||||
<.live_title suffix=" · Phoenix Framework">
|
<.live_title suffix=" · Phoenix Framework">
|
||||||
<%= assigns[:page_title] || "Exmr" %>
|
{assigns[:page_title] || "Exmr"}
|
||||||
</.live_title>
|
</.live_title>
|
||||||
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
|
<link phx-track-static rel="stylesheet" href={~p"/assets/app.css"} />
|
||||||
<script>
|
<script>
|
||||||
|
@ -23,14 +23,14 @@
|
||||||
<DarkMode.button />
|
<DarkMode.button />
|
||||||
<%= if @current_user do %>
|
<%= if @current_user do %>
|
||||||
<li class="text-[0.8125rem] leading-6 text-zinc-900 dark:text-zinc-300">
|
<li class="text-[0.8125rem] leading-6 text-zinc-900 dark:text-zinc-300">
|
||||||
<%= @current_user.email %>
|
{@current_user.email}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<.link
|
<.link
|
||||||
href={~p"/users/settings"}
|
href={~p"/users/settings"}
|
||||||
class="text-[0.8125rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-100"
|
class="text-[0.8125rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-100"
|
||||||
>
|
>
|
||||||
Settings
|
{gettext("Settings")}
|
||||||
</.link>
|
</.link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
method="delete"
|
method="delete"
|
||||||
class="text-[0.8125rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-100"
|
class="text-[0.8125rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-100"
|
||||||
>
|
>
|
||||||
Log out
|
{gettext("Log out")}
|
||||||
</.link>
|
</.link>
|
||||||
</li>
|
</li>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
@ -61,6 +61,6 @@
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
<%= @inner_content %>
|
{@inner_content}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -44,20 +44,20 @@
|
||||||
<h1 class="mt-10 flex items-center text-sm font-semibold leading-6 text-purple-400">
|
<h1 class="mt-10 flex items-center text-sm font-semibold leading-6 text-purple-400">
|
||||||
ExMR
|
ExMR
|
||||||
<small class="bg-brand/5 text-[0.8125rem] ml-3 rounded-full px-2 font-medium leading-6 text-purple-400">
|
<small class="bg-brand/5 text-[0.8125rem] ml-3 rounded-full px-2 font-medium leading-6 text-purple-400">
|
||||||
v<%= Application.spec(:exmr, :vsn) %>
|
v{Application.spec(:exmr, :vsn)}
|
||||||
</small>
|
</small>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-zinc-900 dark:text-zinc-200/90 text-balance">
|
<p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-zinc-900 dark:text-zinc-200/90 text-balance">
|
||||||
hell yeah
|
{gettext("A simple, modern, and fast exam management system.")}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-4 text-base leading-7 text-zinc-600 dark:text-zinc-300">
|
<p class="mt-4 text-base leading-7 text-zinc-600 dark:text-zinc-300">
|
||||||
y'all really though i'm gonna be serious? lol
|
{gettext("Built using Phoenix LiveView, Ecto, and TailwindCSS by @vavakado")}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="w-full sm:w-auto">
|
<div class="w-full sm:w-auto">
|
||||||
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-3">
|
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-3">
|
||||||
<a
|
<a
|
||||||
href="https://git.vavakado.com/vavakado/exmr"
|
href="https://git.vavakado.xyz/vavakado/exmr"
|
||||||
class="group relative rounded-2xl px-6 py-4 text-sm font-semibold leading-6 text-zinc-900 sm:py-6"
|
class="group relative rounded-2xl px-6 py-4 text-sm font-semibold leading-6 text-zinc-900 sm:py-6"
|
||||||
>
|
>
|
||||||
<span class="absolute inset-0 rounded-2xl bg-zinc-50 transition group-hover:bg-zinc-100 dark:bg-zinc-800 dark:group-hover:bg-zinc-900/95 sm:group-hover:scale-105">
|
<span class="absolute inset-0 rounded-2xl bg-zinc-50 transition group-hover:bg-zinc-100 dark:bg-zinc-800 dark:group-hover:bg-zinc-900/95 sm:group-hover:scale-105">
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center py-8 font-bold text-3xl text-red-600">
|
<div class="text-center py-8 font-bold text-3xl text-red-600">
|
||||||
<.link navigate={~p"/exams"} class="underline hover:text-red-400 transition-all ease-in-out">
|
<.link navigate={~p"/exams"} class="underline hover:text-red-400 transition-all ease-in-out">
|
||||||
exams
|
{gettext("Exams")}
|
||||||
</.link>
|
</.link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
7
lib/exmr_web/helpers.ex
Normal file
7
lib/exmr_web/helpers.ex
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
defmodule ExmrWeb.LiveHelpers do
|
||||||
|
def on_mount(:default, _params, session, socket) do
|
||||||
|
locale = session["locale"] || "en"
|
||||||
|
Gettext.put_locale(locale)
|
||||||
|
{:cont, socket}
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,8 +8,10 @@ defmodule ExmrWeb.ExamLive.FormComponent do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<.header>
|
<.header>
|
||||||
<%= @title %>
|
{@title}
|
||||||
<:subtitle>Use this form to manage exam records in your database.</:subtitle>
|
<:subtitle>
|
||||||
|
{gettext("Use this form to manage exam records in your database.")}
|
||||||
|
</:subtitle>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<.simple_form
|
<.simple_form
|
||||||
|
@ -19,11 +21,11 @@ defmodule ExmrWeb.ExamLive.FormComponent do
|
||||||
phx-change="validate"
|
phx-change="validate"
|
||||||
phx-submit="save"
|
phx-submit="save"
|
||||||
>
|
>
|
||||||
<.input field={@form[:subject]} type="text" label="Subject" />
|
<.input field={@form[:subject]} type="text" label={gettext("Subject")} />
|
||||||
<.input field={@form[:description]} type="text" label="Description" />
|
<.input field={@form[:description]} type="text" label={gettext("Description")} />
|
||||||
<.input field={@form[:date]} type="date" label="Date" />
|
<.input field={@form[:date]} type="date" label={gettext("Date")} />
|
||||||
<:actions>
|
<:actions>
|
||||||
<.button phx-disable-with="Saving...">Save Exam</.button>
|
<.button phx-disable-with={gettext("Saving...")}>{gettext("Save Exam")}</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.simple_form>
|
</.simple_form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@ defmodule ExmrWeb.ExamLive.Index do
|
||||||
|
|
||||||
defp apply_action(socket, :new, _params) do
|
defp apply_action(socket, :new, _params) do
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, "New Exam")
|
|> assign(:page_title, gettext("New Exam"))
|
||||||
|> assign(:exam, %Exam{})
|
|> assign(:exam, %Exam{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
<.header>
|
<.header>
|
||||||
Listing Exams
|
{gettext("Listing Exams")}
|
||||||
<div>
|
<div>
|
||||||
<button phx-click="sort" phx-value-by="subject" class="font-light">Sort by Subject</button>
|
<button phx-click="sort" phx-value-by="subject" class="font-light">
|
||||||
|
{gettext("Sort by Subject")}
|
||||||
|
</button>
|
||||||
<a>|</a>
|
<a>|</a>
|
||||||
|
|
||||||
<button phx-click="sort" phx-value-by="date" class="font-light">Sort by Date</button>
|
<button phx-click="sort" phx-value-by="date" class="font-light">
|
||||||
|
{gettext("Sort by Date")}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.link patch={~p"/exams/new"}>
|
<.link patch={~p"/exams/new"}>
|
||||||
<.button class="dark:bg-sky-300 text-white dark:text-black/80 dark:hover:bg-sky-400">
|
<.button class="dark:bg-sky-300 text-white dark:text-black/80 dark:hover:bg-sky-400">
|
||||||
New Exam
|
{gettext("New Exam")}
|
||||||
</.button>
|
</.button>
|
||||||
</.link>
|
</.link>
|
||||||
</:actions>
|
</:actions>
|
||||||
|
@ -18,9 +22,17 @@
|
||||||
<div class="divide-y">
|
<div class="divide-y">
|
||||||
<div :for={exam <- @exams} class="py-2 flex gap-2">
|
<div :for={exam <- @exams} class="py-2 flex gap-2">
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<div class="font-bold"><%= exam.subject %></div>
|
<div class="font-bold">{exam.subject}</div>
|
||||||
<div class="font-sm">
|
<div class="font-sm">
|
||||||
<%= exam.date %> | In <b><%= Date.diff(exam.date, Date.utc_today()) %></b> days
|
{exam.date} |
|
||||||
|
<b>
|
||||||
|
{case Date.diff(exam.date, Date.utc_today()) do
|
||||||
|
0 -> gettext("Today")
|
||||||
|
1 -> gettext("Tommorow")
|
||||||
|
x when x > 1 -> ngettext("Tomorrow", "%{count} days left", x)
|
||||||
|
x when x < 0 -> ngettext("Yesterday", "%{count} days passed", x * -1)
|
||||||
|
end}
|
||||||
|
</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
@ -28,14 +40,14 @@
|
||||||
phx-value-id={exam.id}
|
phx-value-id={exam.id}
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-3 rounded-md"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-3 rounded-md"
|
||||||
>
|
>
|
||||||
Edit
|
{gettext("Edit")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
phx-click="remove"
|
phx-click="remove"
|
||||||
phx-value-id={exam.id}
|
phx-value-id={exam.id}
|
||||||
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-3 rounded-md"
|
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-3 rounded-md"
|
||||||
>
|
>
|
||||||
Remove
|
{gettext("Remove")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<.header>
|
<.header>
|
||||||
exam №<%= @exam.id %>
|
exam №{@exam.id}
|
||||||
<:subtitle>очередная контрольная работа по <strong><%= @exam.subject %></strong></:subtitle>
|
<:subtitle>очередная контрольная работа по <strong>{@exam.subject}</strong></:subtitle>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.link patch={~p"/exams/#{@exam}/show/edit"} phx-click={JS.push_focus()}>
|
<.link patch={~p"/exams/#{@exam}/show/edit"} phx-click={JS.push_focus()}>
|
||||||
<.button>изменить</.button>
|
<.button>изменить</.button>
|
||||||
|
@ -9,8 +9,8 @@
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<.list>
|
<.list>
|
||||||
<:item title="Description"><%= @exam.description %></:item>
|
<:item title="Description">{@exam.description}</:item>
|
||||||
<:item title="Date"><%= @exam.date %></:item>
|
<:item title="Date">{@exam.date}</:item>
|
||||||
</.list>
|
</.list>
|
||||||
|
|
||||||
<.back navigate={~p"/exams"}>Back to exams</.back>
|
<.back navigate={~p"/exams"}>Back to exams</.back>
|
||||||
|
|
|
@ -6,8 +6,8 @@ defmodule ExmrWeb.UserSettingsLive do
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<.header class="text-center">
|
<.header class="text-center">
|
||||||
Account Settings
|
{gettext("Account Settings")}
|
||||||
<:subtitle>Manage your account email address and password settings</:subtitle>
|
<:subtitle>{gettext("Manage your account email address and password settings")}</:subtitle>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<div class="space-y-12 divide-y">
|
<div class="space-y-12 divide-y">
|
||||||
|
@ -18,18 +18,20 @@ defmodule ExmrWeb.UserSettingsLive do
|
||||||
phx-submit="update_email"
|
phx-submit="update_email"
|
||||||
phx-change="validate_email"
|
phx-change="validate_email"
|
||||||
>
|
>
|
||||||
<.input field={@email_form[:email]} type="email" label="Email" required />
|
<.input field={@email_form[:email]} type="email" label={gettext("Email")} required />
|
||||||
<.input
|
<.input
|
||||||
field={@email_form[:current_password]}
|
field={@email_form[:current_password]}
|
||||||
name="current_password"
|
name="current_password"
|
||||||
id="current_password_for_email"
|
id="current_password_for_email"
|
||||||
type="password"
|
type="password"
|
||||||
label="Current password"
|
label={gettext("Current password")}
|
||||||
value={@email_form_current_password}
|
value={@email_form_current_password}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.button phx-disable-with="Changing...">Change Email</.button>
|
<.button phx-disable-with={gettext("Changing...")}>
|
||||||
|
{gettext("Change Email")}
|
||||||
|
</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.simple_form>
|
</.simple_form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,23 +51,30 @@ defmodule ExmrWeb.UserSettingsLive do
|
||||||
id="hidden_user_email"
|
id="hidden_user_email"
|
||||||
value={@current_email}
|
value={@current_email}
|
||||||
/>
|
/>
|
||||||
<.input field={@password_form[:password]} type="password" label="New password" required />
|
<.input
|
||||||
|
field={@password_form[:password]}
|
||||||
|
type="password"
|
||||||
|
label={gettext("New password")}
|
||||||
|
required
|
||||||
|
/>
|
||||||
<.input
|
<.input
|
||||||
field={@password_form[:password_confirmation]}
|
field={@password_form[:password_confirmation]}
|
||||||
type="password"
|
type="password"
|
||||||
label="Confirm new password"
|
label={gettext("Confirm new password")}
|
||||||
/>
|
/>
|
||||||
<.input
|
<.input
|
||||||
field={@password_form[:current_password]}
|
field={@password_form[:current_password]}
|
||||||
name="current_password"
|
name="current_password"
|
||||||
type="password"
|
type="password"
|
||||||
label="Current password"
|
label={gettext("Current password")}
|
||||||
id="current_password_for_password"
|
id="current_password_for_password"
|
||||||
value={@current_password}
|
value={@current_password}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.button phx-disable-with="Changing...">Change Password</.button>
|
<.button phx-disable-with={gettext("Changing...")}>
|
||||||
|
{gettext("Change Password")}
|
||||||
|
</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.simple_form>
|
</.simple_form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,10 +86,10 @@ defmodule ExmrWeb.UserSettingsLive do
|
||||||
socket =
|
socket =
|
||||||
case Users.update_user_email(socket.assigns.current_user, token) do
|
case Users.update_user_email(socket.assigns.current_user, token) do
|
||||||
:ok ->
|
:ok ->
|
||||||
put_flash(socket, :info, "Email changed successfully.")
|
put_flash(socket, :info, gettext("Email changed successfully."))
|
||||||
|
|
||||||
:error ->
|
:error ->
|
||||||
put_flash(socket, :error, "Email change link is invalid or it has expired.")
|
put_flash(socket, :error, gettext("Email change link is invalid or it has expired."))
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, push_navigate(socket, to: ~p"/users/settings")}
|
{:ok, push_navigate(socket, to: ~p"/users/settings")}
|
||||||
|
@ -127,7 +136,7 @@ defmodule ExmrWeb.UserSettingsLive do
|
||||||
&url(~p"/users/settings/confirm_email/#{&1}")
|
&url(~p"/users/settings/confirm_email/#{&1}")
|
||||||
)
|
)
|
||||||
|
|
||||||
info = "A link to confirm your email change has been sent to the new address."
|
info = gettext("A link to confirm your email change has been sent to the new address.")
|
||||||
{:noreply, socket |> put_flash(:info, info) |> assign(email_form_current_password: nil)}
|
{:noreply, socket |> put_flash(:info, info) |> assign(email_form_current_password: nil)}
|
||||||
|
|
||||||
{:error, changeset} ->
|
{:error, changeset} ->
|
||||||
|
|
67
lib/exmr_web/plug/local_plug.ex
Normal file
67
lib/exmr_web/plug/local_plug.ex
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
defmodule ExmrWeb.Plugs.Locale do
|
||||||
|
import Plug.Conn
|
||||||
|
|
||||||
|
def init(_opts), do: nil
|
||||||
|
|
||||||
|
def call(conn, _opts) do
|
||||||
|
accepted_languages = extract_accept_language(conn)
|
||||||
|
known_locales = Gettext.known_locales(ExmrWeb.Gettext)
|
||||||
|
|
||||||
|
accepted_languages =
|
||||||
|
known_locales --
|
||||||
|
known_locales -- accepted_languages
|
||||||
|
|
||||||
|
case accepted_languages do
|
||||||
|
[locale | _] ->
|
||||||
|
Gettext.put_locale(ExmrWeb.Gettext, locale)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_session(:locale, locale)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Copied from
|
||||||
|
# https://raw.githubusercontent.com/smeevil/set_locale/fd35624e25d79d61e70742e42ade955e5ff857b8/lib/headers.ex
|
||||||
|
def extract_accept_language(conn) do
|
||||||
|
case Plug.Conn.get_req_header(conn, "accept-language") do
|
||||||
|
[value | _] ->
|
||||||
|
value
|
||||||
|
|> String.split(",")
|
||||||
|
|> Enum.map(&parse_language_option/1)
|
||||||
|
|> Enum.sort(&(&1.quality > &2.quality))
|
||||||
|
|> Enum.map(& &1.tag)
|
||||||
|
|> Enum.reject(&is_nil/1)
|
||||||
|
|> ensure_language_fallbacks()
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_language_option(string) do
|
||||||
|
captures = Regex.named_captures(~r/^\s?(?<tag>[\w\-]+)(?:;q=(?<quality>[\d\.]+))?$/i, string)
|
||||||
|
|
||||||
|
quality =
|
||||||
|
case Float.parse(captures["quality"] || "1.0") do
|
||||||
|
{val, _} -> val
|
||||||
|
_ -> 1.0
|
||||||
|
end
|
||||||
|
|
||||||
|
%{tag: captures["tag"], quality: quality}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp ensure_language_fallbacks(tags) do
|
||||||
|
Enum.flat_map(tags, fn tag ->
|
||||||
|
case String.split(tag, "-") do
|
||||||
|
[language, _country_variant] ->
|
||||||
|
if Enum.member?(tags, language), do: [tag], else: [tag, language]
|
||||||
|
|
||||||
|
[_language] ->
|
||||||
|
[tag]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,6 +12,7 @@ defmodule ExmrWeb.Router do
|
||||||
plug :put_root_layout, html: {ExmrWeb.Layouts, :root}
|
plug :put_root_layout, html: {ExmrWeb.Layouts, :root}
|
||||||
plug :protect_from_forgery
|
plug :protect_from_forgery
|
||||||
plug :put_secure_browser_headers
|
plug :put_secure_browser_headers
|
||||||
|
plug ExmrWeb.Plugs.Locale
|
||||||
plug :fetch_current_user
|
plug :fetch_current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ defmodule ExmrWeb.Router do
|
||||||
pipe_through [:browser, :redirect_if_user_is_authenticated]
|
pipe_through [:browser, :redirect_if_user_is_authenticated]
|
||||||
|
|
||||||
live_session :redirect_if_user_is_authenticated,
|
live_session :redirect_if_user_is_authenticated,
|
||||||
on_mount: [{ExmrWeb.UserAuth, :redirect_if_user_is_authenticated}] do
|
on_mount: [{ExmrWeb.UserAuth, :redirect_if_user_is_authenticated}, ExmrWeb.LiveHelpers] do
|
||||||
if Exmr.enable_registration() != "false" do
|
if Exmr.enable_registration() != "false" do
|
||||||
live "/users/register", UserRegistrationLive, :new
|
live "/users/register", UserRegistrationLive, :new
|
||||||
end
|
end
|
||||||
|
@ -70,7 +71,7 @@ defmodule ExmrWeb.Router do
|
||||||
pipe_through [:browser, :require_authenticated_user]
|
pipe_through [:browser, :require_authenticated_user]
|
||||||
|
|
||||||
live_session :require_authenticated_user,
|
live_session :require_authenticated_user,
|
||||||
on_mount: [{ExmrWeb.UserAuth, :ensure_authenticated}] do
|
on_mount: [{ExmrWeb.UserAuth, :ensure_authenticated}, ExmrWeb.LiveHelpers] do
|
||||||
if Exmr.enable_registration() == "false" do
|
if Exmr.enable_registration() == "false" do
|
||||||
live "/users/register", UserRegistrationLive, :new
|
live "/users/register", UserRegistrationLive, :new
|
||||||
end
|
end
|
||||||
|
@ -93,7 +94,7 @@ defmodule ExmrWeb.Router do
|
||||||
delete "/users/log_out", UserSessionController, :delete
|
delete "/users/log_out", UserSessionController, :delete
|
||||||
|
|
||||||
live_session :current_user,
|
live_session :current_user,
|
||||||
on_mount: [{ExmrWeb.UserAuth, :mount_current_user}] do
|
on_mount: [{ExmrWeb.UserAuth, :mount_current_user}, ExmrWeb.LiveHelpers] do
|
||||||
live "/users/confirm/:token", UserConfirmationLive, :edit
|
live "/users/confirm/:token", UserConfirmationLive, :edit
|
||||||
live "/users/confirm", UserConfirmationInstructionsLive, :new
|
live "/users/confirm", UserConfirmationInstructionsLive, :new
|
||||||
end
|
end
|
||||||
|
|
225
priv/gettext/default.pot
Normal file
225
priv/gettext/default.pot
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
## This file is a PO Template file.
|
||||||
|
##
|
||||||
|
## "msgid"s here are often extracted from source code.
|
||||||
|
## Add new messages manually only if they're dynamic
|
||||||
|
## messages that can't be statically extracted.
|
||||||
|
##
|
||||||
|
## Run "mix gettext.extract" to bring this file up to
|
||||||
|
## date. Leave "msgstr"s empty as changing them here has no
|
||||||
|
## effect: edit them in PO (.po) files instead.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "A simple, modern, and fast exam management system."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:489
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:164
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Attempting to reconnect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:54
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Built using Phoenix LiveView, Ecto, and TailwindCSS by @vavakado"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:44
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:155
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Error!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:96
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Exams"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:176
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Hang in there while we get back on track"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.ex:32
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:16
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "New Exam"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Something went wrong!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:10
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sort by Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:5
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sort by Subject"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:154
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Success!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:31
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Today"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Tomorrow"
|
||||||
|
msgid_plural "%{count} days left"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:159
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "We can't find the internet"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:80
|
||||||
|
#: lib/exmr_web/components/core_components.ex:134
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:139
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "A link to confirm your email change has been sent to the new address."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:9
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Account Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Change Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:76
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:32
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:75
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Changing..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:63
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:27
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:69
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:21
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:92
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email change link is invalid or it has expired."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:89
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email changed successfully."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:42
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Log out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:10
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Manage your account email address and password settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:57
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:26
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:25
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:24
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Subject"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:13
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Use this form to manage exam records in your database."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:2
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Listing Exams"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Save Exam"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Saving..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:34
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgid_plural "%{count} days passed"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:32
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Tommorow"
|
||||||
|
msgstr ""
|
225
priv/gettext/en/LC_MESSAGES/default.po
Normal file
225
priv/gettext/en/LC_MESSAGES/default.po
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
## "msgid"s in this file come from POT (.pot) files.
|
||||||
|
###
|
||||||
|
### Do not add, change, or remove "msgid"s manually here as
|
||||||
|
### they're tied to the ones in the corresponding POT file
|
||||||
|
### (with the same domain).
|
||||||
|
###
|
||||||
|
### Use "mix gettext.extract --merge" or "mix gettext.merge"
|
||||||
|
### to merge POT files into PO files.
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Language: en\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "A simple, modern, and fast exam management system."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:489
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:164
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Attempting to reconnect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:54
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Built using Phoenix LiveView, Ecto, and TailwindCSS by @vavakado"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:44
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:155
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Error!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:96
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Exams"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:176
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Hang in there while we get back on track"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.ex:32
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:16
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "New Exam"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:51
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Something went wrong!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:10
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sort by Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:5
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sort by Subject"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:154
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Success!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:31
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Today"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Tomorrow"
|
||||||
|
msgid_plural "%{count} days left"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:159
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "We can't find the internet"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:80
|
||||||
|
#: lib/exmr_web/components/core_components.ex:134
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:139
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "A link to confirm your email change has been sent to the new address."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:9
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Account Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Change Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:76
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:32
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:75
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Changing..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:63
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:27
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:69
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:21
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:92
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email change link is invalid or it has expired."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:89
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email changed successfully."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:42
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Log out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:10
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Manage your account email address and password settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:57
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:26
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:25
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:24
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Subject"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:13
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Use this form to manage exam records in your database."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:2
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Listing Exams"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Save Exam"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Saving..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:34
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgid_plural "%{count} days passed"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:32
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Tommorow"
|
||||||
|
msgstr ""
|
BIN
priv/gettext/ru/LC_MESSAGES/default.mo
Normal file
BIN
priv/gettext/ru/LC_MESSAGES/default.mo
Normal file
Binary file not shown.
206
priv/gettext/ru/LC_MESSAGES/default.po
Normal file
206
priv/gettext/ru/LC_MESSAGES/default.po
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
# # This file is a PO Template file.
|
||||||
|
# #
|
||||||
|
# # "msgid"s here are often extracted from source code.
|
||||||
|
# # Add new messages manually only if they're dynamic
|
||||||
|
# # messages that can't be statically extracted.
|
||||||
|
# #
|
||||||
|
# # Run "mix gettext.extract" to bring this file up to
|
||||||
|
# # date. Leave "msgstr"s empty as changing them here has no
|
||||||
|
# # effect: edit them in PO (.po) files instead.
|
||||||
|
# Vladimir Rubin <vavakado@proton.me>, 2024.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: unnamed project\n"
|
||||||
|
"POT-Creation-Date: \n"
|
||||||
|
"PO-Revision-Date: 2024-12-12 18:19+0200\n"
|
||||||
|
"Last-Translator: Vladimir Rubin <vavakado@proton.me>\n"
|
||||||
|
"Language-Team: Russian\n"
|
||||||
|
"Language: ru\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Gtranslator 47.1\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||||
|
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:51
|
||||||
|
msgid "A simple, modern, and fast exam management system."
|
||||||
|
msgstr "Простая, современная и быстрая система управления экзаменами."
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:489
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr "Действия"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:164
|
||||||
|
msgid "Attempting to reconnect"
|
||||||
|
msgstr "Попытка восстановить соединение"
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:54
|
||||||
|
msgid "Built using Phoenix LiveView, Ecto, and TailwindCSS by @vavakado"
|
||||||
|
msgstr ""
|
||||||
|
"Создано с использованием Phoenix LiveView, Ecto и TailwindCSS в исполнении "
|
||||||
|
"@vavakado"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:44
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr "Изменить"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:155
|
||||||
|
msgid "Error!"
|
||||||
|
msgstr "Ошибка!"
|
||||||
|
|
||||||
|
#: lib/exmr_web/controllers/page_html/home.html.heex:96
|
||||||
|
msgid "Exams"
|
||||||
|
msgstr "Экзамены"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:176
|
||||||
|
msgid "Hang in there while we get back on track"
|
||||||
|
msgstr "Держитесь, пока мы не вернемся в строй"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.ex:32
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:16
|
||||||
|
msgid "New Exam"
|
||||||
|
msgstr "Новый экзамен"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:51
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Удалить"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:171
|
||||||
|
msgid "Something went wrong!"
|
||||||
|
msgstr "Что-то пошло не так!"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:10
|
||||||
|
msgid "Sort by Date"
|
||||||
|
msgstr "Сортировать по дате"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:5
|
||||||
|
msgid "Sort by Subject"
|
||||||
|
msgstr "Сортировать по предмету"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:154
|
||||||
|
msgid "Success!"
|
||||||
|
msgstr "Успех!"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:31
|
||||||
|
msgid "Today"
|
||||||
|
msgstr "Сегодня"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:33
|
||||||
|
msgid "Tomorrow"
|
||||||
|
msgid_plural "%{count} days left"
|
||||||
|
msgstr[0] "%{count} день остался"
|
||||||
|
msgstr[1] "%{count} дня осталось"
|
||||||
|
msgstr[2] "%{count} дней осталось"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:159
|
||||||
|
msgid "We can't find the internet"
|
||||||
|
msgstr "Мы не можем найти интернет"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/core_components.ex:80
|
||||||
|
#: lib/exmr_web/components/core_components.ex:134
|
||||||
|
msgid "close"
|
||||||
|
msgstr "закрыть"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:139
|
||||||
|
msgid "A link to confirm your email change has been sent to the new address."
|
||||||
|
msgstr ""
|
||||||
|
"На новый адрес отправлена ссылка для подтверждения изменения электронной "
|
||||||
|
"почты."
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:9
|
||||||
|
msgid "Account Settings"
|
||||||
|
msgstr "Настройки аккаунта"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:33
|
||||||
|
msgid "Change Email"
|
||||||
|
msgstr "Изменить электронную почту"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:76
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr "Изменить пароль"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:32
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:75
|
||||||
|
msgid "Changing..."
|
||||||
|
msgstr "Меняется..."
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:63
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr "Подтвердите новый пароль"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:27
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:69
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr "Текущий пароль"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:21
|
||||||
|
msgid "Email"
|
||||||
|
msgstr "Электронная почта"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:92
|
||||||
|
msgid "Email change link is invalid or it has expired."
|
||||||
|
msgstr ""
|
||||||
|
"Ссылка для изменения электронной почты недействительна или срок ее действия "
|
||||||
|
"истек."
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:89
|
||||||
|
msgid "Email changed successfully."
|
||||||
|
msgstr "Электронная почта успешно изменена."
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:42
|
||||||
|
msgid "Log out"
|
||||||
|
msgstr "Выйти из системы"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:10
|
||||||
|
msgid "Manage your account email address and password settings"
|
||||||
|
msgstr "Управление адресом электронной почты и настройками пароля"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/user_settings_live.ex:57
|
||||||
|
msgid "New password"
|
||||||
|
msgstr "Новый пароль"
|
||||||
|
|
||||||
|
#: lib/exmr_web/components/layouts/root.html.heex:33
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "Настройки"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:26
|
||||||
|
msgid "Date"
|
||||||
|
msgstr "Дата"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:25
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Описание"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:24
|
||||||
|
msgid "Subject"
|
||||||
|
msgstr "Предмет"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:13
|
||||||
|
msgid "Use this form to manage exam records in your database."
|
||||||
|
msgstr ""
|
||||||
|
"Используйте эту форму для управления записями экзаменов в вашей базе данных."
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:2
|
||||||
|
msgid "Listing Exams"
|
||||||
|
msgstr "Список Экзаменов"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
msgid "Save Exam"
|
||||||
|
msgstr "Сохранить экзамен"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/form_component.ex:28
|
||||||
|
msgid "Saving..."
|
||||||
|
msgstr "Сохранение..."
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:34
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgid_plural "%{count} days passed"
|
||||||
|
msgstr[0] "%{count} день прошёл"
|
||||||
|
msgstr[1] "%{count} дня прошло"
|
||||||
|
msgstr[2] "%{count} дней прошло"
|
||||||
|
|
||||||
|
#: lib/exmr_web/live/exam_live/index.html.heex:32
|
||||||
|
msgid "Tommorow"
|
||||||
|
msgstr "Завтра"
|
122
priv/gettext/ru/LC_MESSAGES/errors.po
Normal file
122
priv/gettext/ru/LC_MESSAGES/errors.po
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
# # "msgid"s in this file come from POT (.pot) files.
|
||||||
|
# ##
|
||||||
|
# ## Do not add, change, or remove "msgid"s manually here as
|
||||||
|
# ## they're tied to the ones in the corresponding POT file
|
||||||
|
# ## (with the same domain).
|
||||||
|
# ##
|
||||||
|
# ## Use "mix gettext.extract --merge" or "mix gettext.merge"
|
||||||
|
# ## to merge POT files into PO files.
|
||||||
|
# Vladimir Rubin <vavakado@proton.me>, 2024.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Language: ru\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||||
|
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Project-Id-Version: unnamed project\n"
|
||||||
|
"Last-Translator: Vladimir Rubin <vavakado@proton.me>\n"
|
||||||
|
"Language-Team: Russian\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"PO-Revision-Date: 2024-12-12 18:52+0200\n"
|
||||||
|
"X-Generator: Gtranslator 47.1\n"
|
||||||
|
|
||||||
|
msgid "can't be blank"
|
||||||
|
msgstr "не может быть пустым"
|
||||||
|
|
||||||
|
msgid "has already been taken"
|
||||||
|
msgstr "уже забрали"
|
||||||
|
|
||||||
|
msgid "is invalid"
|
||||||
|
msgstr "недействителен"
|
||||||
|
|
||||||
|
msgid "must be accepted"
|
||||||
|
msgstr "должен быть принят"
|
||||||
|
|
||||||
|
msgid "has invalid format"
|
||||||
|
msgstr "имеет неправильный формат"
|
||||||
|
|
||||||
|
msgid "has an invalid entry"
|
||||||
|
msgstr "имеет недопустимую запись"
|
||||||
|
|
||||||
|
msgid "is reserved"
|
||||||
|
msgstr "зарезервирован"
|
||||||
|
|
||||||
|
msgid "does not match confirmation"
|
||||||
|
msgstr "не соответствует подтверждению"
|
||||||
|
|
||||||
|
msgid "is still associated with this entry"
|
||||||
|
msgstr "по-прежнему связана с этой записью"
|
||||||
|
|
||||||
|
msgid "are still associated with this entry"
|
||||||
|
msgstr "по-прежнему связаны с этой записью"
|
||||||
|
|
||||||
|
msgid "should have %{count} item(s)"
|
||||||
|
msgid_plural "should have %{count} item(s)"
|
||||||
|
msgstr[0] "должен иметь %{count} элементов"
|
||||||
|
msgstr[1] "должен иметь %{count} элемента"
|
||||||
|
msgstr[2] "должен иметь %{count} элементов"
|
||||||
|
|
||||||
|
msgid "should be %{count} character(s)"
|
||||||
|
msgid_plural "should be %{count} character(s)"
|
||||||
|
msgstr[0] "должен быть %{count} символов"
|
||||||
|
msgstr[1] "должен быть %{count} символа"
|
||||||
|
msgstr[2] "должен быть %{count} символов"
|
||||||
|
|
||||||
|
msgid "should be %{count} byte(s)"
|
||||||
|
msgid_plural "should be %{count} byte(s)"
|
||||||
|
msgstr[0] "должно быть %{count} байт"
|
||||||
|
msgstr[1] "должно быть %{count} байта"
|
||||||
|
msgstr[2] "должно быть %{count} байтов"
|
||||||
|
|
||||||
|
msgid "should have at least %{count} item(s)"
|
||||||
|
msgid_plural "should have at least %{count} item(s)"
|
||||||
|
msgstr[0] "должно быть не менее %{count} элементов"
|
||||||
|
msgstr[1] "должно быть не менее %{count} элемента"
|
||||||
|
msgstr[2] "должно быть не менее %{count} элементов"
|
||||||
|
|
||||||
|
msgid "should be at least %{count} character(s)"
|
||||||
|
msgid_plural "should be at least %{count} character(s)"
|
||||||
|
msgstr[0] "должно быть не менее %{count} символов"
|
||||||
|
msgstr[1] "должно быть не менее %{count} символа"
|
||||||
|
msgstr[2] "должно быть не менее %{count} символов"
|
||||||
|
|
||||||
|
msgid "should be at least %{count} byte(s)"
|
||||||
|
msgid_plural "should be at least %{count} byte(s)"
|
||||||
|
msgstr[0] "должно быть хотя бы %{count} байт"
|
||||||
|
msgstr[1] "должно быть хотя бы %{count} байта"
|
||||||
|
msgstr[2] "должно быть хотя бы %{count} байтов"
|
||||||
|
|
||||||
|
msgid "should have at most %{count} item(s)"
|
||||||
|
msgid_plural "should have at most %{count} item(s)"
|
||||||
|
msgstr[0] "должно содержать не более %{count} элементов"
|
||||||
|
msgstr[1] "должно содержать не более %{count} элементов"
|
||||||
|
msgstr[2] "должно содержать не более %{count} элементов"
|
||||||
|
|
||||||
|
msgid "should be at most %{count} character(s)"
|
||||||
|
msgid_plural "should be at most %{count} character(s)"
|
||||||
|
msgstr[0] "должно быть не более %{count} символа(ов)"
|
||||||
|
msgstr[1] "должно быть не более %{count} символа(ов)"
|
||||||
|
msgstr[2] "должно быть не более %{count} символа(ов)"
|
||||||
|
|
||||||
|
msgid "should be at most %{count} byte(s)"
|
||||||
|
msgid_plural "should be at most %{count} byte(s)"
|
||||||
|
msgstr[0] "должно быть не более %{count} байт(ов)."
|
||||||
|
msgstr[1] "должно быть не более %{count} байт(ов)."
|
||||||
|
msgstr[2] "должно быть не более %{count} байт(ов)."
|
||||||
|
|
||||||
|
msgid "must be less than %{number}"
|
||||||
|
msgstr "должно быть меньше, чем %{number}"
|
||||||
|
|
||||||
|
msgid "must be greater than %{number}"
|
||||||
|
msgstr "должно быть больше, чем %{number}"
|
||||||
|
|
||||||
|
msgid "must be less than or equal to %{number}"
|
||||||
|
msgstr "должно быть меньше или равно %{number}"
|
||||||
|
|
||||||
|
msgid "must be greater than or equal to %{number}"
|
||||||
|
msgstr "должно быть больше или равно %{number}"
|
||||||
|
|
||||||
|
msgid "must be equal to %{number}"
|
||||||
|
msgstr "должно быть равно %{number}"
|
Loading…
Reference in a new issue