diff --git a/.env.sample b/.env.sample index 7e069d2..dc725c4 100644 --- a/.env.sample +++ b/.env.sample @@ -3,7 +3,7 @@ BASE_URL=http://localhost:4000 # SECURE_COOKIE=false DATABASE_URL=postgres://claper:claper@db:5432/claper -SECRET_KEY_BASE=0LZiQBLw4WvqPlz4cz8RsHJlxNiSqM9B48y4ChyJ5v1oA0L/TPIqRjQNdPZN3iEG # Generate with `mix phx.gen.secret` +SECRET_KEY_BASE=0LZiQBLw4WvqPlz4cz8RsHJlxNiSqM9B48y4ChyJ5v1oA0L/TPIqRjQNdPZN3iEG # Generate with `mix phx.gen.secret` # ⚠️ Don't use this exact value for SECRET_KEY_BASE or someone would be able to sign a cookie with user_id=1 and log in as the admin! # Storage configuration @@ -12,10 +12,19 @@ PRESENTATION_STORAGE=local PRESENTATION_STORAGE_DIR=/app/uploads #MAX_FILE_SIZE_MB=15 -#AWS_ACCESS_KEY_ID=xxx -#AWS_SECRET_ACCESS_KEY=xxx -#AWS_REGION=eu-west-3 -#AWS_PRES_BUCKET=xxx +# The standard AWS environment variables +#S3_ACCESS_KEY_ID=xxx +#S3_SECRET_ACCESS_KEY=xxx +#S3_REGION=eu-west-3 +#S3_BUCKET=xxx + +# If you're using an alternative S3-compatible service, port optional +#S3_SCHEME=https:// +#S3_HOST=www.example.com +#S3_PORT=443 + +# If the public S3-compatible URL is different from the one used to write data +#S3_PUBLIC_URL=https://www.example.com # Mail configuration @@ -39,6 +48,7 @@ MAIL_FROM_NAME=Claper #ALLOW_UNLINK_EXTERNAL_PROVIDER=false #LOGOUT_REDIRECT_URL=https://google.com #GS_JPG_RESOLUTION=300x300 +#LANGUAGES=en,fr,es,it,nl,de # OIDC configuration @@ -49,4 +59,4 @@ MAIL_FROM_NAME=Claper # OIDC_SCOPES="openid email profile" # OIDC_LOGO_URL="" # OIDC_PROPERTY_MAPPINGS="roles:custom_attributes.roles,organization:custom_attributes.organization" -# OIDC_AUTO_REDIRECT_LOGIN=true \ No newline at end of file +# OIDC_AUTO_REDIRECT_LOGIN=true diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 0f1934e..6dc5a15 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -42,8 +42,8 @@ jobs: - name: Set up Elixir uses: erlef/setup-beam@v1 with: - elixir-version: '1.16.2' - otp-version: '26' + elixir-version: '1.18.4' + otp-version: '28' - name: Restore dependencies cache uses: actions/cache@v3 with: diff --git a/.gitignore b/.gitignore index b7b3375..bb6c6f5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,16 +30,21 @@ claper-*.tar # Ignore digested assets cache. /priv/static/cache_manifest.json +# Env files except sample +.env* +!.env.sample + # In case you use Node.js/npm, you want to ignore these. npm-debug.log /assets/node_modules/ priv/static/images/.DS_Store priv/static/.DS_Store -.env priv/static/fonts/.DS_Store test/e2e/node_modules .DS_Store priv/static/.well-known/apple-developer-merchantid-domain-association priv/static/loaderio-eb3b956a176cdd4f54eb8570ce8bbb06.txt .elixir_ls + +tailwind.config.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 422a79c..5949489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +### v.2.4.0 + +### ⚠️ Breaking changes + +- S3 variables are now named: S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGION and S3_BUCKET +- Users now have roles. Refer to the `roles` table and assign a role to a user with the `role_id` column in the `users` table. + +### Features + +- Add Admin Panel to manage users and presentations +- Add user roles: user, admin +- Add `LANGUAGES` setting to configure available languages in the app +- Add hideable presenter attendee count (#183 #155) +- Add Hungarian translation (#161) +- Add Latvian translation (#163) +- Add custom S3 endpoint with `S3_SCHEME`, `S3_HOST`, `S3_PORT` and `S3_PUBLIC_URL` + +### Fixes and improvements + +- Upgrade JS dependencies +- Upgrade Elixir dependencies, including Phoenix Live View to 1.0.17 +- Upgrade to Tailwind 4+ +- Refactor view templates to use {} instead of <%= %> +- Fix event name validation to be required +- Docker image is now using Ubuntu instead of Alpine for better dependencies support +- Fix scrollbar not showing in event manager when no presentation file (#164) (@aryel780) +- Fix settings scroll for small screen (#168) +- Fix duplicate key quiz when duplicate (#182) +- Fix email change confirmation (#172) +- Fix italian translation (#179) +- Fix random poll choices (#184) + ### v.2.3.2 ### Fixes and improvements diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..e043078 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,112 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Development Commands + +### Setup and Dependencies +```bash +# Install dependencies +mix deps.get +mix setup # Runs deps.get + ecto.setup + +# Setup database +mix ecto.setup # Creates DB, runs migrations, seeds +mix ecto.reset # Drops DB and runs ecto.setup + +# Install frontend dependencies +cd assets && npm install && cd .. +``` + +### Running the Application +```bash +# Start Phoenix server +mix phx.server + +# Or inside IEx +iex -S mix phx.server +``` + +### Testing +```bash +# Run tests +mix test + +# Run specific test file +mix test test/path/to/test_file.exs + +# Run test with specific line number +mix test test/path/to/test_file.exs:42 +``` + +### Code Quality +```bash +# Format code +mix format + +# Run Credo for code analysis +mix credo +``` + +### Building Assets +```bash +# For production deployment +mix assets.deploy +``` + +## High-Level Architecture + +Claper is an interactive presentation platform built with Phoenix Framework and Elixir. It enables real-time audience interaction during presentations through polls, forms, messages, and quizzes. + +### Core Components + +1. **Phoenix LiveView Architecture** + - Real-time updates without JavaScript through WebSocket connections + - LiveView modules in `lib/claper_web/live/` handle interactive UI + - Presence tracking for real-time user counts + +2. **Main Domain Contexts** (in `lib/claper/`) + - `Accounts` - User management, authentication, OIDC integration + - `Events` - Core presentation/event management + - `Posts` - Audience messages and reactions + - `Polls` - Interactive polls with real-time voting + - `Forms` - Custom forms for audience feedback + - `Quizzes` - Quiz functionality with LTI support + - `Presentations` - Slide management and state tracking + - `Embeds` - External content embedding + +3. **Authentication & Authorization** + - Multiple auth methods: email/password, OIDC + - Role-based access control with admin panel + - LTI 1.3 support for educational platforms + +4. **Real-time Features** + - Phoenix PubSub for broadcasting updates + - Phoenix Presence for tracking online users + - LiveView for reactive UI without custom JavaScript + +5. **Background Jobs** + - Oban for background job processing + - Email sending + +6. **Frontend Stack** + - Tailwind CSS for styling (with DaisyUI components) + - Alpine.js for minimal JavaScript interactions + - esbuild for JavaScript bundling + - Separate admin and user interfaces + +7. **Key LiveView Modules** + - `EventLive.Show` - Attendee view + - `EventLive.Presenter` - Presenter control view + - `EventLive.Manage` - Event management interface + - `AdminLive.*` - Admin panel components + +8. **Database Structure** + - PostgreSQL with Ecto + - Key models: User, Event, Post, Poll, Quiz, PresentationState + - Soft deletes for users + - UUID-based public identifiers + +9. **LTI Integration** + - LTI 1.3 support for quizzes, publish score to LMS + - LTI launch handling in `LtiController` diff --git a/CNAME b/CNAME deleted file mode 100644 index d0de72e..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.claper.co \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8132d81..7d006ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,22 @@ -# Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian instead of -# Alpine to avoid DNS resolution issues in production. -# -# https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu -# https://hub.docker.com/_/ubuntu?tab=tags -# -# -# This file is based on these images: -# -# - https://hub.docker.com/r/hexpm/elixir/tags - for the build image -# - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20210902-slim - for the release image -# - https://pkgs.org/ - resource for finding needed packages -# - Ex: hexpm/elixir:1.13.2-erlang-24.2.1-debian-bullseye-20210902-slim -# -ARG BUILDER_IMAGE="hexpm/elixir:1.16.0-erlang-26.2.1-alpine-3.18.4" -ARG RUNNER_IMAGE="alpine:3.18.4" +ARG BUILDER_IMAGE="hexpm/elixir:1.18.4-erlang-28.0.1-ubuntu-noble-20250619" +ARG RUNNER_IMAGE="ubuntu:24.04" FROM ${BUILDER_IMAGE} as builder -# install build dependencies -# RUN apt-get update -y && apt-get install -y curl build-essential git \ -# && apt-get clean && rm -f /var/lib/apt/lists/*_* -RUN apk add --no-cache -U build-base git curl bash ca-certificates nodejs npm openssl ncurses +RUN apt-get update && apt-get install -y \ + build-essential \ + git \ + curl \ + bash \ + ca-certificates \ + nodejs \ + npm \ + openssl \ + libncurses5-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -ENV NODE_VERSION 16.20.0 +ENV NODE_VERSION 22.17.0 ENV PRESENTATION_STORAGE_DIR /app/uploads # custom ERL_FLAGS are passed for (public) multi-platform builds @@ -30,19 +24,6 @@ ENV PRESENTATION_STORAGE_DIR /app/uploads ARG ERL_FLAGS ENV ERL_FLAGS=$ERL_FLAGS -# Install nvm with node and npm -# RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \ -# && . $HOME/.nvm/nvm.sh \ -# && nvm install $NODE_VERSION \ -# && nvm alias default $NODE_VERSION \ -# && nvm use default - -# ENV NODE_PATH $HOME/.nvm/versions/node/v$NODE_VERSION/lib/node_modules -# ENV PATH $HOME/.nvm/versions/node/v$NODE_VERSION/bin:$PATH - -# RUN ln -sf $HOME/.nvm/versions/node/v$NODE_VERSION/bin/npm /usr/bin/npm -# RUN ln -sf $HOME/.nvm/versions/node/v$NODE_VERSION/bin/node /usr/bin/node - # prepare build dir WORKDIR /app @@ -66,25 +47,14 @@ RUN mix deps.compile COPY priv priv -# note: if your project uses a tool like https://purgecss.com/, -# which customizes asset compilation based on what it finds in -# your Elixir templates, you will need to move the asset compilation -# step down so that `lib` is available. COPY assets assets -# Compile the release COPY lib lib RUN mix compile -RUN npm install -g sass -RUN cd assets && npm i && \ - sass --no-source-map --style=compressed css/custom.scss ../priv/static/assets/custom.css +RUN mix assets.deploy -# compile assets -RUN mix assets.deploy.nosass - -# Changes to config/runtime.exs don't require recompiling the code COPY config/runtime.exs config/ COPY rel rel @@ -94,20 +64,27 @@ RUN mix release # the compiled release and other runtime necessities FROM ${RUNNER_IMAGE} -# RUN apt-get update -y && apt-get install -y curl libstdc++6 openssl libncurses5 locales ghostscript default-jre libreoffice-java-common \ -# && apt-get install -y libreoffice --no-install-recommends && apt-get clean && rm -f /var/lib/apt/lists/*_* -RUN apk add --no-cache curl libstdc++6 openssl ncurses ghostscript openjdk11-jre +RUN apt-get update -y && apt-get install -y curl libstdc++6 openssl locales ghostscript default-jre libreoffice-java-common \ + && apt-get install -y libreoffice --no-install-recommends && apt-get clean && rm -f /var/lib/apt/lists/*_* +# RUN apk add --no-cache curl libstdc++ openssl ncurses ghostscript openjdk11-jre # Install LibreOffice & Common Fonts -RUN apk --no-cache add bash libreoffice util-linux libreoffice-common \ - font-droid-nonlatin font-droid ttf-dejavu ttf-freefont ttf-liberation && \ - rm -rf /var/cache/apk/* +RUN apt-get update && apt-get install -y \ + libreoffice \ + fonts-dejavu \ + fonts-freefont-ttf \ + fonts-liberation \ + fonts-droid-fallback \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* # Install Microsoft Core Fonts -RUN apk --no-cache add msttcorefonts-installer fontconfig && \ - update-ms-fonts && \ - fc-cache -f && \ - rm -rf /var/cache/apk/* +RUN apt-get update && apt-get install -y \ + ttf-mscorefonts-installer \ + fontconfig \ + && fc-cache -f \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en diff --git a/Dockerfile.dev b/Dockerfile.dev index d502072..2a3a655 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -61,19 +61,18 @@ RUN ARCH=$(uname -m) && \ && rm asdf-v${ASDF_VERSION}-linux-${ASDF_ARCH}.tar.gz \ && mv asdf /usr/bin/ - # Install Erlang and Elixir using asdf RUN asdf plugin add erlang \ && asdf plugin add elixir \ - && asdf install erlang 26.2.1 \ - && asdf install elixir 1.16.0 \ - && asdf set -u erlang 26.2.1 \ - && asdf set -u elixir 1.16.0 + && asdf install erlang 28.0.1 \ + && asdf install elixir 1.18.4-otp-28 \ + && asdf set -u erlang 28.0.1 \ + && asdf set -u elixir 1.18.4-otp-28 # Install Node.js using asdf RUN asdf plugin add nodejs \ - && asdf install nodejs 22.1.0 \ - && asdf set -u nodejs 22.1.0 + && asdf install nodejs 22.17.0 \ + && asdf set -u nodejs 22.17.0 ENV PATH="/root/.asdf/shims:$PATH" diff --git a/README.md b/README.md index e56581b..a4ae41c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Claper has a two-sided mission: - The first one is to help these people presenting an idea or a message by giving them the opportunity to make their presentation unique and to have real-time feedback from their audience. - The second one is to help each participant to take their place, to be an actor in the presentation, in the meeting and to feel important and useful. -Supported languages: 🇬🇧 English, 🇫🇷 French, 🇩🇪 German, 🇪🇸 Spanish, 🇳🇱 Dutch, 🇮🇹 Italian +Supported languages: 🇬🇧 English, 🇫🇷 French, 🇩🇪 German, 🇪🇸 Spanish, 🇳🇱 Dutch, 🇮🇹 Italian, 🇭🇺 Hungarian, 🇱🇻 Latvian ### Built With diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 0000000..c8d7ad5 --- /dev/null +++ b/assets/css/admin.css @@ -0,0 +1,63 @@ +@import "tailwindcss"; +@plugin "daisyui"; + +@utility btn { + @apply rounded-full !font-display text-small-body; +} + +@utility input { + @apply rounded-full focus:outline-none focus-within:outline-none focus:border-2 focus-within:border-2 !font-display text-small-body transition-all; +} + +@utility select { + @apply rounded-full focus:outline-none focus-within:outline-none focus:border-2 focus-within:border-2 !font-display text-small-body transition-all; +} + +@utility label { + @apply ml-2; +} + +@utility fieldset-legend { + @apply ml-3; +} + +@plugin "daisyui/theme" { + name: "claper"; + default: true; /* set as default */ + prefersdark: false; /* set as default dark mode (prefers-color-scheme:dark) */ + color-scheme: light; /* color of browser-provided UI */ + + --color-primary: #140753; + --color-primary-content: #ffffff; + --color-secondary: #f4f4f4; + --color-secondary-content: #140553; + --color-accent: #8611ed; + --color-accent-content: #ffffff; + --color-neutral: #000000; + --color-neutral-content: #ffffff; + --color-info: #79bfe2; + --color-info-content: #0e3649; + --color-success: #3cb957; + --color-success-content: #143e1d; + --color-warning: #ffb62e; + --color-warning-content: #523500; + --color-error: #e7000b; + --color-error-content: #fff; + /* border radius */ + --radius-selector: 1rem; + --radius-field: 0.25rem; + --radius-box: 0.5rem; + + /* base sizes */ + --size-selector: 0.25rem; + --size-field: 0.25rem; + + /* border size */ + --border: 1px; + + /* effects */ + --depth: 1; + --noise: 0; +} + +@import "./modern.css" layer(theme); diff --git a/assets/css/app.css b/assets/css/app.css index 88a6251..b3d3e4d 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -1,12 +1,26 @@ -@import url('air-datepicker/air-datepicker.css'); -@import url("animate.css/animate.min.css"); +@import 'air-datepicker/air-datepicker.css'; +@import 'animate.css/animate.min.css'; -@tailwind base; -@tailwind components; -@tailwind utilities; +@import 'tailwindcss'; +@import './theme.css' layer(theme); + +@plugin "daisyui" { + themes: light --default; + include: toggle; +} + +@layer base { + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentcolor); + } +} * { - font-family: 'Roboto', sans-serif; + font-family: var(--font-family-sans); } [x-cloak] { display: none !important; } @@ -19,19 +33,19 @@ border-radius: 4px; } .alert-info { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1; + color: var(--color-primary-700); + background-color: var(--color-primary-100); + border-color: var(--color-primary-200); } .alert-warning { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #faebcc; + color: var(--color-supporting-yellow-700); + background-color: var(--color-supporting-yellow-50); + border-color: var(--color-supporting-yellow-100); } .alert-danger { - color: #a94442; - background-color: #f2dede; - border-color: #ebccd1; + color: var(--color-supporting-red-700); + background-color: var(--color-supporting-red-100); + border-color: var(--color-supporting-red-200); } .alert p { margin-bottom: 0; @@ -40,7 +54,7 @@ display: none; } .invalid-feedback { - color: #a94442; + color: var(--color-supporting-red-700); display: block; margin-top: 2px; } @@ -80,12 +94,13 @@ background-color: #fefefe; margin: 15vh auto; padding: 20px; - border: 1px solid #888; + border: 1px solid var(--color-neutral-300); width: 80%; + box-shadow: var(--shadow-lg); } .phx-modal-close { - color: #aaa; + color: var(--color-neutral-400); float: right; font-size: 28px; font-weight: bold; @@ -93,7 +108,7 @@ .phx-modal-close:hover, .phx-modal-close:focus { - color: black; + color: var(--color-neutral-900); text-decoration: none; cursor: pointer; } @@ -104,13 +119,21 @@ .input:focus~.label, .input:active~.label, .input.filled~.label { - @apply text-sm transition-all duration-100 -top-1.5 text-primary-500; + font-size: 0.875rem; + transition-property: all; + transition-duration: 100ms; + top: -0.375rem; + color: var(--color-primary-500); } .input:focus~.icon, .input:active~.icon, .input.filled~.icon { - @apply transition-all duration-100 left-3 top-6 h-5; + transition-property: all; + transition-duration: 100ms; + left: 0.75rem; + top: 1.5rem; + height: 1.25rem; } .date-placeholder-hidden::-webkit-datetime-edit { @@ -284,8 +307,22 @@ url('/fonts/Roboto/roboto-v29-latin-900italic.svg#Roboto') format('svg'); /* Legacy iOS */ } +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 100 300 400 500 700 900; + src: url('/fonts/Montserrat/Montserrat-VariableFont_wght.ttf'); +} + +@font-face { + font-family: 'Montserrat'; + font-style: italic; + font-weight: 100 300 400 500 700 900; + src: url('/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf'); +} + .bg-gradient-animate { - background: linear-gradient(-45deg, #b80fef, #8611ed, #14bfdb, #14bfdb); + background: linear-gradient(-45deg, var(--color-secondary-500), var(--color-secondary-600), var(--color-primary-400), var(--color-primary-400)); background-size: 400% 400%; animation: gradient 15s ease infinite; } @@ -305,7 +342,7 @@ .arrow_box { position: relative; background: #fff; - border: 2px solid #e1e1e1; + border: 2px solid var(--color-neutral-100); } .arrow_box.arrow_right:after, .arrow_box.arrow_right:before { left: 100%; @@ -419,8 +456,7 @@ left: 0; top: 50%; right: 0; - border-top: 3px solid; - @apply border-supporting-red-600; + border-top: var(--color-supporting-red-600) 3px solid; -webkit-transform:rotate(-20deg); -moz-transform:rotate(-20deg); @@ -431,15 +467,16 @@ /* Air datepicker */ .air-datepicker-body--day-name { - @apply text-primary-600; + color: var(--color-primary-600); } .air-datepicker-cell.-selected-, .air-datepicker-cell.-selected-.-current- { - @apply bg-primary-500 text-white hover:bg-primary-600; + background-color: var(--color-primary-500); + color: var(--color-white); } .air-datepicker-cell.-current- { - @apply text-secondary-500; + color: var(--color-secondary-500); } .animate__slow_slow { diff --git a/assets/css/modern.css b/assets/css/modern.css new file mode 100644 index 0000000..9dc3070 --- /dev/null +++ b/assets/css/modern.css @@ -0,0 +1,152 @@ +@theme { + /* Colors */ + /* Main colors */ + --color-*: initial; + --color-sky-blue: #81EBFE; + --color-teal: #14BFDB; + --color-azure: #29ACED; + --color-mauve: #8611ED; + --color-purple: #B80FEF; + --color-navy: #140553; + + /* Light colors */ + --color-cold-pink: #F3DEFA; + --color-warm-pink: #FFD2F6; + --color-yeallaw: #FFEAC2; + --color-pistacio: #D4FFF4; + --color-sky-tern: #C8EDFF; + --color-tealy: #81EBFE; + --color-earl-night: #0A7BB4; + --color-dark-night: #184992; + + /* Gradient */ + --gradient-primary: 123deg, var(--color-sky-blue) -36%, var(--color-teal) -12%, var(--color-azure) 21%, var(--color-mauve) 81%, var(--color-purple) 130%; + --gradient-secondary: 123deg, rgba(129, 235, 254, 0.9) -36%, rgba(20, 191, 219, 0.9) -12%, rgba(41, 172, 237, 0.9) 21%, rgba(134, 17, 237, 0.9) 81%, rgba(184, 15, 239, 0.9) 130%; + + /* Grayscale */ + --color-white: #FFFFFF; + --color-black: #191919; + --color-gray-20: #CCCCCC; + --color-gray-40: #9F9F9F; + --color-gray-60: #737373; + --color-gray-80: #464646; + --color-gray-100: #191919; + --color-gray-120: #000000; + + --color-platinum: #F0F0F0; + --color-platinum-20: #FFFFFF; + --color-platinum-40: #FCFCFC; + --color-platinum-60: #F8F8F8; + --color-platinum-80: #F4F4F4; + --color-platinum-100: #F0F0F0; + --color-platinum-120: #EEEEEE; + + /* Typography */ + --font-display: "Montserrat", sans-serif; + + /* Font Sizes - Desktop */ + --text-h1: 80px; + --leading-h1: 120%; + --font-weight-h1: 900; + + --text-h2: 40px; + --leading-h2: 120%; + --font-weight-h2: 700; + + --text-h3: 32px; + --leading-h3: 120%; + --font-weight-h3: 600; + + --text-h4: 24px; + --leading-h4: 120%; + --font-weight-h4: 500; + + --text-h5: 18px; + --leading-h5: 120%; + --font-weight-h5: 600; + + --text-h6: 16px; + --leading-h6: 120%; + --font-weight-h6: 500; + + --text-subheading: 20px; + --leading-subheading: 150%; + --font-weight-subheading: 300; + + --text-body-bold: 16px; + --leading-body-bold: 150%; + --font-weight-body-bold: 700; + + --text-body: 16px; + --leading-body: 150%; + --font-weight-body: 400; + + --text-small-body-bold: 14px; + --leading-small-body-bold: 150%; + --font-weight-small-body-bold: 600; + + --text-small-body: 14px; + --leading-small-body: 150%; + --font-weight-small-body: 400; + + --text-caption: 14px; + --leading-caption: 150%; + --font-weight-caption: 300; + + /* Font Sizes - Mobile */ + --text-mobile-h1: 32px; + --leading-mobile-h1: 120%; + --font-weight-mobile-h1: 900; + + --text-mobile-h2: 28px; + --leading-mobile-h2: 120%; + --font-weight-mobile-h2: 700; + + --text-mobile-h3: 22px; + --leading-mobile-h3: 120%; + --font-weight-mobile-h3: 600; + + --text-mobile-h4: 18px; + --leading-mobile-h4: 120%; + --font-weight-mobile-h4: 500; + + --text-mobile-h5: 16px; + --leading-mobile-h5: 120%; + --font-weight-mobile-h5: 600; + + --text-mobile-h6: 14px; + --leading-mobile-h6: 120%; + --font-weight-mobile-h6: 500; + + /* Spacing */ + --spacing-0: 0px; + --spacing-4: 4px; + --spacing-8: 8px; + --spacing-12: 12px; + --spacing-16: 16px; + --spacing-20: 20px; + --spacing-24: 24px; + --spacing-28: 28px; + --spacing-32: 32px; + --spacing-36: 36px; + --spacing-40: 40px; + --spacing-44: 44px; + --spacing-48: 48px; + --spacing-52: 52px; + --spacing-56: 56px; + --spacing-60: 60px; + --spacing-64: 64px; + --spacing-68: 68px; + --spacing-72: 72px; + --spacing-76: 76px; + --spacing-80: 80px; + --spacing-128: 128px; + + /* Font Weights */ + --font-weight-regular: 400; + --font-weight-bold: 700; + + /* Shadows */ + --shadow-3xl: 0px 902px 253px 0px rgba(65, 69, 124, 0.00), 0px 577px 231px 0px rgba(65, 69, 124, 0.01), 0px 325px 195px 0px rgba(65, 69, 124, 0.05), 0px 144px 144px 0px rgba(65, 69, 124, 0.09), 0px 36px 79px 0px rgba(65, 69, 124, 0.10) + +} \ No newline at end of file diff --git a/assets/css/theme.css b/assets/css/theme.css new file mode 100644 index 0000000..10987a5 --- /dev/null +++ b/assets/css/theme.css @@ -0,0 +1,87 @@ + +@theme { + /* Primary Colors (water-blue) */ + --color-primary-50: #E3F2FD; + --color-primary-100: #C2E3FA; + --color-primary-200: #84C8F6; + --color-primary-300: #3DA7F0; + --color-primary-400: #1395EC; + --color-primary-500: #1186D5; + --color-primary-600: #0D65A1; + --color-primary-700: #0A5689; + --color-primary-800: #0A4B76; + --color-primary-900: #073250; + + /* Secondary Colors (electric-purple) */ + --color-secondary-50: #F2E0FF; + --color-secondary-100: #E3BDFF; + --color-secondary-200: #C77AFF; + --color-secondary-300: #A62EFF; + --color-secondary-400: #9200FF; + --color-secondary-500: #A327FF; + --color-secondary-600: #6400AD; + --color-secondary-700: #550094; + --color-secondary-800: #490080; + --color-secondary-900: #320057; + + /* Neutral Colors (wedgewood) */ + --color-neutral-50: #F0F4F8; + --color-neutral-100: #D9E3ED; + --color-neutral-200: #B9CCDF; + --color-neutral-300: #97B3CE; + --color-neutral-400: #7499BE; + --color-neutral-500: #507DAA; + --color-neutral-600: #3F6388; + --color-neutral-700: #314D68; + --color-neutral-800: #253B50; + --color-neutral-900: #1A2938; + + /* Supporting Red Colors (rose-madder) */ + --color-supporting-red-50: #FCEDEE; + --color-supporting-red-100: #F9D5D7; + --color-supporting-red-200: #F3ABB0; + --color-supporting-red-300: #ED8188; + --color-supporting-red-400: #E75761; + --color-supporting-red-500: #E12D39; + --color-supporting-red-600: #B4242E; + --color-supporting-red-700: #871B22; + --color-supporting-red-800: #5A1217; + --color-supporting-red-900: #2D090B; + + /* Supporting Yellow Colors (school-bus-yellow) */ + --color-supporting-yellow-50: #FFFBEB; + --color-supporting-yellow-100: #FEF3C7; + --color-supporting-yellow-200: #FDE68A; + --color-supporting-yellow-300: #FCD34D; + --color-supporting-yellow-400: #FBBF24; + --color-supporting-yellow-500: #F59E0B; + --color-supporting-yellow-600: #D97706; + --color-supporting-yellow-700: #B45309; + --color-supporting-yellow-800: #92400E; + --color-supporting-yellow-900: #78350F; + + /* Supporting Green Colors (green-teal) */ + --color-supporting-green-50: #ECFDF5; + --color-supporting-green-100: #D1FAE5; + --color-supporting-green-200: #A7F3D0; + --color-supporting-green-300: #6EE7B7; + --color-supporting-green-400: #34D399; + --color-supporting-green-500: #10B981; + --color-supporting-green-600: #059669; + --color-supporting-green-700: #047857; + --color-supporting-green-800: #065F46; + --color-supporting-green-900: #064E3B; + + /* Font Family */ + --font-family-sans: 'Roboto', sans-serif; + --font-family-serif: 'Merriweather', serif; + --font-display: 'Montserrat', sans-serif; + + /* Box Shadows */ + --shadow-base: 0px 1px 3px 0px rgba(0,0,0,0.1), 0px 1px 2px 0px rgba(0,0,0,0.06); + --shadow-md: 0px 4px 6px 0px rgba(0,0,0,0.1), 0px 2px 4px 0px rgba(0,0,0,0.06); + --shadow-lg: 0px 4px 6px 0px rgba(0,0,0,0.05), 0px 10px 15px 0px rgba(0,0,0,0.1); + --shadow-xl: 0px 10px 10px 0px rgba(0,0,0,0.04), 0px 20px 25px 0px rgba(0,0,0,0.1); + --shadow-2xl: 0px 25px 50px 0px rgba(0,0,0,0.25); + --shadow-inner: inset 0px 2px 4px 0px rgba(0,0,0,0.06); +} diff --git a/assets/js/admin-charts.js b/assets/js/admin-charts.js new file mode 100644 index 0000000..9ab3818 --- /dev/null +++ b/assets/js/admin-charts.js @@ -0,0 +1,207 @@ +import { + Chart, + LineElement, + PointElement, + CategoryScale, + LinearScale, + Title, + Tooltip, + Legend, + LineController, + Filler +} from 'chart.js'; +import 'chartjs-adapter-moment'; + +// Register Chart.js components +Chart.register( + LineElement, + PointElement, + CategoryScale, + LinearScale, + Title, + Tooltip, + Legend, + LineController, + Filler +); + +export class AdminCharts { + constructor() { + this.charts = {}; + this.defaultOptions = { + responsive: true, + maintainAspectRatio: false, + interaction: { + intersect: false, + mode: 'index' + }, + plugins: { + legend: { + display: true, + position: 'top', + labels: { + usePointStyle: true, + padding: 20, + font: { + size: 12, + family: 'Inter, system-ui, sans-serif' + }, + color: 'rgba(255, 255, 255, 0.9)' + } + }, + tooltip: { + enabled: true, + backgroundColor: 'rgba(0, 0, 0, 0.8)', + titleColor: 'rgba(255, 255, 255, 0.9)', + bodyColor: 'rgba(255, 255, 255, 0.9)', + borderColor: 'rgba(255, 255, 255, 0.1)', + borderWidth: 1, + cornerRadius: 8, + displayColors: false, + padding: 12, + titleFont: { + size: 14, + weight: 'bold' + }, + bodyFont: { + size: 13 + } + } + }, + scales: { + x: { + display: true, + grid: { + display: false + }, + ticks: { + color: 'rgba(255, 255, 255, 0.7)', + font: { + size: 11 + } + } + }, + y: { + display: true, + grid: { + color: 'rgba(255, 255, 255, 0.1)', + drawBorder: false + }, + ticks: { + color: 'rgba(255, 255, 255, 0.7)', + font: { + size: 11 + }, + callback: function(value) { + return Number.isInteger(value) ? value : ''; + } + } + } + }, + elements: { + line: { + tension: 0.4, + borderWidth: 3, + fill: true + }, + point: { + radius: 0, + hoverRadius: 6, + hoverBorderWidth: 2, + hoverBorderColor: 'rgba(255, 255, 255, 0.9)' + } + }, + animation: { + duration: 800, + easing: 'easeInOutQuart' + } + }; + } + + createUsersChart(canvasId, data) { + const ctx = document.getElementById(canvasId); + if (!ctx) return null; + + const chartData = { + labels: data.labels, + datasets: [{ + label: 'Users', + data: data.values, + borderColor: 'rgba(102, 126, 234, 1)', + backgroundColor: 'rgba(102, 126, 234, 0.1)', + pointBackgroundColor: 'rgba(102, 126, 234, 1)', + pointBorderColor: 'rgba(255, 255, 255, 0.9)', + pointHoverBackgroundColor: 'rgba(102, 126, 234, 1)', + pointHoverBorderColor: 'rgba(255, 255, 255, 0.9)', + }] + }; + + if (this.charts[canvasId]) { + this.charts[canvasId].destroy(); + } + + this.charts[canvasId] = new Chart(ctx, { + type: 'line', + data: chartData, + options: this.defaultOptions + }); + + return this.charts[canvasId]; + } + + createEventsChart(canvasId, data) { + const ctx = document.getElementById(canvasId); + if (!ctx) return null; + + const chartData = { + labels: data.labels, + datasets: [{ + label: 'Events', + data: data.values, + borderColor: 'rgba(16, 185, 129, 1)', + backgroundColor: 'rgba(16, 185, 129, 0.1)', + pointBackgroundColor: 'rgba(16, 185, 129, 1)', + pointBorderColor: 'rgba(255, 255, 255, 0.9)', + pointHoverBackgroundColor: 'rgba(16, 185, 129, 1)', + pointHoverBorderColor: 'rgba(255, 255, 255, 0.9)', + }] + }; + + if (this.charts[canvasId]) { + this.charts[canvasId].destroy(); + } + + this.charts[canvasId] = new Chart(ctx, { + type: 'line', + data: chartData, + options: this.defaultOptions + }); + + return this.charts[canvasId]; + } + + updateChart(canvasId, data) { + const chart = this.charts[canvasId]; + if (!chart) return; + + chart.data.labels = data.labels; + chart.data.datasets[0].data = data.values; + chart.update('active'); + } + + destroyChart(canvasId) { + if (this.charts[canvasId]) { + this.charts[canvasId].destroy(); + delete this.charts[canvasId]; + } + } + + destroyAllCharts() { + Object.keys(this.charts).forEach(canvasId => { + this.destroyChart(canvasId); + }); + } +} + +// Create global instance +window.AdminCharts = new AdminCharts(); \ No newline at end of file diff --git a/assets/js/app.js b/assets/js/app.js index 9eb6282..93fefdf 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -13,40 +13,71 @@ import airdatepickerLocaleDe from "air-datepicker/locale/de"; import airdatepickerLocaleEs from "air-datepicker/locale/es"; import airdatepickerLocaleNl from "air-datepicker/locale/nl"; import airdatepickerLocaleIt from "air-datepicker/locale/it"; +import airdatepickerLocaleHu from "air-datepicker/locale/hu"; import "moment/locale/de"; import "moment/locale/fr"; import "moment/locale/es"; import "moment/locale/nl"; import "moment/locale/it"; +import "moment/locale/hu"; +import "moment/locale/lv"; import QRCodeStyling from "qr-code-styling"; import { Presenter } from "./presenter"; import { Manager } from "./manager"; import Split from "split-grid"; +import CustomHooks from "./hooks"; import { TourGuideClient } from "@sjmc11/tourguidejs/src/Tour"; +import "./admin-charts.js"; window.moment = moment; -const supportedLocales = ["en", "fr", "de", "es", "nl", "it"]; +// Get supported locales from backend configuration or fallback to default list +const supportedLocales = window.claperConfig?.supportedLocales || [ + "en", + "fr", + "de", + "es", + "nl", + "it", + "hu", + "lv", +]; + +const airdatePickrSupportedLocales = window.claperConfig?.supportedLocales || [ + "en", + "fr", + "de", + "es", + "nl", + "it", + "hu", +]; var locale = document.querySelector("html").getAttribute("lang") || navigator.language.split("-")[0]; +var airdatepickrLocale = locale; + if (!supportedLocales.includes(locale)) { locale = "en"; } +if (!airdatePickrSupportedLocales.includes(locale)) { + airdatepickrLocale = "en"; +} window.moment.locale("en"); window.moment.locale(locale); window.Alpine = Alpine; Alpine.start(); -let airdatepickerLocale = { +let airdatePickrLocales = { en: airdatepickerLocaleEn, fr: airdatepickerLocaleFr, de: airdatepickerLocaleDe, es: airdatepickerLocaleEs, nl: airdatepickerLocaleNl, it: airdatepickerLocaleIt, + hu: airdatepickerLocaleHu, }; let csrfToken = document .querySelector("meta[name='csrf-token']") @@ -69,8 +100,8 @@ Hooks.EmbeddedBanner = { Hooks.TourGuide = { mounted() { this.triggerDiv = document.querySelector(this.el.dataset.btnTrigger); - this.btnTrigger = this.triggerDiv.querySelector('.open'); - this.closeBtnTrigger = this.triggerDiv.querySelector('.close'); + this.btnTrigger = this.triggerDiv.querySelector(".open"); + this.closeBtnTrigger = this.triggerDiv.querySelector(".close"); this.tour = new TourGuideClient({ nextLabel: this.el.dataset.nextLabel, @@ -105,7 +136,7 @@ Hooks.TourGuide = { destroyed() { this.btnTrigger.removeEventListener("click", () => { this.startTour(); - }); + }); this.closeBtnTrigger.removeEventListener("click", () => { this.triggerDiv.classList.add("hidden"); this.tour.finishTour(true, this.el.dataset.group); @@ -200,26 +231,36 @@ Hooks.Scroll = { Hooks.ScrollIntoDiv = { mounted() { let useParent = this.el.dataset.useParent === "true"; - this.scrollElement = this.el.dataset.useParent === "true" ? this.el.parentElement : this.el; + this.scrollElement = + this.el.dataset.useParent === "true" ? this.el.parentElement : this.el; this.checkIfAtBottom(); this.scrollToBottom(true); this.handleEvent("scroll", () => this.scrollToBottom()); this.scrollElement.addEventListener("scroll", () => this.checkIfAtBottom()); }, checkIfAtBottom() { - this.isAtBottom = this.scrollElement.scrollHeight - this.scrollElement.scrollTop - this.scrollElement.clientHeight <= 30; + this.isAtBottom = + this.scrollElement.scrollHeight - + this.scrollElement.scrollTop - + this.scrollElement.clientHeight <= + 30; }, scrollToBottom(force = false) { if (force || this.isAtBottom) { - this.scrollElement.scrollTo({ top: this.scrollElement.scrollHeight, behavior: "smooth" }); + this.scrollElement.scrollTo({ + top: this.scrollElement.scrollHeight, + behavior: "smooth", + }); } }, updated() { this.scrollToBottom(); }, destroyed() { - this.scrollElement.removeEventListener("scroll", () => this.checkIfAtBottom()); - } + this.scrollElement.removeEventListener("scroll", () => + this.checkIfAtBottom(), + ); + }, }; Hooks.NicknamePicker = { @@ -243,7 +284,7 @@ Hooks.NicknamePicker = { clicked(e) { let nickname = prompt( this.el.dataset.prompt, - localStorage.getItem("nickname") || "" + localStorage.getItem("nickname") || "", ); if (nickname) { @@ -265,6 +306,19 @@ Hooks.EmptyNickname = { }, }; +Hooks.SearchableSelect = { + mounted() { + this.handleEvent("update_hidden_field", (payload) => { + if (payload.id === this.el.id) { + this.el.value = payload.value; + // Trigger a change event to update the form + const event = new Event('input', { bubbles: true }); + this.el.dispatchEvent(event); + } + }); + } +}; + Hooks.PostForm = { onPress(e, submitBtn, TA) { if (e.key == "Enter" && !e.shiftKey) { @@ -353,7 +407,7 @@ Hooks.Pickr = { const utc = moment(date).utc().format("YYYY-MM-DDTHH:mm:ss"); utcTime.value = utc; }, - locale: airdatepickerLocale[locale], + locale: airdatePickrLocales[airdatepickrLocale], }); }, updated() {}, @@ -392,7 +446,7 @@ Hooks.OpenPresenter = { window.open( this.el.dataset.url, "newwindow", - "width=" + window.screen.width + ",height=" + window.screen.height + "width=" + window.screen.width + ",height=" + window.screen.height, ); }, mounted() { @@ -417,7 +471,12 @@ Hooks.GlobalReacts = { const container = document.createElement("div"); container.innerHTML = svgContent; const svgElement = container.firstChild; - svgElement.classList.add("react-animation", "absolute", "transform", "opacity-0"); + svgElement.classList.add( + "react-animation", + "absolute", + "transform", + "opacity-0", + ); svgElement.classList.add(...this.el.className.split(" ")); this.el.appendChild(svgElement); } @@ -429,15 +488,17 @@ Hooks.GlobalReacts = { preloadSVGs() { const svgTypes = ["heart", "hundred", "clap", "raisehand"]; - svgTypes.forEach(type => { + svgTypes.forEach((type) => { fetch(`/images/icons/${type}.svg`) - .then(response => response.text()) - .then(svgContent => { + .then((response) => response.text()) + .then((svgContent) => { this.svgCache[type] = svgContent; }) - .catch(error => console.error(`Error loading SVG for ${type}:`, error)); + .catch((error) => + console.error(`Error loading SVG for ${type}:`, error), + ); }); - } + }, }; Hooks.JoinEvent = { mounted() { @@ -570,35 +631,61 @@ Hooks.Dropdown = { }, }; -let Uploaders = {}; - -Uploaders.S3 = function (entries, onViewError) { - entries.forEach((entry) => { - let formData = new FormData(); - let { url, fields } = entry.meta; - Object.entries(fields).forEach(([key, val]) => formData.append(key, val)); - formData.append("file", entry.file); - let xhr = new XMLHttpRequest(); - onViewError(() => xhr.abort()); - xhr.onload = () => - xhr.status === 204 ? entry.progress(100) : entry.error(); - xhr.onerror = () => entry.error(); - xhr.upload.addEventListener("progress", (event) => { - if (event.lengthComputable) { - let percent = Math.round((event.loaded / event.total) * 100); - if (percent < 100) { - entry.progress(percent); - } - } +Hooks.AdminChart = { + mounted() { + const chartType = this.el.dataset.chartType; + const canvasId = this.el.querySelector('canvas').id; + const data = JSON.parse(this.el.dataset.chartData); + + if (chartType === 'users') { + window.AdminCharts.createUsersChart(canvasId, data); + } else if (chartType === 'events') { + window.AdminCharts.createEventsChart(canvasId, data); + } + + this.handleEvent("update_chart", (newData) => { + window.AdminCharts.updateChart(canvasId, newData); }); - - xhr.open("POST", url, true); - xhr.send(formData); - }); + }, + + updated() { + const chartType = this.el.dataset.chartType; + const canvasId = this.el.querySelector('canvas').id; + const data = JSON.parse(this.el.dataset.chartData); + + if (chartType === 'users') { + window.AdminCharts.createUsersChart(canvasId, data); + } else if (chartType === 'events') { + window.AdminCharts.createEventsChart(canvasId, data); + } + }, + + destroyed() { + const canvasId = this.el.querySelector('canvas').id; + window.AdminCharts.destroyChart(canvasId); + } }; +Hooks.CSVDownloader = { + mounted() { + this.handleEvent("download_csv", ({ filename, content }) => { + const blob = new Blob([content], { type: 'text/csv' }); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }); + } +}; + +// Merge our custom hooks with the existing hooks +Object.assign(Hooks, CustomHooks); + let liveSocket = new LiveSocket("/live", Socket, { - uploaders: Uploaders, params: { _csrf_token: csrfToken, tz: Intl.DateTimeFormat().resolvedOptions().timeZone, @@ -629,7 +716,6 @@ window.addEventListener("phx:page-loading-stop", (info) => { topbar.hide(); }); - const onlineUserTemplate = function (user) { return `
diff --git a/assets/js/hooks.js b/assets/js/hooks.js new file mode 100644 index 0000000..779e08c --- /dev/null +++ b/assets/js/hooks.js @@ -0,0 +1,197 @@ +// LiveView hooks for client-side functionality + +const Hooks = { + // Hook for handling CSV downloads from LiveView + CSVDownloader: { + mounted() { + this.handleEvent("download_csv", ({ filename, content }) => { + // Create a Blob with the CSV content + const blob = new Blob([content], { type: "text/csv" }); + + // Create a temporary URL for the Blob + const url = window.URL.createObjectURL(blob); + + // Create a temporary link element + const link = document.createElement("a"); + link.href = url; + link.setAttribute("download", filename); + + // Append the link to the document body + document.body.appendChild(link); + + // Trigger the download + link.click(); + + // Clean up + window.URL.revokeObjectURL(url); + document.body.removeChild(link); + }); + } + }, + + // Hook for User Growth Chart + UserGrowthChart: { + mounted() { + // Import Chart.js dynamically + import("chart.js/auto").then(({ default: Chart }) => { + const ctx = this.el.getContext("2d"); + const labels = JSON.parse(this.el.dataset.labels); + const values = JSON.parse(this.el.dataset.values); + + this.chart = new Chart(ctx, { + type: "line", + data: { + labels: labels, + datasets: [{ + label: "New Users", + data: values, + borderColor: "#111827", + backgroundColor: "rgba(17, 24, 39, 0.05)", + borderWidth: 2, + tension: 0.4, + fill: true, + pointRadius: 0, + pointHoverRadius: 0, + pointBackgroundColor: "transparent", + pointBorderColor: "transparent" + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + interaction: { + intersect: false, + mode: 'index' + }, + plugins: { + legend: { + display: false + }, + tooltip: { + enabled: true, + backgroundColor: "rgba(17, 24, 39, 0.9)", + titleColor: "#fff", + bodyColor: "#fff", + borderColor: "#111827", + borderWidth: 1, + cornerRadius: 4, + displayColors: false, + padding: 8, + titleFont: { + size: 12 + }, + bodyFont: { + size: 14, + weight: 'bold' + }, + callbacks: { + label: function(context) { + return context.parsed.y + ' users'; + } + } + } + }, + scales: { + x: { + display: false + }, + y: { + display: false + } + } + } + }); + }); + }, + + destroyed() { + if (this.chart) { + this.chart.destroy(); + } + } + }, + + // Hook for Event Creation Chart + EventCreationChart: { + mounted() { + // Import Chart.js dynamically + import("chart.js/auto").then(({ default: Chart }) => { + const ctx = this.el.getContext("2d"); + const labels = JSON.parse(this.el.dataset.labels); + const values = JSON.parse(this.el.dataset.values); + + this.chart = new Chart(ctx, { + type: "line", + data: { + labels: labels, + datasets: [{ + label: "New Events", + data: values, + borderColor: "#111827", + backgroundColor: "rgba(17, 24, 39, 0.05)", + borderWidth: 2, + tension: 0.4, + fill: true, + pointRadius: 0, + pointHoverRadius: 0, + pointBackgroundColor: "transparent", + pointBorderColor: "transparent" + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + interaction: { + intersect: false, + mode: 'index' + }, + plugins: { + legend: { + display: false + }, + tooltip: { + enabled: true, + backgroundColor: "rgba(17, 24, 39, 0.9)", + titleColor: "#fff", + bodyColor: "#fff", + borderColor: "#111827", + borderWidth: 1, + cornerRadius: 4, + displayColors: false, + padding: 8, + titleFont: { + size: 12 + }, + bodyFont: { + size: 14, + weight: 'bold' + }, + callbacks: { + label: function(context) { + return context.parsed.y + ' events'; + } + } + } + }, + scales: { + x: { + display: false + }, + y: { + display: false + } + } + } + }); + }); + }, + + destroyed() { + if (this.chart) { + this.chart.destroy(); + } + } + } +}; + +export default Hooks; diff --git a/assets/package-lock.json b/assets/package-lock.json index c9bfb81..4365d3b 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -6,9 +6,10 @@ "": { "dependencies": { "@sjmc11/tourguidejs": "^0.0.16", - "@tailwindcss/container-queries": "^0.1.1", "air-datepicker": "^3.5.0", "animate.css": "^4.1.1", + "chart.js": "^4.4.0", + "chartjs-adapter-moment": "^1.0.1", "moment": "^2.29.4", "moment-timezone": "^0.5.43", "phoenix": "file:../deps/phoenix", @@ -20,32 +21,52 @@ "tiny-slider": "^2.9.4" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.11", "alpinejs": "^3.13.8", - "autoprefixer": "^10.4.19", - "esbuild": "^0.20.2", + "daisyui": "^5.0.47", + "esbuild": "^0.25.5", "postcss": "^8.4.38", - "postcss-import": "^15.1.0", - "tailwindcss": "^3.3.3" + "tailwindcss": "^4.1.11" } }, "../deps/phoenix": { - "version": "1.7.11", + "version": "1.7.21", "license": "MIT" }, "../deps/phoenix_html": { - "version": "4.1.0" + "version": "4.2.1" }, "../deps/phoenix_live_view": { - "version": "0.20.14", + "version": "1.0.17", "license": "MIT", + "dependencies": { + "morphdom": "2.7.5" + }, "devDependencies": { - "@playwright/test": "^1.41.0" + "@babel/cli": "7.27.0", + "@babel/core": "7.26.10", + "@babel/preset-env": "7.26.9", + "@eslint/js": "^9.24.0", + "@playwright/test": "^1.51.1", + "@stylistic/eslint-plugin-js": "^4.2.0", + "css.escape": "^1.5.1", + "eslint": "9.24.0", + "eslint-plugin-jest": "28.11.0", + "eslint-plugin-playwright": "^2.2.0", + "globals": "^16.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-monocart-coverage": "^1.1.1", + "monocart-reporter": "^2.9.17", + "phoenix": "1.7.21" } }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -53,10 +74,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", "cpu": [ "ppc64" ], @@ -66,13 +101,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "cpu": [ "arm" ], @@ -82,13 +117,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "cpu": [ "arm64" ], @@ -98,13 +133,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", "cpu": [ "x64" ], @@ -114,13 +149,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", "cpu": [ "arm64" ], @@ -130,13 +165,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", "cpu": [ "x64" ], @@ -146,13 +181,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "cpu": [ "arm64" ], @@ -162,13 +197,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "cpu": [ "x64" ], @@ -178,13 +213,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "cpu": [ "arm" ], @@ -194,13 +229,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "cpu": [ "arm64" ], @@ -210,13 +245,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "cpu": [ "ia32" ], @@ -226,13 +261,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "cpu": [ "loong64" ], @@ -242,13 +277,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "cpu": [ "mips64el" ], @@ -258,13 +293,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "cpu": [ "ppc64" ], @@ -274,13 +309,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", "cpu": [ "riscv64" ], @@ -290,13 +325,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "cpu": [ "s390x" ], @@ -306,13 +341,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", "cpu": [ "x64" ], @@ -322,13 +357,29 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", "cpu": [ "x64" ], @@ -338,13 +389,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", "cpu": [ "x64" ], @@ -354,13 +421,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", "cpu": [ "x64" ], @@ -370,13 +437,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "cpu": [ "arm64" ], @@ -386,13 +453,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "cpu": [ "ia32" ], @@ -402,13 +469,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "cpu": [ "x64" ], @@ -418,7 +485,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@floating-ui/core": { @@ -443,80 +510,63 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "minipass": "^7.0.4" }, "engines": { - "node": ">=6.0.0" + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" }, "node_modules/@sjmc11/tourguidejs": { "version": "0.0.16", @@ -527,12 +577,280 @@ "sass": "^1.55.0" } }, - "node_modules/@tailwindcss/container-queries": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", - "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==", - "peerDependencies": { - "tailwindcss": ">=3.2.0" + "node_modules/@tailwindcss/node": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", + "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.11" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", + "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-x64": "4.1.11", + "@tailwindcss/oxide-freebsd-x64": "4.1.11", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-x64-musl": "4.1.11", + "@tailwindcss/oxide-wasm32-wasi": "4.1.11", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", + "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", + "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", + "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", + "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", + "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", + "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", + "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", + "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", + "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", + "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.11", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", + "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", + "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.11.tgz", + "integrity": "sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.11", + "@tailwindcss/oxide": "4.1.11", + "postcss": "^8.4.41", + "tailwindcss": "4.1.11" } }, "node_modules/@vue/reactivity": { @@ -569,11 +887,6 @@ "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -586,53 +899,6 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -644,15 +910,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -664,66 +921,28 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/chart.js": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", + "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" + "@kurkle/color": "^0.3.0" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "pnpm": ">=8" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" + "node_modules/chartjs-adapter-moment": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.1.tgz", + "integrity": "sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==", + "license": "MIT", + "peerDependencies": { + "chart.js": ">=3.0.0", + "moment": "^2.10.2" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001609", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz", - "integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -747,114 +966,88 @@ "fsevents": "~2.3.2" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 6" + "node": ">=18" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "node_modules/daisyui": { + "version": "5.0.47", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.47.tgz", + "integrity": "sha512-RuYjjVKpodDoOYAHIvG6qC3BeRxhlyj4JCO+6aV0VzK+i3RWD7cmICh0m5+Xfr5938mV0Mk7FUOQ00msz8H8dw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/saadeghi/daisyui?sponsor=1" + } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", - "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==", - "dev": true - }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dependencies": { - "reusify": "^1.0.4" + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" } }, "node_modules/fill-range": { @@ -868,24 +1061,6 @@ "node": ">=8" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -899,14 +1074,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -918,36 +1085,18 @@ "node": ">= 6" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" }, "node_modules/immutable": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -959,17 +1108,6 @@ "node": ">=8" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -998,55 +1136,301 @@ } }, "node_modules/jiti": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", - "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, "engines": { "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/moment": { @@ -1068,26 +1452,18 @@ "node": "*" } }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1095,12 +1471,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1109,52 +1479,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "node_modules/phoenix": { "resolved": "../deps/phoenix", "link": true @@ -1168,9 +1492,11 @@ "link": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -1183,26 +1509,11 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "engines": { - "node": ">= 6" - } - }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1217,112 +1528,16 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" - }, - "engines": { - "node": ">= 14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, "node_modules/qr-code-styling": { "version": "1.6.0-rc.1", "resolved": "https://registry.npmjs.org/qr-code-styling/-/qr-code-styling-1.6.0-rc.1.tgz", @@ -1336,33 +1551,6 @@ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz", "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==" }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dependencies": { - "pify": "^2.3.0" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1374,53 +1562,6 @@ "node": ">=8.10.0" } }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/sass": { "version": "1.72.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", @@ -1438,9 +1579,10 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1455,121 +1597,39 @@ "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz", "integrity": "sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw==" }, - "node_modules/sucrase": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", - "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "7.1.6", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/tailwindcss": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", - "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.2.12", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.18.2", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", + "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=6" } }, - "node_modules/tailwindcss/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.3" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" }, "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" + "node": ">=18" } }, "node_modules/tiny-slider": { @@ -1588,57 +1648,14 @@ "node": ">=8.0" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 14" + "node": ">=18" } } }, @@ -1646,166 +1663,191 @@ "@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true + }, + "@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } }, "@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", "dev": true, "optional": true }, "@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "dev": true, "optional": true }, @@ -1831,62 +1873,51 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "minipass": "^7.0.4" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } + "@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" }, "@sjmc11/tourguidejs": { "version": "0.0.16", @@ -1897,11 +1928,147 @@ "sass": "^1.55.0" } }, - "@tailwindcss/container-queries": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", - "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==", - "requires": {} + "@tailwindcss/node": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", + "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.11" + } + }, + "@tailwindcss/oxide": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", + "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", + "dev": true, + "requires": { + "@tailwindcss/oxide-android-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-arm64": "4.1.11", + "@tailwindcss/oxide-darwin-x64": "4.1.11", + "@tailwindcss/oxide-freebsd-x64": "4.1.11", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", + "@tailwindcss/oxide-linux-x64-musl": "4.1.11", + "@tailwindcss/oxide-wasm32-wasi": "4.1.11", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.11", + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + } + }, + "@tailwindcss/oxide-android-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", + "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", + "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-darwin-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", + "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", + "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", + "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", + "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", + "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", + "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", + "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", + "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", + "dev": true, + "optional": true, + "requires": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.11", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + } + }, + "@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", + "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", + "dev": true, + "optional": true + }, + "@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", + "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", + "dev": true, + "optional": true + }, + "@tailwindcss/postcss": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.11.tgz", + "integrity": "sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==", + "dev": true, + "requires": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.11", + "@tailwindcss/oxide": "4.1.11", + "postcss": "^8.4.41", + "tailwindcss": "4.1.11" + } }, "@vue/reactivity": { "version": "3.1.5", @@ -1937,11 +2104,6 @@ "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -1951,44 +2113,11 @@ "picomatch": "^2.0.4" } }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, - "requires": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, "binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -1997,28 +2126,19 @@ "fill-range": "^7.1.1" } }, - "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, + "chart.js": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", + "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "@kurkle/color": "^0.3.0" } }, - "camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" - }, - "caniuse-lite": { - "version": "1.0.30001609", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz", - "integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==", - "dev": true + "chartjs-adapter-moment": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.1.tgz", + "integrity": "sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==", + "requires": {} }, "chokidar": { "version": "3.6.0", @@ -2035,92 +2155,65 @@ "readdirp": "~3.6.0" } }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "cssesc": { + "chownr": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "electron-to-chromium": { - "version": "1.4.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", - "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true }, - "esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "daisyui": { + "version": "5.0.47", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.47.tgz", + "integrity": "sha512-RuYjjVKpodDoOYAHIvG6qC3BeRxhlyj4JCO+6aV0VzK+i3RWD7cmICh0m5+Xfr5938mV0Mk7FUOQ00msz8H8dw==", + "dev": true + }, + "detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, "requires": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" } }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "requires": { - "reusify": "^1.0.4" + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" } }, "fill-range": { @@ -2131,28 +2224,12 @@ "to-regex-range": "^5.0.1" } }, - "fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -2161,33 +2238,17 @@ "is-glob": "^4.0.1" } }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "requires": { - "function-bind": "^1.1.2" - } + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "immutable": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2196,14 +2257,6 @@ "binary-extensions": "^2.0.0" } }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2223,42 +2276,130 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jiti": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", - "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==" + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dev": true, "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "detect-libc": "^2.0.3", + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "dev": true, + "optional": true + }, + "lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "dev": true, + "optional": true + }, + "lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "dev": true, + "optional": true + }, + "lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "dev": true, + "optional": true + }, + "lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "dev": true, + "optional": true + }, + "lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "dev": true, + "optional": true + }, + "lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "dev": true, + "optional": true + }, + "lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "dev": true, + "optional": true + }, + "lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "dev": true, + "optional": true + }, + "lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "dev": true, + "optional": true + }, + "magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "requires": { + "minipass": "^7.1.2" + } + }, + "mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -2272,25 +2413,10 @@ "moment": "^2.29.4" } }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==" - }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true }, "normalize-path": { @@ -2298,40 +2424,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "phoenix": { "version": "file:../deps/phoenix" }, @@ -2341,88 +2433,47 @@ "phoenix_live_view": { "version": "file:../deps/phoenix_live_view", "requires": { - "@playwright/test": "^1.41.0" + "@babel/cli": "7.27.0", + "@babel/core": "7.26.10", + "@babel/preset-env": "7.26.9", + "@eslint/js": "^9.24.0", + "@playwright/test": "^1.51.1", + "@stylistic/eslint-plugin-js": "^4.2.0", + "css.escape": "^1.5.1", + "eslint": "9.24.0", + "eslint-plugin-jest": "28.11.0", + "eslint-plugin-playwright": "^2.2.0", + "globals": "^16.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-monocart-coverage": "^1.1.1", + "monocart-reporter": "^2.9.17", + "morphdom": "2.7.5", + "phoenix": "1.7.21" } }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" - }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" - }, "postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" } }, - "postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" - } - }, - "postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "requires": { - "postcss-selector-parser": "^6.0.11" - } - }, - "postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, "qr-code-styling": { "version": "1.6.0-rc.1", "resolved": "https://registry.npmjs.org/qr-code-styling/-/qr-code-styling-1.6.0-rc.1.tgz", @@ -2436,19 +2487,6 @@ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz", "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==" }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "requires": { - "pify": "^2.3.0" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2457,29 +2495,6 @@ "picomatch": "^2.2.1" } }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, "sass": { "version": "1.72.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", @@ -2491,9 +2506,9 @@ } }, "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" }, "split-grid": { "version": "1.0.11", @@ -2505,93 +2520,30 @@ "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz", "integrity": "sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw==" }, - "sucrase": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", - "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "7.1.6", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, "tailwindcss": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", - "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "requires": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.2.12", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.18.2", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "dependencies": { - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "requires": { - "is-glob": "^4.0.3" - } - } - } + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", + "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", + "dev": true }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "requires": { - "any-promise": "^1.0.0" - } + "tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, "requires": { - "thenify": ">= 3.1.0 < 4" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" } }, "tiny-slider": { @@ -2607,35 +2559,11 @@ "is-number": "^7.0.0" } }, - "ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==" + "yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true } } } diff --git a/assets/package.json b/assets/package.json index f7f2c37..6911815 100644 --- a/assets/package.json +++ b/assets/package.json @@ -3,18 +3,20 @@ "deploy": "NODE_ENV=production tailwindcss --postcss --minify --input=css/app.css --output=../priv/static/assets/app.css" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.11", "alpinejs": "^3.13.8", - "autoprefixer": "^10.4.19", - "esbuild": "^0.20.2", + "daisyui": "^5.0.47", + "esbuild": "^0.25.5", "postcss": "^8.4.38", - "postcss-import": "^15.1.0", - "tailwindcss": "^3.3.3" + "tailwindcss": "^4.1.11" }, "dependencies": { "@sjmc11/tourguidejs": "^0.0.16", "@tailwindcss/container-queries": "^0.1.1", "air-datepicker": "^3.5.0", "animate.css": "^4.1.1", + "chart.js": "^4.4.0", + "chartjs-adapter-moment": "^1.0.1", "moment": "^2.29.4", "moment-timezone": "^0.5.43", "phoenix": "file:../deps/phoenix", diff --git a/assets/postcss.config.js b/assets/postcss.config.js index f6c9294..36521a5 100644 --- a/assets/postcss.config.js +++ b/assets/postcss.config.js @@ -1,7 +1,5 @@ module.exports = { plugins: { - "postcss-import": {}, - tailwindcss: {}, - autoprefixer: {}, + '@tailwindcss/postcss': {}, } } \ No newline at end of file diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js deleted file mode 100644 index d927e1d..0000000 --- a/assets/tailwind.config.js +++ /dev/null @@ -1,134 +0,0 @@ -const { colors: defaultColors } = require("tailwindcss/defaultTheme"); - -const colors = { - ...defaultColors, - ...{ - "water-blue": { - 50: "#E3F2FD", - 100: "#C2E3FA", - 200: "#84C8F6", - 300: "#3DA7F0", - 400: "#1395EC", - 500: "#1186D5", - 600: "#0D65A1", - 700: "#0A5689", - 800: "#0A4B76", - 900: "#073250", - }, - "electric-purple": { - 50: "#F2E0FF", - 100: "#E3BDFF", - 200: "#C77AFF", - 300: "#A62EFF", - 400: "#9200FF", - 500: "#A327FF", - 600: "#6400AD", - 700: "#550094", - 800: "#490080", - 900: "#320057", - }, - wedgewood: { - 50: "#F0F4F8", - 100: "#D9E3ED", - 200: "#B9CCDF", - 300: "#97B3CE", - 400: "#7499BE", - 500: "#507DAA", - 600: "#3F6388", - 700: "#314D68", - 800: "#253B50", - 900: "#1A2938", - }, - "rose-madder": { - 50: "#FCEDEE", - 100: "#F9D5D7", - 200: "#F3ABB0", - 300: "#ED8188", - 400: "#E75761", - 500: "#E12D39", - 600: "#B4242E", - 700: "#871B22", - 800: "#5A1217", - 900: "#2D090B", - }, - "school-bus-yellow": { - 50: "#FFFBEB", - 100: "#FEF3C7", - 200: "#FDE68A", - 300: "#FCD34D", - 400: "#FBBF24", - 500: "#F59E0B", - 600: "#D97706", - 700: "#B45309", - 800: "#92400E", - 900: "#78350F", - }, - "green-teal": { - 50: "#ECFDF5", - 100: "#D1FAE5", - 200: "#A7F3D0", - 300: "#6EE7B7", - 400: "#34D399", - 500: "#10B981", - 600: "#059669", - 700: "#047857", - 800: "#065F46", - 900: "#064E3B", - }, - }, -}; - -module.exports = { - mode: "jit", - content: ["./js/**/*.js", "../lib/*_web/**/*.*ex"], - safelist: [ - "-top-1.5", - "top-1", - "left-3", - "top-6", - "h-5", - "left-2.5", - "top-3", - "h-7", - "bg-secondary-600", - "text-white", - "bg-white", - "text-gray-600", - ], - darkMode: "media", - theme: { - extend: { - backgroundSize: { - "size-200": "200% 200%", - }, - backgroundPosition: { - "pos-0": "0% 0%", - "pos-100": "100% 100%", - }, - colors: { - primary: colors["water-blue"], - secondary: colors["electric-purple"], - neutral: colors["wedgewood"], - "supporting-red": colors["rose-madder"], - "supporting-yellow": colors["school-bus-yellow"], - "supporting-green": colors["green-teal"], - }, - }, - fontFamily: { - sans: ["Roboto", "sans-serif"], - serif: ["Merriweather", "serif"], - }, - boxShadow: { - base: "0px 1px 3px 0px rgba(0,0,0,0.1), 0px 1px 2px 0px rgba(0,0,0,0.06)", - lg: "0px 4px 6px 0px rgba(0,0,0,0.05), 0px 10px 15px 0px rgba(0,0,0,0.1)", - md: "0px 4px 6px 0px rgba(0,0,0,0.1), 0px 2px 4px 0px rgba(0,0,0,0.06)", - xl: "0px 10px 10px 0px rgba(0,0,0,0.04), 0px 20px 25px 0px rgba(0,0,0,0.1)", - "2xl": "0px 25px 50px 0px rgba(0,0,0,0.25)", - inner: "inset 0px 2px 4px 0px rgba(0,0,0,0.06)", - }, - }, - variants: { - extend: {}, - }, - plugins: [require("@tailwindcss/container-queries")], -}; diff --git a/charts/claper/templates/_env.yaml b/charts/claper/templates/_env.yaml index 8ac902c..0af766f 100644 --- a/charts/claper/templates/_env.yaml +++ b/charts/claper/templates/_env.yaml @@ -16,15 +16,15 @@ value: claper.co - name: DATABASE_URL value: postgresql://claper:claper@10.0.0.6:6432/claper -- name: AWS_ACCESS_KEY_ID +- name: S3_ACCESS_KEY_ID value: XXX -- name: AWS_PRES_BUCKET +- name: S3_BUCKET value: XXX - name: POOL_SIZE value: "20" -- name: AWS_REGION +- name: S3_REGION value: eu-west-3 -- name: AWS_SECRET_ACCESS_KEY +- name: S3_SECRET_ACCESS_KEY value: XXX - name: PRESENTATION_STORAGE value: s3 diff --git a/config/config.exs b/config/config.exs index 1aa67c7..51120c3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -36,9 +36,26 @@ config :dart_sass, cd: Path.expand("../assets", __DIR__) ] +config :tailwind, + version: "4.1.10", + default: [ + args: ~w( + --input=assets/css/app.css + --output=priv/static/assets/app.css + ), + cd: Path.expand("..", __DIR__) + ], + admin: [ + args: ~w( + --input=assets/css/admin.css + --output=priv/static/assets/admin.css + ), + cd: Path.expand("..", __DIR__) + ] + # Configure esbuild (the version is required) config :esbuild, - version: "0.12.18", + version: "0.25.5", default: [ args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*), diff --git a/config/dev.exs b/config/dev.exs index 720a20b..41198be 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -13,19 +13,13 @@ config :claper, ClaperWeb.Endpoint, watchers: [ # Start the esbuild watcher by calling Esbuild.install_and_run(:default, args) esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}, + tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}, + tailwind_admin: {Tailwind, :install_and_run, [:admin, ~w(--watch)]}, sass: { DartSass, :install_and_run, [:default, ~w(--embed-source-map --source-map-urls=absolute --watch)] - }, - npx: [ - "tailwindcss", - "--input=css/app.css", - "--output=../priv/static/assets/app.css", - "--postcss", - "--watch", - cd: Path.expand("../assets", __DIR__) - ] + } ] # Watch static and templates for browser reloading. diff --git a/config/runtime.exs b/config/runtime.exs index 8fd9681..d1e0476 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -86,9 +86,39 @@ smtp_tls = get_var_from_path_or_env(config_dir, "SMTP_TLS", "always") smtp_auth = get_var_from_path_or_env(config_dir, "SMTP_AUTH", "always") smtp_port = get_int_from_path_or_env(config_dir, "SMTP_PORT", 25) -aws_access_key_id = get_var_from_path_or_env(config_dir, "AWS_ACCESS_KEY_ID", nil) -aws_secret_access_key = get_var_from_path_or_env(config_dir, "AWS_SECRET_ACCESS_KEY", nil) -aws_region = get_var_from_path_or_env(config_dir, "AWS_REGION", nil) +storage = get_var_from_path_or_env(config_dir, "PRESENTATION_STORAGE", "local") +if storage not in ["local", "s3"], do: raise("Invalid PRESENTATION_STORAGE value #{storage}") + +s3_access_key_id = get_var_from_path_or_env(config_dir, "S3_ACCESS_KEY_ID") +s3_secret_access_key = get_var_from_path_or_env(config_dir, "S3_SECRET_ACCESS_KEY") +s3_region = get_var_from_path_or_env(config_dir, "S3_REGION") +s3_bucket = get_var_from_path_or_env(config_dir, "S3_BUCKET") + +if storage == "s3" and + not Enum.all?([s3_access_key_id, s3_secret_access_key, s3_region, s3_bucket]) do + raise( + "S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGION and S3_BUCKET required when PRESENTATION_STORAGE=s3" + ) +end + +s3_scheme = get_var_from_path_or_env(config_dir, "S3_SCHEME") +s3_host = get_var_from_path_or_env(config_dir, "S3_HOST") +s3_port = get_var_from_path_or_env(config_dir, "S3_PORT") + +if storage == "s3" do + if !!s3_scheme and !s3_host, do: "S3_HOST required if S3_SCHEME is set" + if !s3_scheme and !!s3_host, do: "S3_SCHEME required if S3_HOST is set" +end + +s3_public_url = + get_var_from_path_or_env( + config_dir, + "S3_PUBLIC_URL", + if(s3_scheme && s3_host, + do: s3_scheme <> s3_host <> if(s3_port, do: ":#{s3_port}", else: ""), + else: "https://#{s3_bucket}.s3.#{s3_region}.amazonaws.com" + ) + ) same_site_cookie = get_var_from_path_or_env(config_dir, "SAME_SITE_COOKIE", "Lax") @@ -128,6 +158,11 @@ allow_unlink_external_provider = logout_redirect_url = get_var_from_path_or_env(config_dir, "LOGOUT_REDIRECT_URL", nil) +languages = + get_var_from_path_or_env(config_dir, "LANGUAGES", "en,fr,es,it,de") + |> String.split(",") + |> Enum.map(&String.trim/1) + config :claper, :oidc, enabled: oidc_enabled, issuer: oidc_issuer, @@ -166,13 +201,15 @@ config :claper, enable_account_creation: enable_account_creation, email_confirmation: email_confirmation, allow_unlink_external_provider: allow_unlink_external_provider, - logout_redirect_url: logout_redirect_url + logout_redirect_url: logout_redirect_url, + languages: languages config :claper, :presentations, max_file_size: max_file_size, - storage: get_var_from_path_or_env(config_dir, "PRESENTATION_STORAGE", "local"), - aws_bucket: get_var_from_path_or_env(config_dir, "AWS_PRES_BUCKET", nil), - resolution: get_var_from_path_or_env(config_dir, "GS_JPG_RESOLUTION", "300x300") + storage: storage, + s3_bucket: s3_bucket, + resolution: get_var_from_path_or_env(config_dir, "GS_JPG_RESOLUTION", "300x300"), + s3_public_url: s3_public_url config :claper, :mail, from: get_var_from_path_or_env(config_dir, "MAIL_FROM", "noreply@claper.co"), @@ -221,9 +258,10 @@ case mail_transport do end config :ex_aws, - access_key_id: aws_access_key_id, - secret_access_key: aws_secret_access_key, - region: aws_region, - normalize_path: false + access_key_id: s3_access_key_id, + secret_access_key: s3_secret_access_key, + region: s3_region, + normalize_path: false, + s3: [scheme: s3_scheme, host: s3_host, port: s3_port] config :swoosh, :api_client, Swoosh.ApiClient.Finch diff --git a/dev.sh b/dev.sh deleted file mode 100755 index 9254574..0000000 --- a/dev.sh +++ /dev/null @@ -1,14 +0,0 @@ -set -a -source .env -set +a - -args=("$@") - -if [ "${args[0]}" == "start" ]; then - mix phx.server -elif [ "${args[0]}" == "iex" ]; then - iex -S mix -else - mix "$@" -fi - diff --git a/docker-compose.yml b/docker-compose.yml index c25890c..0fe4637 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,6 @@ services: db: image: postgres:15 - ports: - - 5432:5432 volumes: - "claper-db:/var/lib/postgresql/data" healthcheck: diff --git a/elixir_buildpack.config b/elixir_buildpack.config deleted file mode 100644 index 63e1e63..0000000 --- a/elixir_buildpack.config +++ /dev/null @@ -1,2 +0,0 @@ -elixir_version=1.13.2 -erlang_version=24.0 diff --git a/lib/claper/accounts.ex b/lib/claper/accounts.ex index f93508c..0570419 100644 --- a/lib/claper/accounts.ex +++ b/lib/claper/accounts.ex @@ -7,7 +7,7 @@ defmodule Claper.Accounts do alias Claper.Accounts alias Claper.Repo - alias Claper.Accounts.{User, UserToken, UserNotifier} + alias Claper.Accounts.{User, UserToken, UserNotifier, Role} @doc """ Creates a user. @@ -20,6 +20,9 @@ defmodule Claper.Accounts do {:error, %Ecto.Changeset{}} """ def create_user(attrs) do + # Get user role if not explicitly set + attrs = maybe_set_default_role(attrs) + %User{} |> User.registration_changeset(attrs) |> Repo.insert(returning: [:uuid]) @@ -55,18 +58,39 @@ defmodule Claper.Accounts do def get_user_by_email_or_create(email) when is_binary(email) do case get_user_by_email(email) do nil -> - create_user(%{ + attrs = %{ email: email, confirmed_at: DateTime.utc_now(), is_randomized_password: true, password: :crypto.strong_rand_bytes(32) - }) + } + + # Set default role if not explicitly set + attrs = maybe_set_default_role(attrs) + + create_user(attrs) user -> {:ok, user} end end + @doc """ + Lists all users that are not deleted. + + ## Examples + + iex> list_users() + [%User{}, ...] + + """ + def list_users(preload \\ []) do + User + |> where([u], is_nil(u.deleted_at)) + |> Repo.all() + |> Repo.preload(preload) + end + @doc """ Gets a user by email and password. @@ -147,6 +171,9 @@ defmodule Claper.Accounts do """ def register_user(attrs) do + # Get user role if not explicitly set + attrs = maybe_set_default_role(attrs) + %User{} |> User.registration_changeset(attrs) |> Repo.insert(returning: [:uuid]) @@ -165,6 +192,37 @@ defmodule Claper.Accounts do User.registration_changeset(user, attrs, hash_password: false) end + @doc """ + Returns an `%Ecto.Changeset{}` for tracking user changes for admin operations. + + ## Examples + + iex> change_user(user) + %Ecto.Changeset{data: %User{}} + + """ + def change_user(%User{} = user, attrs \\ %{}) do + User.admin_changeset(user, attrs, hash_password: false) + end + + @doc """ + Updates a user for admin operations. + + ## Examples + + iex> update_user(user, %{field: new_value}) + {:ok, %User{}} + + iex> update_user(user, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_user(%User{} = user, attrs) do + user + |> User.admin_changeset(attrs) + |> Repo.update() + end + ## Settings @doc """ @@ -262,6 +320,23 @@ defmodule Claper.Accounts do end end + # Alternative version with different signature - keeping for compatibility + def update_user_password(user, %{"current_password" => curr_pw} = attrs) do + changeset = + user + |> User.password_changeset(attrs) + |> User.validate_current_password(curr_pw) + + Ecto.Multi.new() + |> Ecto.Multi.update(:user, changeset) + |> Ecto.Multi.delete_all(:tokens, UserToken.user_and_contexts_query(user, :all)) + |> Repo.transaction() + |> case do + {:ok, %{user: user}} -> {:ok, user} + {:error, :user, changeset, _} -> {:error, changeset} + end + end + @doc """ Sets the user password. ## Examples @@ -343,34 +418,6 @@ defmodule Claper.Accounts do User.password_changeset(user, attrs) end - @doc """ - Updates the user password. - - ## Examples - - iex> update_user_password(user, "valid password", %{password: ...}) - {:ok, %User{}} - - iex> update_user_password(user, "invalid password", %{password: ...}) - {:error, %Ecto.Changeset{}} - - """ - def update_user_password(user, %{"current_password" => curr_pw} = attrs) do - changeset = - user - |> User.password_changeset(attrs) - |> User.validate_current_password(curr_pw) - - Ecto.Multi.new() - |> Ecto.Multi.update(:user, changeset) - |> Ecto.Multi.delete_all(:tokens, UserToken.user_and_contexts_query(user, :all)) - |> Repo.transaction() - |> case do - {:ok, %{user: user}} -> {:ok, user} - {:error, :user, changeset, _} -> {:error, changeset} - end - end - ## Session @doc """ @@ -602,4 +649,271 @@ defmodule Claper.Accounts do {:error, changeset} -> {:error, changeset} end end + + ## Role Management + + @doc """ + Returns the list of roles. + + ## Examples + + iex> list_roles() + [%Role{}, ...] + + """ + def list_roles do + Repo.all(Role) + end + + @doc """ + Gets a single role. + + Raises `Ecto.NoResultsError` if the Role does not exist. + + ## Examples + + iex> get_role!(123) + %Role{} + + iex> get_role!(456) + ** (Ecto.NoResultsError) + + """ + def get_role!(id), do: Repo.get!(Role, id) + + @doc """ + Gets a role by name. + + Returns nil if the Role does not exist. + + ## Examples + + iex> get_role_by_name("admin") + %Role{} + + iex> get_role_by_name("nonexistent") + nil + + """ + def get_role_by_name(name) when is_binary(name) do + Repo.get_by(Role, name: name) + end + + @doc """ + Creates a role. + + ## Examples + + iex> create_role(%{field: value}) + {:ok, %Role{}} + + iex> create_role(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_role(attrs \\ %{}) do + %Role{} + |> Role.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a role. + + ## Examples + + iex> update_role(role, %{field: new_value}) + {:ok, %Role{}} + + iex> update_role(role, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_role(%Role{} = role, attrs) do + role + |> Role.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a role. + + ## Examples + + iex> delete_role(role) + {:ok, %Role{}} + + iex> delete_role(role) + {:error, %Ecto.Changeset{}} + + """ + def delete_role(%Role{} = role) do + Repo.delete(role) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking role changes. + + ## Examples + + iex> change_role(role) + %Ecto.Changeset{data: %Role{}} + + """ + def change_role(%Role{} = role, attrs \\ %{}) do + Role.changeset(role, attrs) + end + + @doc """ + Assigns a role to a user by role name or role struct. + + ## Examples + + iex> assign_role(user, "admin") + {:ok, %User{}} + + iex> assign_role(user, %Role{id: 1}) + {:ok, %User{}} + + iex> assign_role(user, "unknown") + {:error, :role_not_found} + """ + def assign_role(%User{} = user, %Role{} = role) do + user + |> Ecto.Changeset.change(%{role_id: role.id}) + |> Repo.update() + end + + def assign_role(%User{} = user, role_name) when is_binary(role_name) do + case get_role_by_name(role_name) do + nil -> + {:error, :role_not_found} + + role -> + user + |> Ecto.Changeset.change(%{role_id: role.id}) + |> Repo.update() + end + end + + @doc """ + Gets the role of a user. + + ## Examples + + iex> get_user_role(user) + %Role{} + + iex> get_user_role(user_without_role) + nil + """ + def get_user_role(%User{} = user) do + user = user |> Repo.preload(:role) + user.role + end + + @doc """ + Lists users by role name. + + ## Examples + + iex> list_users_by_role("admin") + [%User{}, ...] + + iex> list_users_by_role("unknown") + [] + """ + def list_users_by_role(role_name) when is_binary(role_name) do + case get_role_by_name(role_name) do + nil -> + [] + + role -> + User + |> where([u], u.role_id == ^role.id and is_nil(u.deleted_at)) + |> Repo.all() + end + end + + @doc """ + Checks if a user has a specific role. + + ## Examples + + iex> user_has_role?(user, "admin") + true + + iex> user_has_role?(user, "unknown") + false + """ + def user_has_role?(%User{} = user, role_name) when is_binary(role_name) do + case get_user_role(user) do + nil -> false + role -> role.name == role_name + end + end + + @doc """ + Promotes a user to admin role. + + ## Examples + + iex> promote_to_admin(user) + {:ok, %User{}} + + iex> promote_to_admin(already_admin_user) + {:ok, %User{}} + """ + def promote_to_admin(%User{} = user) do + assign_role(user, "admin") + end + + @doc """ + Demotes a user from admin role to regular user role. + + ## Examples + + iex> demote_from_admin(admin_user) + {:ok, %User{}} + + iex> demote_from_admin(already_user_user) + {:ok, %User{}} + """ + def demote_from_admin(%User{} = user) do + assign_role(user, "user") + end + + # Private helper to set default role if not already set + defp maybe_set_default_role(attrs) do + # Only set default role if role_id is not explicitly provided + case Map.get(attrs, :role_id) || Map.get(attrs, "role_id") do + nil -> set_default_user_role(attrs) + _ -> attrs + end + end + + defp set_default_user_role(attrs) do + case get_role_by_name("user") do + nil -> attrs + user_role -> put_role_id(attrs, user_role.id) + end + end + + defp put_role_id(attrs, role_id) do + key = determine_role_key(attrs) + Map.put(attrs, key, role_id) + end + + defp determine_role_key(attrs) do + if has_string_keys?(attrs) do + "role_id" + else + :role_id + end + end + + defp has_string_keys?(attrs) do + is_map(attrs) and map_size(attrs) > 0 and + Enum.all?(Map.keys(attrs), &is_binary/1) + end end diff --git a/lib/claper/accounts/guardian.ex b/lib/claper/accounts/guardian.ex new file mode 100644 index 0000000..0af6669 --- /dev/null +++ b/lib/claper/accounts/guardian.ex @@ -0,0 +1,27 @@ +defmodule Claper.Accounts.Guardian do + @moduledoc """ + Implementation module for Guardian authentication. + This module handles JWT token generation and validation for user authentication. + """ + + defmodule Plug do + @moduledoc """ + Plug helpers for Guardian authentication in tests. + """ + + @doc """ + Sign in a user to a conn. + + ## Parameters + - conn: The connection + - user: The user to sign in + + ## Returns + - Updated conn with user signed in + """ + def sign_in(conn, user) do + # For tests, we'll just put the user in the conn assigns + Elixir.Plug.Conn.assign(conn, :current_user, user) + end + end +end diff --git a/lib/claper/accounts/oidc.ex b/lib/claper/accounts/oidc.ex new file mode 100644 index 0000000..3961494 --- /dev/null +++ b/lib/claper/accounts/oidc.ex @@ -0,0 +1,119 @@ +defmodule Claper.Accounts.Oidc do + @moduledoc """ + The OIDC context for authentication and provider management. + """ + + import Ecto.Query, warn: false + alias Claper.Repo + alias Claper.Accounts.Oidc.Provider + + @doc """ + Returns the list of oidc_providers. + + ## Examples + + iex> list_providers() + [%Provider{}, ...] + + """ + def list_providers do + Repo.all(Provider) + end + + @doc """ + Gets a single provider. + + Raises `Ecto.NoResultsError` if the Provider does not exist. + + ## Examples + + iex> get_provider!(123) + %Provider{} + + iex> get_provider!(456) + ** (Ecto.NoResultsError) + + """ + def get_provider!(id), do: Repo.get!(Provider, id) + + @doc """ + Creates a provider. + + ## Examples + + iex> create_provider(%{field: value}) + {:ok, %Provider{}} + + iex> create_provider(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_provider(attrs \\ %{}) do + %Provider{} + |> Provider.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a provider. + + ## Examples + + iex> update_provider(provider, %{field: new_value}) + {:ok, %Provider{}} + + iex> update_provider(provider, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_provider(%Provider{} = provider, attrs) do + provider + |> Provider.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a provider. + + ## Examples + + iex> delete_provider(provider) + {:ok, %Provider{}} + + iex> delete_provider(provider) + {:error, %Ecto.Changeset{}} + + """ + def delete_provider(%Provider{} = provider) do + Repo.delete(provider) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking provider changes. + + ## Examples + + iex> change_provider(provider) + %Ecto.Changeset{data: %Provider{}} + + """ + def change_provider(%Provider{} = provider, attrs \\ %{}) do + Provider.changeset(provider, attrs) + end + + @doc """ + Search providers by name or issuer. + + ## Examples + + iex> search_providers("%example%") + [%Provider{}, ...] + + """ + def search_providers(search_term) do + from(p in Provider, + where: ilike(p.name, ^search_term) or ilike(p.issuer, ^search_term) + ) + |> Repo.all() + end +end diff --git a/lib/claper/accounts/oidc/provider.ex b/lib/claper/accounts/oidc/provider.ex new file mode 100644 index 0000000..ba1c10f --- /dev/null +++ b/lib/claper/accounts/oidc/provider.ex @@ -0,0 +1,57 @@ +defmodule Claper.Accounts.Oidc.Provider do + use Ecto.Schema + import Ecto.Changeset + + @type t :: %__MODULE__{ + id: integer(), + name: String.t(), + issuer: String.t(), + client_id: String.t(), + client_secret: String.t(), + redirect_uri: String.t(), + scope: String.t(), + active: boolean(), + response_type: String.t(), + response_mode: String.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + + schema "oidc_providers" do + field :name, :string + field :issuer, :string + field :client_id, :string + field :client_secret, :string + field :redirect_uri, :string + field :scope, :string, default: "openid email profile" + field :active, :boolean, default: true + field :response_type, :string, default: "code" + field :response_mode, :string, default: "query" + + timestamps() + end + + @doc """ + A changeset for creating or updating an OIDC provider. + """ + def changeset(provider, attrs) do + provider + |> cast(attrs, [ + :name, + :issuer, + :client_id, + :client_secret, + :redirect_uri, + :scope, + :active, + :response_type, + :response_mode + ]) + |> validate_required([:name, :issuer, :client_id, :client_secret, :redirect_uri]) + |> validate_format(:issuer, ~r/^https?:\/\//, message: "must start with http:// or https://") + |> validate_format(:redirect_uri, ~r/^https?:\/\//, + message: "must start with http:// or https://" + ) + |> unique_constraint(:name) + end +end diff --git a/lib/claper/accounts/role.ex b/lib/claper/accounts/role.ex new file mode 100644 index 0000000..d039093 --- /dev/null +++ b/lib/claper/accounts/role.ex @@ -0,0 +1,31 @@ +defmodule Claper.Accounts.Role do + use Ecto.Schema + import Ecto.Changeset + + @type t :: %__MODULE__{ + id: integer(), + name: String.t(), + permissions: map(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + + schema "roles" do + field :name, :string + field :permissions, :map, default: %{} + + has_many :users, Claper.Accounts.User + + timestamps() + end + + @doc """ + Changeset for creating or updating a role. + """ + def changeset(role, attrs) do + role + |> cast(attrs, [:name, :permissions]) + |> validate_required([:name]) + |> unique_constraint(:name) + end +end diff --git a/lib/claper/accounts/user.ex b/lib/claper/accounts/user.ex index d342307..2262642 100644 --- a/lib/claper/accounts/user.ex +++ b/lib/claper/accounts/user.ex @@ -13,6 +13,8 @@ defmodule Claper.Accounts.User do confirmed_at: NaiveDateTime.t() | nil, locale: String.t() | nil, events: [Claper.Events.Event.t()] | nil, + role: Claper.Accounts.Role.t() | nil, + role_id: integer() | nil, inserted_at: NaiveDateTime.t(), updated_at: NaiveDateTime.t(), deleted_at: NaiveDateTime.t() | nil @@ -30,15 +32,18 @@ defmodule Claper.Accounts.User do has_many :events, Claper.Events.Event has_one :lti_user, Lti13.Users.User + belongs_to :role, Claper.Accounts.Role + has_many :quiz_responses, Claper.Quizzes.QuizResponse timestamps() end def registration_changeset(user, attrs, opts \\ []) do user - |> cast(attrs, [:email, :confirmed_at, :password, :is_randomized_password]) + |> cast(attrs, [:email, :confirmed_at, :password, :is_randomized_password, :role_id]) |> validate_email() |> validate_password(opts) + |> foreign_key_constraint(:role_id) end def preferences_changeset(user, attrs) do @@ -46,6 +51,17 @@ defmodule Claper.Accounts.User do |> cast(attrs, [:locale]) end + @doc """ + A changeset for admin operations on users. + """ + def admin_changeset(user, attrs, opts \\ []) do + user + |> cast(attrs, [:email, :confirmed_at, :password, :role_id]) + |> validate_email() + |> validate_admin_password(opts) + |> foreign_key_constraint(:role_id) + end + @doc """ A changeset for marking a user as deleted. """ @@ -70,6 +86,19 @@ defmodule Claper.Accounts.User do |> maybe_hash_password(opts) end + defp validate_admin_password(changeset, opts) do + password = get_change(changeset, :password) + + # Only validate password if it's provided + if password && password != "" do + changeset + |> validate_length(:password, min: 6, max: 72) + |> maybe_hash_password(opts) + else + changeset + end + end + defp maybe_hash_password(changeset, opts) do hash_password? = Keyword.get(opts, :hash_password, true) password = get_change(changeset, :password) diff --git a/lib/claper/accounts/user_notifier.ex b/lib/claper/accounts/user_notifier.ex index b5f4321..cf8d784 100644 --- a/lib/claper/accounts/user_notifier.ex +++ b/lib/claper/accounts/user_notifier.ex @@ -52,7 +52,7 @@ defmodule Claper.Accounts.UserNotifier do Deliver instructions to update a user email. """ def deliver_update_email_instructions(user, url) do - Claper.Workers.Mailers.new_update_email(user.id, url) |> Oban.insert() + Claper.Workers.Mailers.new_update_email(user.email, url) |> Oban.insert() {:ok, :enqueued} end diff --git a/lib/claper/admin.ex b/lib/claper/admin.ex new file mode 100644 index 0000000..25dd736 --- /dev/null +++ b/lib/claper/admin.ex @@ -0,0 +1,635 @@ +defmodule Claper.Admin do + @moduledoc """ + The Admin context. + Provides functions for admin dashboard statistics and paginated lists of resources. + """ + + import Ecto.Query, warn: false + alias Claper.Repo + alias Claper.Accounts.User + alias Claper.Events.Event + alias Claper.Accounts.Oidc.Provider + + @doc """ + Gets dashboard statistics. + + Returns a map with counts of users, events, and upcoming events. + + ## Examples + + iex> get_dashboard_stats() + %{users_count: 10, events_count: 20, upcoming_events: 5} + + """ + def get_dashboard_stats do + users_count = + User + |> where([u], is_nil(u.deleted_at)) + |> Repo.aggregate(:count, :id) + + events_count = + Event + |> Repo.aggregate(:count, :id) + + _now = NaiveDateTime.utc_now() + + upcoming_events = + Event + |> where([e], is_nil(e.expired_at)) + |> Repo.aggregate(:count, :id) + + %{ + users_count: users_count, + events_count: events_count, + upcoming_events: upcoming_events + } + end + + @doc """ + Gets users over time for analytics charts. + + Returns user registration data grouped by time period. + + ## Parameters + - period: :day, :week, :month (default: :day) + - days_back: number of days to look back (default: 30) + + ## Examples + + iex> get_users_over_time(:day, 7) + %{ + labels: ["2025-01-10", "2025-01-11", ...], + values: [2, 5, 1, 3, ...] + } + """ + def get_users_over_time(period \\ :day, days_back \\ 30) do + end_date = NaiveDateTime.utc_now() + start_date = NaiveDateTime.add(end_date, -(days_back * 24 * 60 * 60), :second) + + # Generate all dates in the range + date_range = generate_date_range(start_date, end_date, period) + + # Get actual user counts per period using raw SQL to avoid parameter conflicts + period_sql_value = period_sql(period) + + sql = """ + SELECT DATE_TRUNC($1, inserted_at) as period, COUNT(id) as count + FROM users + WHERE deleted_at IS NULL + AND inserted_at >= $2 + AND inserted_at <= $3 + GROUP BY DATE_TRUNC($1, inserted_at) + ORDER BY period + """ + + result = Repo.query!(sql, [period_sql_value, start_date, end_date]) + + user_counts = + result.rows + |> Enum.map(fn [period, count] -> + normalized_period = NaiveDateTime.truncate(period, :second) + {normalized_period, count} + end) + |> Enum.into(%{}) + + # Format data for charts + labels = Enum.map(date_range, &format_date_label(&1, period)) + + values = + Enum.map(date_range, fn date -> + Map.get(user_counts, truncate_date(date, period), 0) + end) + + %{ + labels: labels, + values: values + } + end + + @doc """ + Gets events over time for analytics charts. + + Returns event creation data grouped by time period. + + ## Parameters + - period: :day, :week, :month (default: :day) + - days_back: number of days to look back (default: 30) + + ## Examples + + iex> get_events_over_time(:day, 7) + %{ + labels: ["2025-01-10", "2025-01-11", ...], + values: [1, 3, 0, 2, ...] + } + """ + def get_events_over_time(period \\ :day, days_back \\ 30) do + end_date = NaiveDateTime.utc_now() + start_date = NaiveDateTime.add(end_date, -(days_back * 24 * 60 * 60), :second) + + # Generate all dates in the range + date_range = generate_date_range(start_date, end_date, period) + + # Get actual event counts per period using raw SQL to avoid parameter conflicts + period_sql_value = period_sql(period) + + sql = """ + SELECT DATE_TRUNC($1, inserted_at) as period, COUNT(id) as count + FROM events + WHERE inserted_at >= $2 + AND inserted_at <= $3 + GROUP BY DATE_TRUNC($1, inserted_at) + ORDER BY period + """ + + result = Repo.query!(sql, [period_sql_value, start_date, end_date]) + + event_counts = + result.rows + |> Enum.map(fn [period, count] -> + # Normalize the timestamp by removing microseconds + normalized_period = NaiveDateTime.truncate(period, :second) + {normalized_period, count} + end) + |> Enum.into(%{}) + + # Format data for charts + labels = Enum.map(date_range, &format_date_label(&1, period)) + + values = + Enum.map(date_range, fn date -> + Map.get(event_counts, truncate_date(date, period), 0) + end) + + %{ + labels: labels, + values: values + } + end + + @doc """ + Gets growth metrics for dashboard statistics. + + Returns percentage growth for users and events compared to previous period. + """ + def get_growth_metrics do + now = NaiveDateTime.utc_now() + thirty_days_ago = NaiveDateTime.add(now, -(30 * 24 * 60 * 60), :second) + sixty_days_ago = NaiveDateTime.add(now, -(60 * 24 * 60 * 60), :second) + + # Current period (last 30 days) + current_users = + User + |> where([u], is_nil(u.deleted_at)) + |> where([u], u.inserted_at >= ^thirty_days_ago and u.inserted_at <= ^now) + |> Repo.aggregate(:count, :id) + + current_events = + Event + |> where([e], e.inserted_at >= ^thirty_days_ago and e.inserted_at <= ^now) + |> Repo.aggregate(:count, :id) + + # Previous period (30-60 days ago) + previous_users = + User + |> where([u], is_nil(u.deleted_at)) + |> where([u], u.inserted_at >= ^sixty_days_ago and u.inserted_at < ^thirty_days_ago) + |> Repo.aggregate(:count, :id) + + previous_events = + Event + |> where([e], e.inserted_at >= ^sixty_days_ago and e.inserted_at < ^thirty_days_ago) + |> Repo.aggregate(:count, :id) + + %{ + users_growth: calculate_growth_percentage(current_users, previous_users), + events_growth: calculate_growth_percentage(current_events, previous_events) + } + end + + @doc """ + Gets recent activity stats for dashboard. + + Returns counts of recent activities. + """ + def get_activity_stats do + now = NaiveDateTime.utc_now() + twenty_four_hours_ago = NaiveDateTime.add(now, -(24 * 60 * 60), :second) + seven_days_ago = NaiveDateTime.add(now, -(7 * 24 * 60 * 60), :second) + + %{ + users_today: + User + |> where([u], is_nil(u.deleted_at)) + |> where([u], u.inserted_at >= ^twenty_four_hours_ago) + |> Repo.aggregate(:count, :id), + events_today: + Event + |> where([e], e.inserted_at >= ^twenty_four_hours_ago) + |> Repo.aggregate(:count, :id), + users_this_week: + User + |> where([u], is_nil(u.deleted_at)) + |> where([u], u.inserted_at >= ^seven_days_ago) + |> Repo.aggregate(:count, :id), + events_this_week: + Event + |> where([e], e.inserted_at >= ^seven_days_ago) + |> Repo.aggregate(:count, :id) + } + end + + # Private helper functions + + defp generate_date_range(start_date, end_date, period) do + start_date + |> NaiveDateTime.to_date() + |> Date.range(NaiveDateTime.to_date(end_date)) + |> Enum.to_list() + |> case do + dates when period == :day -> + dates + + dates when period == :week -> + dates |> Enum.chunk_every(7) |> Enum.map(&List.first/1) + + dates when period == :month -> + dates |> Enum.group_by(&Date.beginning_of_month/1) |> Map.keys() + end + end + + defp period_sql(period) do + case period do + :day -> "day" + :week -> "week" + :month -> "month" + end + end + + defp format_date_label(date, period) do + case period do + :day -> Date.to_string(date) + :week -> "Week of #{Date.to_string(date)}" + :month -> "#{Date.to_string(date) |> String.slice(0..6)}" + end + end + + defp truncate_date(date, period) do + naive_date = NaiveDateTime.new!(date, ~T[00:00:00]) + + case period do + :day -> + NaiveDateTime.truncate(naive_date, :second) + + :week -> + days_to_subtract = Date.day_of_week(date) - 1 + + date + |> Date.add(-days_to_subtract) + |> NaiveDateTime.new!(~T[00:00:00]) + |> NaiveDateTime.truncate(:second) + + :month -> + date + |> Date.beginning_of_month() + |> NaiveDateTime.new!(~T[00:00:00]) + |> NaiveDateTime.truncate(:second) + end + end + + defp calculate_growth_percentage(current, previous) do + cond do + previous == 0 and current > 0 -> + 100.0 + + previous == 0 and current == 0 -> + 0.0 + + previous > 0 -> + :erlang.float_to_binary(((current - previous) / previous * 100) |> Float.round(1), + decimals: 1 + ) + + true -> + 0.0 + end + end + + @doc """ + Returns a paginated list of users. + + ## Options + + * `:page` - The page number (default: 1) + * `:per_page` - The number of users per page (default: 20) + * `:search` - Search term for filtering users by email + * `:role` - Filter users by role name + + ## Examples + + iex> list_users_paginated(%{page: 1, per_page: 10}) + %{entries: [%User{}, ...], page_number: 1, page_size: 10, total_entries: 20, total_pages: 2} + + """ + def list_users_paginated(params \\ %{}) do + page = Map.get(params, "page", 1) + per_page = Map.get(params, "per_page", 20) + search = Map.get(params, "search", "") + role = Map.get(params, "role", "") + + query = + User + |> where([u], is_nil(u.deleted_at)) + |> preload(:role) + + query = + if search != "" do + query |> where([u], ilike(u.email, ^"%#{search}%")) + else + query + end + + query = + if role != "" do + query |> join(:inner, [u], r in assoc(u, :role), on: r.name == ^role) + else + query + end + + query = query |> order_by([u], desc: u.inserted_at) + + Repo.paginate(query, page: page, page_size: per_page) + end + + @doc """ + Returns a paginated list of events. + + ## Options + + * `:page` - The page number (default: 1) + * `:per_page` - The number of events per page (default: 20) + * `:search` - Search term for filtering events by name + * `:status` - Filter events by status (upcoming, past) + * `:start_date` - Filter events by start date + * `:end_date` - Filter events by end date + * `:creator_id` - Filter events by creator ID + + ## Examples + + iex> list_events_paginated(%{page: 1, per_page: 10}) + %{entries: [%Event{}, ...], page_number: 1, page_size: 10, total_entries: 20, total_pages: 2} + + """ + def list_events_paginated(params \\ %{}) do + page = Map.get(params, "page", 1) + per_page = Map.get(params, "per_page", 20) + search = Map.get(params, "search", "") + status = Map.get(params, "status", "") + start_date = Map.get(params, "start_date", nil) + end_date = Map.get(params, "end_date", nil) + creator_id = Map.get(params, "creator_id", nil) + + query = + Event + |> preload(:user) + + query = + if search != "" do + query |> where([e], ilike(e.name, ^"%#{search}%")) + else + query + end + + query = + case status do + "upcoming" -> + now = NaiveDateTime.utc_now() + query |> where([e], e.started_at > ^now) + + "past" -> + now = NaiveDateTime.utc_now() + query |> where([e], e.started_at <= ^now) + + _ -> + query + end + + query = + if start_date do + query |> where([e], e.started_at >= ^start_date) + else + query + end + + query = + if end_date do + query |> where([e], e.started_at <= ^end_date) + else + query + end + + query = + if creator_id do + query |> where([e], e.user_id == ^creator_id) + else + query + end + + query = query |> order_by([e], desc: e.started_at) + + Repo.paginate(query, page: page, page_size: per_page) + end + + @doc """ + Returns a paginated list of OIDC providers. + + ## Options + + * `:page` - The page number (default: 1) + * `:per_page` - The number of providers per page (default: 20) + * `:search` - Search term for filtering providers by name + + ## Examples + + iex> list_oidc_providers_paginated(%{page: 1, per_page: 10}) + %{entries: [%Provider{}, ...], page_number: 1, page_size: 10, total_entries: 20, total_pages: 2} + + """ + def list_oidc_providers_paginated(params \\ %{}) do + page = Map.get(params, "page", 1) + per_page = Map.get(params, "per_page", 20) + search = Map.get(params, "search", "") + + query = Provider + + query = + if search != "" do + query |> where([p], ilike(p.name, ^"%#{search}%")) + else + query + end + + query = query |> order_by([p], p.name) + + Repo.paginate(query, page: page, page_size: per_page) + end + + @doc """ + Returns a complete list of OIDC providers for export purposes. + + Unlike the paginated version, this returns all providers matching the search criteria. + + ## Options + + * `:search` - Search term for filtering providers by name + + ## Examples + + iex> list_all_oidc_providers(%{search: "Google"}) + [%Provider{}, ...] + + """ + def list_all_oidc_providers(params \\ %{}) do + search = Map.get(params, "search", "") + + query = Provider + + query = + if search != "" do + query |> where([p], ilike(p.name, ^"%#{search}%")) + else + query + end + + query = query |> order_by([p], p.name) + + Repo.all(query) + end + + @doc """ + Returns a complete list of events for export purposes. + + Unlike the paginated version, this returns all events matching the search criteria. + + ## Options + + * `:search` - Search term for filtering events by name + * `:status` - Filter events by status (upcoming, past) + * `:start_date` - Filter events by start date + * `:end_date` - Filter events by end date + * `:creator_id` - Filter events by creator ID + + ## Examples + + iex> list_all_events(%{search: "Conference"}) + [%Event{}, ...] + + """ + def list_all_events(params \\ %{}) do + Event + |> join(:left, [e], u in assoc(e, :user)) + |> preload([e, u], user: u) + |> apply_event_search_filter(Map.get(params, "search", "")) + |> apply_event_status_filter(Map.get(params, "status", "")) + |> apply_event_start_date_filter(Map.get(params, "start_date", nil)) + |> apply_event_end_date_filter(Map.get(params, "end_date", nil)) + |> apply_event_creator_filter(Map.get(params, "creator_id", nil)) + |> order_by([e], desc: e.started_at) + |> Repo.all() + |> Enum.map(fn event -> Map.put(event, :user_email, event.user.email) end) + end + + defp apply_event_search_filter(query, ""), do: query + + defp apply_event_search_filter(query, search) do + search_term = "%#{search}%" + + query + |> where( + [e, u], + ilike(e.name, ^search_term) or ilike(e.code, ^search_term) or + ilike(u.email, ^search_term) + ) + end + + defp apply_event_status_filter(query, "upcoming") do + now = NaiveDateTime.utc_now() + query |> where([e], e.started_at > ^now) + end + + defp apply_event_status_filter(query, "past") do + now = NaiveDateTime.utc_now() + query |> where([e], e.started_at <= ^now) + end + + defp apply_event_status_filter(query, _), do: query + + defp apply_event_start_date_filter(query, nil), do: query + + defp apply_event_start_date_filter(query, start_date) do + query |> where([e], e.started_at >= ^start_date) + end + + defp apply_event_end_date_filter(query, nil), do: query + + defp apply_event_end_date_filter(query, end_date) do + query |> where([e], e.started_at <= ^end_date) + end + + defp apply_event_creator_filter(query, nil), do: query + + defp apply_event_creator_filter(query, creator_id) do + query |> where([e], e.user_id == ^creator_id) + end + + @doc """ + Returns a complete list of users for export purposes. + + Unlike the paginated version, this returns all users matching the search criteria. + + ## Options + + * `:search` - Search term for filtering users by email or name + * `:role` - Filter users by role ID + + ## Examples + + iex> list_all_users(%{search: "admin"}) + [%User{}, ...] + + """ + def list_all_users(params \\ %{}) do + search = Map.get(params, "search", "") + role = Map.get(params, "role", "") + + query = + User + |> where([u], is_nil(u.deleted_at)) + |> preload(:role) + + query = + if search != "" do + query |> where([u], ilike(u.email, ^"%#{search}%") or ilike(u.name, ^"%#{search}%")) + else + query + end + + query = + if role != "" do + query |> where([u], u.role_id == ^role) + else + query + end + + query = query |> order_by([u], u.email) + + # Add a virtual field for role_name to make it accessible in CSV export + Repo.all(query) + |> Enum.map(fn user -> + role_name = if user.role, do: user.role.name, else: "none" + + user + |> Map.put(:role_name, role_name) + end) + end +end diff --git a/lib/claper/embeds/embed.ex b/lib/claper/embeds/embed.ex index 8030588..f05bc9d 100644 --- a/lib/claper/embeds/embed.ex +++ b/lib/claper/embeds/embed.ex @@ -1,7 +1,7 @@ defmodule Claper.Embeds.Embed do use Ecto.Schema import Ecto.Changeset - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext @type t :: %__MODULE__{ id: integer(), @@ -61,7 +61,7 @@ defmodule Claper.Embeds.Embed do |> validate_format(:content, ~r/^https?:\/\/.+$/, message: gettext("Please enter a valid link starting with http:// or https://") ) - |> validate_format(:content, ~r/youtu\.be/, + |> validate_format(:content, ~r/(youtu\.be)|(youtube\.com)/, message: gettext("Please enter a valid %{provider} link", provider: "YouTube") ) diff --git a/lib/claper/events.ex b/lib/claper/events.ex index 131c8fa..b19b550 100644 --- a/lib/claper/events.ex +++ b/lib/claper/events.ex @@ -6,8 +6,8 @@ defmodule Claper.Events do """ import Ecto.Query, warn: false - alias Claper.Repo + alias Claper.{Accounts, Presentations, Repo} alias Claper.Events.{Event, ActivityLeader} @default_page_size 5 @@ -22,7 +22,7 @@ defmodule Claper.Events do """ def list_events(user_id, preload \\ []) do - from(e in Event, where: e.user_id == ^user_id, order_by: [desc: e.inserted_at]) + from(e in Event, where: e.user_id == ^user_id, order_by: [desc: e.id]) |> Repo.all() |> Repo.preload(preload) end @@ -43,7 +43,7 @@ defmodule Claper.Events do query = from(e in Event, where: e.user_id == ^user_id, - order_by: [desc: e.inserted_at] + order_by: [desc: e.id] ) Repo.paginate(query, page: page, page_size: page_size, preload: preload) @@ -61,7 +61,7 @@ defmodule Claper.Events do def list_not_expired_events(user_id, preload \\ []) do from(e in Event, where: e.user_id == ^user_id and is_nil(e.expired_at), - order_by: [desc: e.inserted_at] + order_by: [desc: e.id] ) |> Repo.all() |> Repo.preload(preload) @@ -83,7 +83,7 @@ defmodule Claper.Events do query = from(e in Event, where: e.user_id == ^user_id and is_nil(e.expired_at), - order_by: [desc: e.inserted_at] + order_by: [desc: e.id] ) Repo.paginate(query, page: page, page_size: page_size, preload: preload) @@ -140,12 +140,12 @@ defmodule Claper.Events do """ def list_managed_events_by(email, preload \\ []) do from(a in ActivityLeader, - join: u in Claper.Accounts.User, + join: u in Accounts.User, on: u.email == a.email, join: e in Event, on: e.id == a.event_id, where: a.email == ^email, - order_by: [desc: e.expired_at], + order_by: [desc: e.expired_at, desc: e.id], select: e ) |> Repo.all() @@ -167,12 +167,12 @@ defmodule Claper.Events do query = from(a in ActivityLeader, - join: u in Claper.Accounts.User, + join: u in Accounts.User, on: u.email == a.email, join: e in Event, on: e.id == a.event_id, where: a.email == ^email, - order_by: [desc: e.expired_at], + order_by: [desc: e.expired_at, desc: e.id], select: e ) @@ -181,7 +181,7 @@ defmodule Claper.Events do def count_managed_events_by(email) do from(a in ActivityLeader, - join: u in Claper.Accounts.User, + join: u in Accounts.User, on: u.email == a.email, join: e in Event, on: e.id == a.event_id, @@ -193,8 +193,7 @@ defmodule Claper.Events do def count_expired_events(user_id) do from(e in Event, - where: e.user_id == ^user_id and not is_nil(e.expired_at), - order_by: [desc: e.expired_at] + where: e.user_id == ^user_id and not is_nil(e.expired_at) ) |> Repo.aggregate(:count, :id) end @@ -207,28 +206,42 @@ defmodule Claper.Events do from(e in Event, where: e.user_id == ^user_id and e.inserted_at <= ^DateTime.utc_now() and - e.inserted_at >= ^last_month, - order_by: [desc: e.id] + e.inserted_at >= ^last_month ) |> Repo.aggregate(:count, :id) end @doc """ - Gets a single event. + Gets a single event by serial ID or UUID. Raises `Ecto.NoResultsError` if the Event does not exist. ## Examples + iex> get_event!(123) + %Event{} + iex> get_event!("123e4567-e89b-12d3-a456-426614174000") %Event{} + iex> get_event!(456) + ** (Ecto.NoResultsError) + iex> get_event!("123e4567-e89b-12d3-a456-4266141740111") ** (Ecto.NoResultsError) """ - def get_event!(id, preload \\ []), - do: Repo.get_by!(Event, uuid: id) |> Repo.preload(preload) + def get_event!(id_or_uuid, preload \\ []) + + def get_event!( + <<_::bytes-8, "-", _::bytes-4, "-", _::bytes-4, "-", _::bytes-4, "-", _::bytes-12>> = + uuid, + preload + ), + do: Repo.get_by!(Event, uuid: uuid) |> Repo.preload(preload) + + def get_event!(id, preload), + do: Repo.get!(Event, id) |> Repo.preload(preload) @doc """ Gets a single managed event. @@ -244,17 +257,18 @@ defmodule Claper.Events do ** (Ecto.NoResultsError) """ - def get_managed_event!(current_user, id, preload \\ []) do - event = Repo.get_by!(Event, uuid: id) - - is_leader = - Claper.Events.leaded_by?(current_user.email, event) || event.user_id == current_user.id - - if is_leader do - event |> Repo.preload(preload) - else - raise Ecto.NoResultsError - end + def get_managed_event!(user, uuid, preload \\ []) do + from( + e in Event, + join: u in Accounts.User, + on: e.user_id == u.id, + left_join: a in ActivityLeader, + on: e.id == a.event_id, + where: e.uuid == ^uuid and (u.id == ^user.id or a.email == ^user.email), + select: e + ) + |> Repo.one!() + |> Repo.preload(preload) end @doc """ @@ -304,43 +318,22 @@ defmodule Claper.Events do |> Repo.preload(preload) end - @doc """ - Get a single event with the same code excluding a specific event. - - ## Examples - - iex> get_different_event_with_code("Hello", 123) - %Event{} - - - """ - def get_different_event_with_code(nil, _event_id), do: nil - - def get_different_event_with_code(code, event_id) do - now = DateTime.utc_now() - - from(e in Event, where: e.code == ^code and e.id != ^event_id and e.expired_at > ^now) - |> Repo.one() - end - @doc """ Check if a user is a facilitator of a specific event. ## Examples - iex> leaded_by?("email@example.com", 123) + iex> led_by?("email@example.com", 123) true - """ - def leaded_by?(email, event) do + def led_by?(email, event) do from(a in ActivityLeader, - join: u in Claper.Accounts.User, + join: u in Accounts.User, on: u.email == a.email, join: e in Event, on: e.id == a.event_id, - where: a.email == ^email and e.id == ^event.id, - order_by: [desc: e.expired_at] + where: a.email == ^email and e.id == ^event.id ) |> Repo.exists?() end @@ -363,7 +356,10 @@ defmodule Claper.Events do |> validate_unique_event() |> case do {:ok, event} -> - Repo.insert(event, returning: [:uuid]) + with {:ok, event} <- Repo.insert(event, returning: [:uuid]) do + broadcast_all_users({:created, event}) + {:ok, event} + end {:error, changeset} -> {:error, %{changeset | action: :insert}} @@ -384,6 +380,15 @@ defmodule Claper.Events do end end + defp get_different_event_with_code(nil, _event_id), do: nil + + defp get_different_event_with_code(code, event_id) do + now = DateTime.utc_now() + + from(e in Event, where: e.code == ^code and e.id != ^event_id and e.expired_at > ^now) + |> Repo.one() + end + @doc """ Updates an event. @@ -402,7 +407,25 @@ defmodule Claper.Events do |> validate_unique_event() |> case do {:ok, event} -> - Repo.update(event, returning: [:uuid]) + with {:ok, event} <- Repo.update(event, returning: [:uuid]) do + broadcast_all_users({:updated, event}) + + deleted_leaders = + attrs + |> Map.get("leaders", %{}) + |> Map.values() + |> Enum.filter(fn + %{"delete" => "true"} -> true + _ -> false + end) + + for %{"email" => leader_email} <- deleted_leaders do + leader = Accounts.get_user_by_email(leader_email) + broadcast_user_events(leader.id, {:updated, event}) + end + + {:ok, event} + end {:error, changeset} -> {:error, %{changeset | action: :update}} @@ -424,7 +447,9 @@ defmodule Claper.Events do |> Repo.update() |> case do {:ok, event} -> - broadcast({:ok, event, event.uuid}, :event_terminated) + broadcast_all_users({:updated, event}) + broadcast_event(event.uuid, {:event_terminated, event.uuid}) + {:ok, event} {:error, changeset} -> {:error, %{changeset | action: :update}} @@ -517,7 +542,10 @@ defmodule Claper.Events do end @doc """ - Duplicate an event + Duplicates an event. + + Raises `Ecto.NoResultsError` for invalid `user_id`-`event_uuid` combinations + and returns an error tuple if any part of the transaction fails. ## Examples @@ -527,159 +555,201 @@ defmodule Claper.Events do iex> duplicate(user_id, event_uuid) {:error, %Ecto.Changeset{}} + iex> duplicate(another_user_id, event_uuid) + ** (Ecto.NoResultsError) + """ def duplicate_event(user_id, event_uuid) do - case Ecto.Multi.new() - |> Ecto.Multi.run(:original_event, fn _repo, _changes -> - {:ok, - get_user_event!(user_id, event_uuid, - presentation_file: [ - polls: [:poll_opts], - forms: [], - embeds: [], - quizzes: [:quiz_questions, quiz_questions: :quiz_question_opts], - presentation_state: [] - ] - )} - end) - |> Ecto.Multi.run(:new_event, fn _repo, %{original_event: original_event} -> - new_code = - for _ <- 1..5, - into: "", - do: <> + original = + get_user_event!(user_id, event_uuid, + presentation_file: [ + presentation_state: [], + polls: [:poll_opts], + forms: [], + embeds: [], + quizzes: [quiz_questions: [:quiz_question_opts]] + ] + ) - attrs = - Map.from_struct(original_event) - |> Map.drop([:id, :inserted_at, :updated_at, :presentation_file, :expired_at]) - |> Map.put(:leaders, []) - |> Map.put(:code, "#{new_code}") - |> Map.put(:name, "#{original_event.name} (Copy)") + multi = + Ecto.Multi.new() + |> Ecto.Multi.run(:event, fn _repo, changes -> duplicate_event_attrs(original, changes) end) + |> Ecto.Multi.run(:presentation_file, fn _repo, changes -> + duplicate_presentation_file(original, changes) + end) + |> Ecto.Multi.run(:presentation_state, fn _repo, changes -> + duplicate_presentation_state(original, changes) + end) + |> Ecto.Multi.run(:polls, fn _repo, changes -> duplicate_polls(original, changes) end) + |> Ecto.Multi.run(:forms, fn _repo, changes -> duplicate_forms(original, changes) end) + |> Ecto.Multi.run(:embeds, fn _repo, changes -> duplicate_embeds(original, changes) end) + |> Ecto.Multi.run(:quizzes, fn _repo, changes -> duplicate_quizzes(original, changes) end) - create_event(attrs) - end) - |> Ecto.Multi.run(:new_presentation_file, fn _repo, - %{ - original_event: original_event, - new_event: new_event - } -> - attrs = - Map.from_struct(original_event.presentation_file) - |> Map.drop([:id, :inserted_at, :updated_at, :presentation_state]) - |> Map.put(:event_id, new_event.id) - - Claper.Presentations.create_presentation_file(attrs) - end) - |> Ecto.Multi.run(:new_presentation_state, fn _repo, - %{ - original_event: original_event, - new_presentation_file: - new_presentation_file - } -> - attrs = - Map.from_struct(original_event.presentation_file.presentation_state) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:presentation_file_id, new_presentation_file.id) - |> Map.put(:position, 0) - |> Map.put(:banned, []) - - Claper.Presentations.create_presentation_state(attrs) - end) - |> Ecto.Multi.run(:polls, fn _repo, - %{ - new_presentation_file: new_presentation_file, - original_event: original_event - } -> - {:ok, - Enum.map(original_event.presentation_file.polls, fn poll -> - poll_attrs = - Map.from_struct(poll) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:presentation_file_id, new_presentation_file.id) - |> Map.put( - :poll_opts, - Enum.map(poll.poll_opts, fn opt -> - Map.from_struct(opt) - |> Map.drop([:id, :inserted_at, :updated_at]) - end) - ) - - {:ok, new_poll} = Claper.Polls.create_poll(poll_attrs) - new_poll - end)} - end) - |> Ecto.Multi.run(:forms, fn _repo, - %{ - new_presentation_file: new_presentation_file, - original_event: original_event - } -> - {:ok, - Enum.map(original_event.presentation_file.forms, fn form -> - form_attrs = - Map.from_struct(form) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:presentation_file_id, new_presentation_file.id) - |> Map.put( - :fields, - Enum.map(form.fields, &Map.from_struct(&1)) - ) - - {:ok, new_form} = Claper.Forms.create_form(form_attrs) - new_form - end)} - end) - |> Ecto.Multi.run(:embeds, fn _repo, - %{ - new_presentation_file: new_presentation_file, - original_event: original_event - } -> - {:ok, - Enum.map(original_event.presentation_file.embeds, fn embed -> - embed_attrs = - Map.from_struct(embed) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:presentation_file_id, new_presentation_file.id) - - {:ok, new_embed} = Claper.Embeds.create_embed(embed_attrs) - new_embed - end)} - end) - |> Ecto.Multi.run(:quizzes, fn _repo, - %{ - new_presentation_file: new_presentation_file, - original_event: original_event - } -> - {:ok, - Enum.map(original_event.presentation_file.quizzes, fn quiz -> - quiz_attrs = - Map.from_struct(quiz) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:presentation_file_id, new_presentation_file.id) - |> Map.put( - :quiz_questions, - Enum.map(quiz.quiz_questions, fn question -> - Map.from_struct(question) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put( - :quiz_question_opts, - Enum.map(question.quiz_question_opts, fn opt -> - Map.from_struct(opt) - |> Map.drop([:id, :inserted_at, :updated_at]) - |> Map.put(:response_count, 0) - end) - ) - end) - ) - - {:ok, new_quiz} = Claper.Quizzes.create_quiz(quiz_attrs) - new_quiz - end)} - end) - |> Repo.transaction() do - {:ok, %{new_event: new_event}} -> {:ok, new_event} - {:error, _failed_operation, failed_value, _changes_so_far} -> {:error, failed_value} + case Repo.transaction(multi) do + {:ok, %{event: event}} -> {:ok, event} + {:error, _operation, value, _changes} -> {:error, value} end end + defp duplicate_event_attrs(original, _changes) do + code = + for _ <- 1..5, + into: "", + do: <> + + attrs = + Map.from_struct(original) + |> Map.drop([:id, :inserted_at, :updated_at, :presentation_file, :expired_at]) + |> Map.put(:leaders, []) + |> Map.put(:code, "#{code}") + |> Map.put(:name, "#{original.name} (Copy)") + + create_event(attrs) + end + + defp duplicate_presentation_file(original, changes) do + case get_in(original.presentation_file) do + %Presentations.PresentationFile{} = presentation_file -> + attrs = + Map.from_struct(presentation_file) + |> Map.drop([:id, :inserted_at, :updated_at, :presentation_state]) + |> Map.put(:event_id, changes.event.id) + + Presentations.create_presentation_file(attrs) + + _ -> + {:ok, nil} + end + end + + defp duplicate_presentation_state(original, changes) do + case get_in(original.presentation_file.presentation_state) do + %Presentations.PresentationState{} = presentation_state -> + attrs = + Map.from_struct(presentation_state) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:presentation_file_id, changes.presentation_file.id) + |> Map.put(:position, 0) + |> Map.put(:banned, []) + + Presentations.create_presentation_state(attrs) + + _ -> + {:ok, nil} + end + end + + defp duplicate_polls(original, changes) do + case get_in(original.presentation_file.polls) do + polls when is_list(polls) -> + polls = + for poll <- polls do + attrs = + Map.from_struct(poll) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:presentation_file_id, changes.presentation_file.id) + |> Map.put( + :poll_opts, + Enum.map(poll.poll_opts, fn opt -> + Map.from_struct(opt) + |> Map.drop([:id, :inserted_at, :updated_at, :vote_count]) + end) + ) + + {:ok, poll} = Claper.Polls.create_poll(attrs) + poll + end + + {:ok, polls} + + _ -> + {:ok, nil} + end + end + + defp duplicate_forms(original, changes) do + case get_in(original.presentation_file.forms) do + forms when is_list(forms) -> + forms = + for form <- forms do + attrs = + Map.from_struct(form) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:presentation_file_id, changes.presentation_file.id) + |> Map.put( + :fields, + Enum.map(form.fields, &Map.from_struct(&1)) + ) + + {:ok, form} = Claper.Forms.create_form(attrs) + form + end + + {:ok, forms} + + _ -> + {:ok, nil} + end + end + + defp duplicate_embeds(original, changes) do + case get_in(original.presentation_file.embeds) do + embeds when is_list(embeds) -> + embeds = + for embed <- embeds do + attrs = + Map.from_struct(embed) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:presentation_file_id, changes.presentation_file.id) + + {:ok, embed} = Claper.Embeds.create_embed(attrs) + embed + end + + {:ok, embeds} + + _ -> + {:ok, nil} + end + end + + defp duplicate_quizzes(original, changes) do + case get_in(original.presentation_file.quizzes) do + quizzes when is_list(quizzes) -> + quizzes = + for quiz <- quizzes do + attrs = + Map.from_struct(quiz) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:presentation_file_id, changes.presentation_file.id) + |> Map.put(:quiz_questions, Enum.map(quiz.quiz_questions, &map_quiz_question/1)) + + {:ok, quiz} = Claper.Quizzes.create_quiz(attrs) + quiz + end + + {:ok, quizzes} + + _ -> + {:ok, nil} + end + end + + defp map_quiz_question(question) do + Map.from_struct(question) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put( + :quiz_question_opts, + Enum.map(question.quiz_question_opts, &map_quiz_question_opt/1) + ) + end + + defp map_quiz_question_opt(opt) do + Map.from_struct(opt) + |> Map.drop([:id, :inserted_at, :updated_at]) + |> Map.put(:response_count, 0) + end + @doc """ Deletes a event. @@ -693,7 +763,20 @@ defmodule Claper.Events do """ def delete_event(%Event{} = event) do - Repo.delete(event) + leaders = + for %{email: email} <- get_activity_leaders_for_event(event.id) do + Accounts.get_user_by_email(email) + end + + with {:ok, event} <- Repo.delete(event) do + broadcast_user_events(event.user_id, {:deleted, event}) + + for leader <- leaders do + broadcast_user_events(leader.id, {:deleted, event}) + end + + {:ok, event} + end end @doc """ @@ -709,8 +792,6 @@ defmodule Claper.Events do Event.changeset(event, attrs) end - alias Claper.Events.ActivityLeader - @doc """ Creates a activity leader. @@ -756,7 +837,7 @@ defmodule Claper.Events do """ def get_activity_leaders_for_event(event_id) do from(a in ActivityLeader, - left_join: u in Claper.Accounts.User, + left_join: u in Accounts.User, on: u.email == a.email, where: a.event_id == ^event_id, select: %{a | user_id: u.id} @@ -777,13 +858,47 @@ defmodule Claper.Events do ActivityLeader.changeset(activity_leader, attrs) end - defp broadcast({:ok, e, event_uuid}, event) do - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{event_uuid}", - {event, event_uuid} - ) + @doc """ + Subscribes to an event's public `Phoenix.PubSub` topic. - {:ok, e} + The broadcasted messages match the pattern: + + * {:terminated, event_uuid} + + """ + def subscribe_event(event_uuid) when is_binary(event_uuid) do + Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_uuid}") + end + + defp broadcast_event(event_uuid, message) when is_binary(event_uuid) do + Phoenix.PubSub.broadcast(Claper.PubSub, "event:#{event_uuid}", message) + end + + @doc """ + Subscribes to a user's events private `Phoenix.PubSub` topic. + + The broadcasted messages match the pattern: + + * {:created, %Event{}} + * {:updated, %Event{}} + * {:deleted, %Event{}} + + """ + def subscribe_user_events(user_id) when is_integer(user_id) do + Phoenix.PubSub.subscribe(Claper.PubSub, "user:#{user_id}:events") + end + + def broadcast_user_events(user_id, message) when is_integer(user_id) do + Phoenix.PubSub.broadcast(Claper.PubSub, "user:#{user_id}:events", message) + end + + defp broadcast_all_users({_type, %Event{} = event} = message, _opts \\ []) do + event = Repo.preload(event, [:leaders]) + broadcast_user_events(event.user_id, message) + + for %{email: leader_email} <- event.leaders do + leader = Accounts.get_user_by_email(leader_email) + broadcast_user_events(leader.id, message) + end end end diff --git a/lib/claper/events/event.ex b/lib/claper/events/event.ex index d557346..d1f3091 100644 --- a/lib/claper/events/event.ex +++ b/lib/claper/events/event.ex @@ -45,11 +45,12 @@ defmodule Claper.Events.Event do :code, :started_at, :expired_at, - :audience_peak + :audience_peak, + :user_id ]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code, :name]) + |> validate_required([:name, :code, :started_at]) end def create_changeset(event, attrs) do @@ -57,7 +58,7 @@ defmodule Claper.Events.Event do |> cast(attrs, [:name, :code, :user_id, :started_at, :expired_at]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code, :started_at]) + |> validate_required([:name, :code, :started_at, :user_id]) |> validate_length(:code, min: 5, max: 10) |> validate_length(:name, min: 5, max: 50) |> downcase_code @@ -74,10 +75,10 @@ defmodule Claper.Events.Event do def update_changeset(event, attrs) do event - |> cast(attrs, [:name, :code, :started_at, :expired_at, :audience_peak]) + |> cast(attrs, [:name, :code, :started_at, :expired_at, :audience_peak, :user_id]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code, :started_at]) + |> validate_required([:name, :code, :started_at, :user_id]) |> validate_length(:code, min: 5, max: 10) |> validate_length(:name, min: 5, max: 50) |> downcase_code @@ -90,8 +91,8 @@ defmodule Claper.Events.Event do change(event, expired_at: expiry) end - def subscribe(event_id) do - Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_id}") + def subscribe(event_uuid) do + Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_uuid}") end def started?(event) do diff --git a/lib/claper/forms/field.ex b/lib/claper/forms/field.ex index d0b3214..0269e40 100644 --- a/lib/claper/forms/field.ex +++ b/lib/claper/forms/field.ex @@ -4,19 +4,21 @@ defmodule Claper.Forms.Field do @type t :: %__MODULE__{ name: String.t(), - type: String.t() + type: String.t(), + required: boolean() } @primary_key false embedded_schema do field :name, :string field :type, :string + field :required, :boolean, default: true end @doc false def changeset(form, attrs \\ %{}) do form - |> cast(attrs, [:name, :type]) + |> cast(attrs, [:name, :type, :required]) |> validate_required([:name, :type]) end end diff --git a/lib/claper/forms/form_submit.ex b/lib/claper/forms/form_submit.ex index a867fa5..f0c490f 100644 --- a/lib/claper/forms/form_submit.ex +++ b/lib/claper/forms/form_submit.ex @@ -25,6 +25,6 @@ defmodule Claper.Forms.FormSubmit do def changeset(form_submit, attrs) do form_submit |> cast(attrs, [:attendee_identifier, :user_id, :form_id, :response]) - |> validate_required([:form_id]) + |> validate_required([:form_id, :user_id, :response]) end end diff --git a/lib/claper/polls/poll.ex b/lib/claper/polls/poll.ex index f340b53..145cdc5 100644 --- a/lib/claper/polls/poll.ex +++ b/lib/claper/polls/poll.ex @@ -27,7 +27,11 @@ defmodule Claper.Polls.Poll do field :show_results, :boolean belongs_to :presentation_file, Claper.Presentations.PresentationFile - has_many :poll_opts, Claper.Polls.PollOpt, on_replace: :delete + + has_many :poll_opts, Claper.Polls.PollOpt, + preload_order: [asc: :id], + on_replace: :delete + has_many :poll_votes, Claper.Polls.PollVote, on_replace: :delete timestamps() diff --git a/lib/claper/presentations.ex b/lib/claper/presentations.ex index 680661e..31e92dc 100644 --- a/lib/claper/presentations.ex +++ b/lib/claper/presentations.ex @@ -31,6 +31,65 @@ defmodule Claper.Presentations do def get_presentation_files_by_hash(hash) when is_nil(hash), do: [] + @doc """ + Returns a list of JPG slide URLs for a given presentation. + + When a `Claper.Presentations.PresentationFile{}` struct is provided, the + function builds the list of URLs programmatically from the `hash` and + `length` fields. + + When an integer or binary `hash` is provided, it queries the database for the + associated presentation file and builds the list of URLs programmatically + from that. + + When `nil` is provided or when no presentation file is found for the given + `hash`, it returns an empty list. + """ + def get_slide_urls(hash_or_presentation_file) + + def get_slide_urls(nil), do: [] + + def get_slide_urls(hash) when is_integer(hash), do: get_slide_urls(to_string(hash)) + + def get_slide_urls(hash) when is_binary(hash) do + case Repo.get_by(PresentationFile, hash: hash) do + nil -> + [] + + presentation -> + get_slide_urls(hash, presentation.length) + end + end + + def get_slide_urls(%PresentationFile{} = presentation) do + get_slide_urls(presentation.hash, presentation.length) + end + + @doc """ + Returns a list of JPG slide URLs for a given presentation `hash` and + `length`. See also `get_slide_urls/1`. + """ + def get_slide_urls(hash, length) when is_binary(hash) and is_integer(length) do + config = Application.get_env(:claper, :presentations) + + case Keyword.fetch!(config, :storage) do + "local" -> + for index <- 1..length do + "/uploads/#{hash}/#{index}.jpg" + end + + "s3" -> + base_url = Keyword.fetch!(config, :s3_public_url) + + for index <- 1..length do + base_url <> "/presentations/#{hash}/#{index}.jpg" + end + + storage -> + raise "Unrecognised presentations storage value #{storage}" + end + end + @doc """ Creates a presentation_files. diff --git a/lib/claper/presentations/presentation_state.ex b/lib/claper/presentations/presentation_state.ex index 24ff236..e92b8d2 100644 --- a/lib/claper/presentations/presentation_state.ex +++ b/lib/claper/presentations/presentation_state.ex @@ -13,6 +13,7 @@ defmodule Claper.Presentations.PresentationState do message_reaction_enabled: boolean() | nil, banned: [String.t()] | nil, show_only_pinned: boolean() | nil, + show_attendee_count: boolean() | nil, presentation_file_id: integer() | nil, inserted_at: NaiveDateTime.t(), updated_at: NaiveDateTime.t() @@ -28,6 +29,7 @@ defmodule Claper.Presentations.PresentationState do field :message_reaction_enabled, :boolean, default: true field :banned, {:array, :string}, default: [] field :show_only_pinned, :boolean, default: false + field :show_attendee_count, :boolean, default: true belongs_to :presentation_file, Claper.Presentations.PresentationFile @@ -47,6 +49,7 @@ defmodule Claper.Presentations.PresentationState do :chat_enabled, :anonymous_chat_enabled, :show_only_pinned, + :show_attendee_count, :message_reaction_enabled ]) |> validate_required([]) diff --git a/lib/claper/quizzes.ex b/lib/claper/quizzes.ex index d1595bf..8b2c0b0 100644 --- a/lib/claper/quizzes.ex +++ b/lib/claper/quizzes.ex @@ -2,6 +2,8 @@ defmodule Claper.Quizzes do import Ecto.Query, warn: false alias Claper.Repo + alias Claper.Accounts.User + alias Claper.Quizzes.Quiz alias Claper.Quizzes.QuizQuestion alias Claper.Quizzes.QuizQuestionOpt @@ -265,28 +267,62 @@ defmodule Claper.Quizzes do {:ok, quiz} """ - def submit_quiz(user_id, quiz_opts, quiz_id) - when is_number(user_id) and is_list(quiz_opts) do - case Enum.reduce(quiz_opts, Ecto.Multi.new(), fn opt, multi -> - Ecto.Multi.update( - multi, - {:update_quiz_opt, opt.id}, + + # Pattern match on user, from user we create QuizResponse struct + # def submit_quiz(user_id, quiz_opts, quiz_id) + # when is_number(user_id) and is_list(quiz_opts) do + # quiz_opts = Enum.with_index(quiz_opts) + + # case Enum.reduce(quiz_opts, Ecto.Multi.new(), fn {opt, index}, multi -> + # unique_key = "#{opt.id}_#{user_id + index}" + + # multi + # |> Ecto.Multi.update( + # "update_quiz_opt_#{unique_key}", + # QuizQuestionOpt.changeset(opt, %{"response_count" => opt.response_count + 1}) + # ) + # |> Ecto.Multi.insert( + # "insert_quiz_response_#{unique_key}", + # QuizResponse.changeset(%QuizResponse{}, %{ + # user_id: user_id, + # quiz_question_opt_id: opt.id, + # quiz_question_id: opt.quiz_question_id, + # quiz_id: quiz_id + # }) + # ) + # end) + # |> Repo.transact() do + # {:ok, _} -> + # quiz = get_quiz!(quiz_id, [:quiz_questions, quiz_questions: :quiz_question_opts]) + # Lti13.QuizScoreReporter.report_quiz_score(quiz, user_id) + # {:ok, quiz} + # end + # end + + def submit_quiz(%User{} = user, quiz_opts, quiz_id) do + quiz_opts = Enum.with_index(quiz_opts) + + case Enum.reduce(quiz_opts, Ecto.Multi.new(), fn {opt, index}, multi -> + unique_key = "#{opt.id}_#{user.id + index}" + + multi + |> Ecto.Multi.update( + "update_quiz_opt_#{unique_key}", QuizQuestionOpt.changeset(opt, %{"response_count" => opt.response_count + 1}) ) |> Ecto.Multi.insert( - {:insert_quiz_response, opt.id}, - QuizResponse.changeset(%QuizResponse{}, %{ - user_id: user_id, + "insert_quiz_response_#{unique_key}", + Ecto.build_assoc(user, :quiz_responses, %{ quiz_question_opt_id: opt.id, quiz_question_id: opt.quiz_question_id, quiz_id: quiz_id }) ) end) - |> Repo.transaction() do + |> Repo.transact() do {:ok, _} -> quiz = get_quiz!(quiz_id, [:quiz_questions, quiz_questions: :quiz_question_opts]) - Lti13.QuizScoreReporter.report_quiz_score(quiz, user_id) + Lti13.QuizScoreReporter.report_quiz_score(quiz, user.id) {:ok, quiz} end end @@ -294,8 +330,8 @@ defmodule Claper.Quizzes do def submit_quiz(attendee_identifier, quiz_opts, quiz_id) when is_binary(attendee_identifier) and is_list(quiz_opts) do case Enum.reduce(quiz_opts, Ecto.Multi.new(), fn opt, multi -> - Ecto.Multi.update( - multi, + multi + |> Ecto.Multi.update( {:update_quiz_opt, opt.id}, QuizQuestionOpt.changeset(opt, %{"response_count" => opt.response_count + 1}) ) @@ -309,7 +345,7 @@ defmodule Claper.Quizzes do }) ) end) - |> Repo.transaction() do + |> Repo.transact() do {:ok, _} -> quiz = get_quiz!(quiz_id, [:quiz_questions, quiz_questions: :quiz_question_opts]) {:ok, quiz} diff --git a/lib/claper/quizzes/quiz.ex b/lib/claper/quizzes/quiz.ex index 2e46ccb..a0dca68 100644 --- a/lib/claper/quizzes/quiz.ex +++ b/lib/claper/quizzes/quiz.ex @@ -2,6 +2,22 @@ defmodule Claper.Quizzes.Quiz do use Ecto.Schema import Ecto.Changeset + @type t :: %__MODULE__{ + id: integer(), + title: String.t(), + position: integer() | nil, + enabled: boolean(), + show_results: boolean(), + allow_anonymous: boolean(), + lti_line_item_url: String.t() | nil, + lti_resource: Lti13.Resources.Resource.t() | nil, + quiz_responses: [Claper.Quizzes.QuizResponse.t()] | nil, + quiz_questions: [Claper.Quizzes.QuizQuestion.t()] | nil, + presentation_file: Claper.Presentations.PresentationFile.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + schema "quizzes" do field :title, :string field :position, :integer, default: 0 diff --git a/lib/claper/quizzes/quiz_question.ex b/lib/claper/quizzes/quiz_question.ex index 7ffdd8d..dac101e 100644 --- a/lib/claper/quizzes/quiz_question.ex +++ b/lib/claper/quizzes/quiz_question.ex @@ -2,7 +2,17 @@ defmodule Claper.Quizzes.QuizQuestion do use Ecto.Schema import Ecto.Changeset - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext + + @type t :: %__MODULE__{ + id: integer(), + content: String.t(), + type: String.t(), + quiz: Claper.Quizzes.Quiz.t() | nil, + quiz_question_opts: [Claper.Quizzes.QuizQuestionOpt.t()] | nil, + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } schema "quiz_questions" do field :content, :string diff --git a/lib/claper/quizzes/quiz_question_opt.ex b/lib/claper/quizzes/quiz_question_opt.ex index 263fcf4..f36c477 100644 --- a/lib/claper/quizzes/quiz_question_opt.ex +++ b/lib/claper/quizzes/quiz_question_opt.ex @@ -2,6 +2,17 @@ defmodule Claper.Quizzes.QuizQuestionOpt do use Ecto.Schema import Ecto.Changeset + @type t :: %__MODULE__{ + id: integer(), + content: String.t(), + is_correct: boolean(), + response_count: integer(), + percentage: float() | nil, + quiz_question: Claper.Quizzes.QuizQuestion.t() | nil, + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + schema "quiz_question_opts" do field :content, :string field :is_correct, :boolean, default: false diff --git a/lib/claper/quizzes/quiz_response.ex b/lib/claper/quizzes/quiz_response.ex index a1233dc..e8ad88f 100644 --- a/lib/claper/quizzes/quiz_response.ex +++ b/lib/claper/quizzes/quiz_response.ex @@ -2,6 +2,17 @@ defmodule Claper.Quizzes.QuizResponse do use Ecto.Schema import Ecto.Changeset + @type t :: %__MODULE__{ + id: integer(), + attendee_identifier: String.t() | nil, + quiz: Claper.Quizzes.Quiz.t() | nil, + quiz_question: Claper.Quizzes.QuizQuestion.t() | nil, + quiz_question_opt: Claper.Quizzes.QuizQuestionOpt.t() | nil, + user: Claper.Accounts.User.t() | nil, + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + schema "quiz_responses" do field :attendee_identifier, :string @@ -20,8 +31,7 @@ defmodule Claper.Quizzes.QuizResponse do :attendee_identifier, :quiz_id, :quiz_question_id, - :quiz_question_opt_id, - :user_id + :quiz_question_opt_id ]) |> validate_required([:quiz_id, :quiz_question_id, :quiz_question_opt_id]) end diff --git a/lib/claper/release.ex b/lib/claper/release.ex index 4401231..d230ce6 100644 --- a/lib/claper/release.ex +++ b/lib/claper/release.ex @@ -21,7 +21,8 @@ defmodule Claper.Release do for repo <- repos() do {:ok, _, _} = Ecto.Migrator.with_repo(repo, fn _repo -> - Code.eval_file("priv/repo/seeds.exs") + seed_script = Application.app_dir(@app, "priv/repo/seeds.exs") + Code.eval_file(seed_script) end) end end diff --git a/lib/claper/tasks/converter.ex b/lib/claper/tasks/converter.ex index a271cd5..ff8baf7 100644 --- a/lib/claper/tasks/converter.ex +++ b/lib/claper/tasks/converter.ex @@ -4,7 +4,7 @@ defmodule Claper.Tasks.Converter do We use a hash to identify the presentation. A new hash is generated when the conversion is finished and the presentation is being uploaded. """ - alias ExAws.S3 + alias Claper.Events alias Porcelain.Result @doc """ @@ -19,11 +19,7 @@ defmodule Claper.Tasks.Converter do "status" => "progress" }) - Phoenix.PubSub.broadcast( - Claper.PubSub, - "events:#{user_id}", - {:presentation_file_process_done, presentation} - ) + Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation}) path = Path.join([ @@ -53,11 +49,11 @@ defmodule Claper.Tasks.Converter do ) else stream = - ExAws.S3.list_objects(get_aws_bucket(), prefix: "presentations/#{hash}") + ExAws.S3.list_objects(get_s3_bucket(), prefix: "presentations/#{hash}") |> ExAws.stream!() |> Stream.map(& &1.key) - ExAws.S3.delete_all_objects(get_aws_bucket(), stream) |> ExAws.request() + ExAws.S3.delete_all_objects(get_s3_bucket(), stream) |> ExAws.request() end end @@ -137,9 +133,9 @@ defmodule Claper.Tasks.Converter do IO.puts("Uploads #{f} to presentations/#{new_hash}/#{Path.basename(f)}") f - |> S3.Upload.stream_file() - |> S3.upload( - get_aws_bucket(), + |> ExAws.S3.Upload.stream_file() + |> ExAws.S3.upload( + get_s3_bucket(), "presentations/#{new_hash}/#{Path.basename(f)}", acl: "public-read" ) @@ -167,11 +163,7 @@ defmodule Claper.Tasks.Converter do }) do if get_presentation_storage() != "local", do: File.rm_rf!(path) - Phoenix.PubSub.broadcast( - Claper.PubSub, - "events:#{user_id}", - {:presentation_file_process_done, presentation} - ) + Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation}) end end @@ -182,11 +174,7 @@ defmodule Claper.Tasks.Converter do }) do File.rm_rf!(path) - Phoenix.PubSub.broadcast( - Claper.PubSub, - "events:#{user_id}", - {:presentation_file_process_done, presentation} - ) + Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation}) end end @@ -198,8 +186,8 @@ defmodule Claper.Tasks.Converter do Application.get_env(:claper, :storage_dir) end - defp get_aws_bucket do - Application.get_env(:claper, :presentations) |> Keyword.get(:aws_bucket) + defp get_s3_bucket do + Application.get_env(:claper, :presentations) |> Keyword.get(:s3_bucket) end defp get_resolution do diff --git a/lib/claper/workers/mailers.ex b/lib/claper/workers/mailers.ex index d330b17..081eeab 100644 --- a/lib/claper/workers/mailers.ex +++ b/lib/claper/workers/mailers.ex @@ -6,19 +6,25 @@ defmodule Claper.Workers.Mailers do @impl Oban.Worker def perform(%Oban.Job{args: %{"type" => type, "user_id" => user_id, "url" => url}}) - when type in ["confirm", "reset", "update_email"] do + when type in ["confirm", "reset"] do user = Claper.Accounts.get_user!(user_id) email = case type do "confirm" -> UserNotifier.confirm(user, url) "reset" -> UserNotifier.reset(user, url) - "update_email" -> UserNotifier.update_email(user, url) end Mailer.deliver(email) end + def perform(%Oban.Job{ + args: %{"type" => "update_email", "new_email" => new_email, "url" => url} + }) do + email = UserNotifier.update_email(new_email, url) + Mailer.deliver(email) + end + def perform(%Oban.Job{args: %{"type" => "magic", "email" => email, "url" => url}}) do email = UserNotifier.magic(email, url) Mailer.deliver(email) @@ -50,8 +56,8 @@ defmodule Claper.Workers.Mailers do new(%{type: "reset", user_id: user_id, url: url}) end - def new_update_email(user_id, url) do - new(%{type: "update_email", user_id: user_id, url: url}) + def new_update_email(new_email, url) do + new(%{type: "update_email", new_email: new_email, url: url}) end def new_magic_link(email, url) do diff --git a/lib/claper_web.ex b/lib/claper_web.ex index 5ebb91b..bc77c14 100644 --- a/lib/claper_web.ex +++ b/lib/claper_web.ex @@ -24,7 +24,7 @@ defmodule ClaperWeb do use Phoenix.Controller, namespace: ClaperWeb import Plug.Conn - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext unquote(verified_routes()) end @@ -87,7 +87,7 @@ defmodule ClaperWeb do quote do use Phoenix.Channel import Phoenix.View - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext end end @@ -99,7 +99,7 @@ defmodule ClaperWeb do use PhoenixHTMLHelpers # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) - import Phoenix.LiveView.Helpers + import Phoenix.Component import ClaperWeb.LiveHelpers alias Phoenix.LiveView.JS @@ -107,7 +107,7 @@ defmodule ClaperWeb do import Phoenix.View import ClaperWeb.ErrorHelpers - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext unquote(verified_routes()) end diff --git a/lib/claper_web/controllers/stat_controller.ex b/lib/claper_web/controllers/stat_controller.ex index 95e0be1..8b4f4bf 100644 --- a/lib/claper_web/controllers/stat_controller.ex +++ b/lib/claper_web/controllers/stat_controller.ex @@ -197,7 +197,7 @@ defmodule ClaperWeb.StatController do # Private functions defp authorize_event_access(user, event) do - if Events.leaded_by?(user.email, event) || event.user_id == user.id do + if Events.led_by?(user.email, event) || event.user_id == user.id do :ok else :unauthorized diff --git a/lib/claper_web/controllers/user_oidc_auth.ex b/lib/claper_web/controllers/user_oidc_auth.ex index e55975e..6cb495d 100644 --- a/lib/claper_web/controllers/user_oidc_auth.ex +++ b/lib/claper_web/controllers/user_oidc_auth.ex @@ -103,7 +103,7 @@ defmodule ClaperWeb.UserOidcAuth do Application.get_env(:claper, ClaperWeb.Endpoint)[:base_url] end - defp opts(pkce_verifier \\ nil) do + defp opts(pkce_verifier) do url = base_url() base_opts = %{ diff --git a/lib/claper_web/gettext.ex b/lib/claper_web/gettext.ex index 47262d4..93b8009 100644 --- a/lib/claper_web/gettext.ex +++ b/lib/claper_web/gettext.ex @@ -5,7 +5,7 @@ defmodule ClaperWeb.Gettext do By using [Gettext](https://hexdocs.pm/gettext), your module gains a set of macros for translations, for example: - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext # Simple translation gettext("Here is the string to translate") @@ -20,5 +20,5 @@ defmodule ClaperWeb.Gettext do See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage. """ - use Gettext, otp_app: :claper + use Gettext.Backend, otp_app: :claper end diff --git a/lib/claper_web/helpers/csv_exporter.ex b/lib/claper_web/helpers/csv_exporter.ex new file mode 100644 index 0000000..3a819ce --- /dev/null +++ b/lib/claper_web/helpers/csv_exporter.ex @@ -0,0 +1,169 @@ +defmodule ClaperWeb.Helpers.CSVExporter do + @moduledoc """ + Helper module for exporting data to CSV format. + + This module provides functions to convert collections of data + into CSV format for download in the admin panel. + """ + + @doc """ + Converts a list of records to CSV format. + + ## Parameters + - records: List of records/maps to convert + - headers: List of column headers + - fields: List of fields to include in the CSV + + ## Returns + - CSV formatted string + """ + def to_csv(records, headers, fields) do + records + |> build_rows(fields) + |> add_headers(headers) + |> CSV.encode() + |> Enum.to_list() + |> Enum.join("") + end + + @doc """ + Generates a timestamped filename for CSV exports. + + ## Parameters + - prefix: Prefix for the filename (e.g., "users", "events") + + ## Returns + - String filename with timestamp + """ + def generate_filename(prefix) do + date = DateTime.utc_now() |> Calendar.strftime("%Y%m%d_%H%M%S") + "#{prefix}_export_#{date}.csv" + end + + # Private helper functions + + defp build_rows(records, fields) do + Enum.map(records, fn record -> + Enum.map(fields, fn field -> + format_field_value(Map.get(record, field)) + end) + end) + end + + defp add_headers(rows, headers) do + [headers | rows] + end + + defp format_field_value(value) when is_boolean(value) do + if value, do: "Yes", else: "No" + end + + defp format_field_value(%DateTime{} = dt) do + Calendar.strftime(dt, "%Y-%m-%d %H:%M:%S") + end + + defp format_field_value(%NaiveDateTime{} = dt) do + Calendar.strftime(dt, "%Y-%m-%d %H:%M:%S") + end + + defp format_field_value(nil), do: "" + + defp format_field_value(value), do: to_string(value) + + @doc """ + Exports a list of users to CSV format. + + ## Parameters + - users: List of User structs to export + + ## Returns + - CSV formatted string + """ + def export_users_to_csv(users) do + headers = ["Email", "Name", "Role", "Created At"] + + # Transform users to include role name + users_with_role = + Enum.map(users, fn user -> + role_name = if user.role, do: user.role.name, else: "" + + %{ + email: user.email, + # Users don't have a name field currently + name: "", + role: role_name, + inserted_at: user.inserted_at + } + end) + + fields = [:email, :name, :role, :inserted_at] + + to_csv(users_with_role, headers, fields) + end + + @doc """ + Exports a list of events to CSV format. + + ## Parameters + - events: List of Event structs to export + + ## Returns + - CSV formatted string + """ + def export_events_to_csv(events) do + headers = [ + "Name", + "Description", + "Start Date", + "End Date", + "Status" + ] + + # Transform events to include description and status + events_transformed = + Enum.map(events, fn event -> + status = + cond do + event.expired_at && + NaiveDateTime.compare(event.expired_at, NaiveDateTime.utc_now()) == :lt -> + "completed" + + event.started_at && + NaiveDateTime.compare(event.started_at, NaiveDateTime.utc_now()) == :gt -> + "scheduled" + + true -> + "active" + end + + %{ + name: event.name, + # Events don't have a description field currently + description: "", + start_date: event.started_at, + end_date: event.expired_at, + status: status + } + end) + + fields = [:name, :description, :start_date, :end_date, :status] + + to_csv(events_transformed, headers, fields) + end + + @doc """ + Exports a list of OIDC providers to CSV format. + + ## Parameters + - providers: List of Provider structs to export + + ## Returns + - CSV formatted string + """ + def export_oidc_providers_to_csv(providers) do + headers = ["Name", "Issuer", "Client ID", "Active"] + fields = [:name, :issuer, :client_id, :active] + + to_csv(providers, headers, fields) + end +end diff --git a/lib/claper_web/live/admin_live/dashboard_live.ex b/lib/claper_web/live/admin_live/dashboard_live.ex new file mode 100644 index 0000000..af6e07d --- /dev/null +++ b/lib/claper_web/live/admin_live/dashboard_live.ex @@ -0,0 +1,109 @@ +defmodule ClaperWeb.AdminLive.DashboardLive do + use ClaperWeb, :live_view + + import Ecto.Query, warn: false + alias Claper.Admin + alias Claper.Events.Event + alias Claper.Repo + + @impl true + def mount(_params, session, socket) do + if connected?(socket) do + # Set up periodic updates every 30 seconds + :timer.send_interval(30_000, self(), :update_charts) + end + + with %{"locale" => locale} <- session do + Gettext.put_locale(ClaperWeb.Gettext, locale) + end + + socket = + socket + |> assign(:page_title, gettext("Dashboard")) + |> assign(:selected_period, :day) + |> assign(:days_back, 30) + |> load_dashboard_data() + + {:ok, socket} + end + + @impl true + def handle_params(_params, _url, socket) do + {:noreply, socket} + end + + @impl true + def handle_event("change_period", %{"period" => period}, socket) do + period_atom = String.to_atom(period) + + days_back = + case period_atom do + :day -> 30 + # 12 weeks + :week -> 84 + # 12 months + :month -> 365 + _ -> 30 + end + + socket = + socket + |> assign(:selected_period, period_atom) + |> assign(:days_back, days_back) + |> load_chart_data() + + {:noreply, socket} + end + + @impl true + def handle_event("refresh_data", _params, socket) do + socket = load_dashboard_data(socket) + {:noreply, socket} + end + + @impl true + def handle_info(:update_charts, socket) do + socket = load_chart_data(socket) + {:noreply, socket} + end + + defp load_dashboard_data(socket) do + stats = Admin.get_dashboard_stats() + growth_metrics = Admin.get_growth_metrics() + activity_stats = Admin.get_activity_stats() + + # Get recent events for the dashboard + recent_events = + Event + |> order_by([e], desc: e.started_at) + |> limit(5) + |> preload(:user) + |> Repo.all() + + # Transform stats to match template expectations + transformed_stats = %{ + total_users: stats.users_count, + total_events: stats.events_count, + active_events: stats.upcoming_events + } + + socket + |> assign(:stats, transformed_stats) + |> assign(:growth_metrics, growth_metrics) + |> assign(:activity_stats, activity_stats) + |> assign(:recent_events, recent_events) + |> load_chart_data() + end + + defp load_chart_data(socket) do + period = socket.assigns.selected_period + days_back = socket.assigns.days_back + + users_chart_data = Admin.get_users_over_time(period, days_back) + events_chart_data = Admin.get_events_over_time(period, days_back) + + socket + |> assign(:users_chart_data, users_chart_data) + |> assign(:events_chart_data, events_chart_data) + end +end diff --git a/lib/claper_web/live/admin_live/dashboard_live.html.heex b/lib/claper_web/live/admin_live/dashboard_live.html.heex new file mode 100644 index 0000000..ad22e66 --- /dev/null +++ b/lib/claper_web/live/admin_live/dashboard_live.html.heex @@ -0,0 +1,212 @@ + +
+

{gettext("Dashboard")}

+
+ + +
+ +
+
+
{gettext("Total Users")}
+
{@stats.total_users}
+
+ 0 do + "text-success" + else + "text-error" + end + }> + <%= if @growth_metrics.users_growth >= 0 do %> + ↗︎ + <% else %> + ↘︎ + <% end %> + {@growth_metrics.users_growth}% + + {gettext("vs last month")} +
+
+ +
+
{gettext("Total Events")}
+
{@stats.total_events}
+
+ 0 do + "text-success" + else + "text-error" + end + }> + <%= if @growth_metrics.events_growth >= 0 do %> + ↗︎ + + <% else %> + ↘︎ + <% end %> + {@growth_metrics.events_growth}% + + {gettext("vs last month")} +
+
+ +
+
{gettext("Active Events")}
+
{@stats.active_events}
+
{gettext("Currently running")}
+
+
+ + +
+
+
+

{gettext("User Growth")}

+

{gettext("Last 30 days")}

+
+ + +
+
+
+ +
+
+

{gettext("Event Creation")}

+

{gettext("Last 30 days")}

+
+ + +
+
+
+
+ + +
+
+
+

{gettext("Recent Events")}

+ +
+ + + + + + + + + + + + + + <%= for event <- @recent_events do %> + <% now = NaiveDateTime.utc_now() %> + <% {status_text, status_class} = + cond do + is_nil(event.expired_at) == false -> + {gettext("Completed"), "badge-ghost"} + + NaiveDateTime.compare(event.started_at, now) == :gt -> + {gettext("Scheduled"), "badge-info"} + + true -> + {gettext("Active"), "badge-success"} + end %> + + + + + + + + + + <% end %> + <%= if Enum.empty?(@recent_events) do %> + + + + <% end %> + +
{gettext("Name")}{gettext("Code")}{gettext("Owner")}{gettext("Start Date")}{gettext("Audience Peak")}{gettext("Status")}
+
{event.name}
+
+ {event.code} + {event.user.email}{Calendar.strftime(event.started_at, "%b %d, %Y")} +
{event.audience_peak}
+
+
+ {status_text} +
+
+
+ <.link + navigate={~p"/admin/events/#{event}"} + class="btn btn-link btn-xs" + title={gettext("View event")} + > + + + + + + <.link + navigate={~p"/admin/events/#{event}/edit"} + class="btn btn-link btn-xs text-primary" + title={gettext("Edit event")} + > + + + + +
+
+
+ {gettext("No events found")} +
+
+
+
+
+
+
diff --git a/lib/claper_web/live/admin_live/event_live.ex b/lib/claper_web/live/admin_live/event_live.ex new file mode 100644 index 0000000..cc65890 --- /dev/null +++ b/lib/claper_web/live/admin_live/event_live.ex @@ -0,0 +1,175 @@ +defmodule ClaperWeb.AdminLive.EventLive do + use ClaperWeb, :live_view + + alias Claper.Admin + alias Claper.Events.Event + alias ClaperWeb.Helpers.CSVExporter + + @impl true + def mount(_params, session, socket) do + with %{"locale" => locale} <- session do + Gettext.put_locale(ClaperWeb.Gettext, locale) + end + + {:ok, + socket + |> assign(:page_title, gettext("Events")) + |> assign(:events, list_events()) + |> assign(:search, "") + |> assign(:current_sort, %{field: :na, order: :asc})} + end + + @impl true + def handle_params(params, _url, socket) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} + end + + defp apply_action(socket, :index, _params) do + socket + |> assign(:page_title, "Events") + |> assign(:event, nil) + end + + defp apply_action(socket, :new, _params) do + socket + |> assign(:page_title, gettext("New event")) + |> assign(:event, %Event{}) + end + + defp apply_action(socket, :edit, %{"id" => id}) do + socket + |> assign(:page_title, gettext("Edit event")) + |> assign(:event, Claper.Events.get_event!(id, [:user])) + end + + defp apply_action(socket, :show, %{"id" => id}) do + socket + |> assign(:page_title, gettext("Event details")) + |> assign(:event, Claper.Events.get_event!(id, [:user])) + end + + @impl true + def handle_event("delete", %{"id" => id}, socket) do + event = Claper.Events.get_event!(id) + {:ok, _} = Claper.Events.delete_event(event) + + {:noreply, + socket + |> put_flash(:info, gettext("Event deleted successfully")) + |> assign(:events, list_events())} + end + + @impl true + def handle_event("search", %{"search" => search}, socket) do + events = search_events(search) + {:noreply, socket |> assign(:search, search) |> assign(:events, events)} + end + + @impl true + def handle_event("sort", %{"field" => field}, socket) do + field = String.to_existing_atom(field) + current_sort = socket.assigns.current_sort + + direction = + if current_sort.field == field && current_sort.order == :asc, do: :desc, else: :asc + + events = sort_events(socket.assigns.events, field, direction) + current_sort = %{field: field, order: direction} + + {:noreply, + socket + |> assign(:events, events) + |> assign(:current_sort, current_sort)} + end + + @impl true + def handle_info({:export_csv_requested, _params}, socket) do + filename = CSVExporter.generate_filename("events") + csv_content = CSVExporter.export_events_to_csv(socket.assigns.events) + + {:noreply, + socket + |> put_flash(:info, gettext("Events exported successfully")) + |> push_event("download_csv", %{filename: filename, content: csv_content})} + end + + @impl true + def handle_info({:table_action, action, event, _event_id}, socket) do + case action do + :view -> + {:noreply, push_navigate(socket, to: ~p"/admin/events/#{event}")} + + :edit -> + {:noreply, push_navigate(socket, to: ~p"/admin/events/#{event}/edit")} + + :delete -> + {:ok, _} = Claper.Events.delete_event(event) + + {:noreply, + socket + |> put_flash(:info, gettext("Event deleted successfully")) + |> assign(:events, list_events())} + end + end + + defp list_events do + Admin.list_all_events() + end + + defp search_events(search) when search == "", do: list_events() + + defp search_events(search) do + Admin.list_all_events(%{"search" => search}) + end + + defp sort_events(events, field, order) do + Enum.sort_by(events, &Map.get(&1, field), order) + end + + def sort_indicator(assigns) do + ~H""" + <%= if @current_sort.field == @field do %> + <%= if @current_sort.order == :asc do %> + + + + <% else %> + + + + <% end %> + <% else %> + + + + <% end %> + """ + end +end diff --git a/lib/claper_web/live/admin_live/event_live.html.heex b/lib/claper_web/live/admin_live/event_live.html.heex new file mode 100644 index 0000000..079752f --- /dev/null +++ b/lib/claper_web/live/admin_live/event_live.html.heex @@ -0,0 +1,367 @@ +<%= case @live_action do %> + <% :index -> %> +
+
+
+

{gettext("Events")}

+
+ <%!-- <.link navigate={~p"/admin/events/new"} class="btn btn-primary btn-sm"> + + + + {gettext("New event")} + --%> +
+
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ + + + + + + + + + + + + + <%= if Enum.empty?(@events) do %> + + + + <% else %> + <%= for event <- @events do %> + + + + + + + + + + <% end %> + <% end %> + +
+ + + + + {gettext("Owner")} + + + + + + + + {gettext("Actions")} +
+ {gettext("No events found")} +
+ {event.name} + + {event.code} + + {if event.user, do: event.user.email, else: gettext("No owner")} + + {if event.started_at, + do: Calendar.strftime(event.started_at, "%Y-%m-%d %H:%M"), + else: gettext("Not started")} + + {if event.expired_at, + do: Calendar.strftime(event.expired_at, "%Y-%m-%d %H:%M"), + else: gettext("Not expired")} + +
+ {event.audience_peak || 0} +
+
+
+ <.link + navigate={~p"/admin/events/#{event}"} + class="btn btn-link btn-sm" + title={gettext("View event")} + > + + + + + + <.link + navigate={~p"/admin/events/#{event}/edit"} + class="btn btn-link btn-sm text-primary" + title={gettext("Edit event")} + > + + + + + + + + + +
+
+
+
+
+
+
+
+ <% :show -> %> +
+
+
+

{gettext("Event details")}

+
+ <.link navigate={~p"/admin/events"} class="btn btn-outline btn-sm"> + {gettext("Back to events")} + + <.link navigate={~p"/admin/events/#{@event}/edit"} class="btn btn-primary btn-sm"> + {gettext("Edit")} + +
+
+
+ +
+
+
+

{@event.name}

+

#{@event.code}

+
+
+
+
{gettext("Name")}
+
{@event.name}
+
+
+
{gettext("Owner")}
+
+ {if @event.user, do: @event.user.email, else: gettext("No owner")} +
+
+
+
{gettext("Started At")}
+
+ {if @event.started_at, + do: Calendar.strftime(@event.started_at, "%Y-%m-%d %H:%M"), + else: gettext("Not started")} +
+
+
+
{gettext("Expired At")}
+
+ {if @event.expired_at, + do: Calendar.strftime(@event.expired_at, "%Y-%m-%d %H:%M"), + else: gettext("Not expired")} +
+
+
+
{gettext("Audience Peak")}
+
+ {@event.audience_peak || 0} {gettext("attendees")} +
+
+
+
{gettext("Created At")}
+
+ {Calendar.strftime(@event.inserted_at, "%Y-%m-%d %H:%M")} +
+
+
+
{gettext("Last Updated")}
+
+ {Calendar.strftime(@event.updated_at, "%Y-%m-%d %H:%M")} +
+
+
+
+
+
+
+ <% :new -> %> +
+
+
+

{gettext("New event")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.EventLive.FormComponent} + id="event-form" + title={gettext("New event")} + action={:new} + event={@event} + navigate={~p"/admin/events"} + /> +
+
+
+
+ <% :edit -> %> +
+
+
+

{gettext("Edit event")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.EventLive.FormComponent} + id={"event-form-#{@event.id}"} + title={gettext("Edit event")} + action={:edit} + event={@event} + navigate={~p"/admin/events"} + /> +
+
+
+
+<% end %> diff --git a/lib/claper_web/live/admin_live/event_live/form_component.ex b/lib/claper_web/live/admin_live/event_live/form_component.ex new file mode 100644 index 0000000..bcbf1eb --- /dev/null +++ b/lib/claper_web/live/admin_live/event_live/form_component.ex @@ -0,0 +1,160 @@ +defmodule ClaperWeb.AdminLive.EventLive.FormComponent do + use ClaperWeb, :live_component + + alias Claper.Events + alias Claper.Accounts + + @impl true + def render(assigns) do + ~H""" +
+ <.form for={@form} id="event-form" phx-target={@myself} phx-change="validate" phx-submit="save"> +
+ <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="event-name" + form={@form} + field={:name} + type="text" + label={gettext("Name")} + placeholder={gettext("Enter event name")} + required={true} + width_class="sm:col-span-6" + description={gettext("A unique name for this event")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="event-code" + form={@form} + field={:code} + type="text" + label={gettext("Code")} + placeholder={gettext("Enter event code")} + required={true} + width_class="sm:col-span-3" + field_class="uppercase" + description={gettext("A unique code for participants to join this event")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="event-started-at" + form={@form} + field={:started_at} + type="datetime" + label={gettext("Started At")} + required={true} + width_class="sm:col-span-3" + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="event-expired-at" + form={@form} + field={:expired_at} + type="datetime" + label={gettext("Expired At")} + required={false} + width_class="sm:col-span-3" + description={gettext("When this event expires (optional)")} + /> + + <.live_component + module={ClaperWeb.AdminLive.SearchableSelectComponent} + id="event-user-id" + form={@form} + field={:user_id} + label={gettext("Assigned User")} + options={@user_options} + placeholder={gettext("Search for a user...")} + required={true} + width_class="sm:col-span-6" + description={gettext("The user who owns this event (required)")} + /> +
+ +
+
+ + +
+
+ +
+ """ + end + + @impl true + def update(%{event: event} = assigns, socket) do + changeset = Events.change_event(event) + + user_options = + Accounts.list_users() + |> Enum.map(&{"#{&1.email}", &1.id}) + + {:ok, + socket + |> assign(assigns) + |> assign(:user_options, user_options) + |> assign_form(changeset)} + end + + @impl true + def handle_event("validate", %{"event" => event_params}, socket) do + changeset = + socket.assigns.event + |> Events.change_event(event_params) + |> Map.put(:action, :validate) + + {:noreply, assign_form(socket, changeset)} + end + + def handle_event("save", %{"event" => event_params}, socket) do + save_event(socket, socket.assigns.action, event_params) + end + + def handle_event("cancel", _params, socket) do + {:noreply, push_navigate(socket, to: socket.assigns.navigate)} + end + + defp save_event(socket, :edit, event_params) do + case Events.update_event(socket.assigns.event, event_params) do + {:ok, event} -> + notify_parent({:saved, event}) + + {:noreply, + socket + |> put_flash(:info, gettext("Event updated successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp save_event(socket, :new, event_params) do + case Events.create_event(event_params) do + {:ok, event} -> + notify_parent({:saved, event}) + + {:noreply, + socket + |> put_flash(:info, gettext("Event created successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp assign_form(socket, %Ecto.Changeset{} = changeset) do + assign(socket, :form, to_form(changeset)) + end + + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) +end diff --git a/lib/claper_web/live/admin_live/form_field_component.ex b/lib/claper_web/live/admin_live/form_field_component.ex new file mode 100644 index 0000000..9f1c44b --- /dev/null +++ b/lib/claper_web/live/admin_live/form_field_component.ex @@ -0,0 +1,184 @@ +defmodule ClaperWeb.AdminLive.FormFieldComponent do + use ClaperWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+
+ + <%= case @type do %> + <% "text" -> %> + {text_input( + @form, + @field, + [ + class: "input w-full " <> @field_class, + placeholder: @placeholder, + required: @required + ] ++ @extra_attrs + )} + <% "email" -> %> + {email_input( + @form, + @field, + [ + class: "input w-full", + placeholder: @placeholder, + required: @required + ] ++ @extra_attrs + )} + <% "password" -> %> +
+ {password_input( + @form, + @field, + [ + class: "input w-full pr-10", + placeholder: @placeholder, + required: @required, + id: "password-field-#{@field}" + ] ++ @extra_attrs + )} + +
+ <% "textarea" -> %> + {textarea( + @form, + @field, + [ + class: "input w-full", + placeholder: @placeholder, + required: @required, + rows: @rows + ] ++ @extra_attrs + )} + <% "select" -> %> + {select( + @form, + @field, + @select_options, + [ + class: "select w-full", + prompt: @prompt || gettext("Select an option"), + required: @required + ] ++ @extra_attrs + )} + <% "checkbox" -> %> +
+ +
+ <% "date" -> %> + {date_input( + @form, + @field, + [ + class: "input input-bordered w-full", + required: @required + ] ++ @extra_attrs + )} + <% "datetime" -> %> + {datetime_local_input( + @form, + @field, + [ + class: "input input-bordered w-full", + required: @required + ] ++ @extra_attrs + )} + <% "file" -> %> +
+ + + {if @selected_file, do: @selected_file, else: gettext("No file chosen")} + +
+ <% _ -> %> + {text_input( + @form, + @field, + [ + class: "input input-bordered w-full", + placeholder: @placeholder, + required: @required + ] ++ @extra_attrs + )} + <% end %> + + +
+
+ """ + end + + @impl true + def mount(socket) do + {:ok, assign(socket, selected_file: nil)} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:placeholder, fn -> "" end) + |> assign_new(:required, fn -> false end) + |> assign_new(:description, fn -> nil end) + |> assign_new(:width_class, fn -> nil end) + |> assign_new(:field_class, fn -> "" end) + |> assign_new(:checkbox_label, fn -> nil end) + |> assign_new(:prompt, fn -> nil end) + |> assign_new(:select_options, fn -> [] end) + |> assign_new(:rows, fn -> 3 end) + |> assign_new(:extra_attrs, fn -> [] end) + + {:ok, socket} + end + + @impl true + def handle_event("file_selected", %{"_target" => [_field_name]}, socket) do + {:noreply, assign(socket, selected_file: gettext("File selected"))} + end + + defp toggle_password_visibility(field_id) do + %Phoenix.LiveView.JS{} + |> Phoenix.LiveView.JS.dispatch("toggle-password", to: "##{field_id}") + end +end diff --git a/lib/claper_web/live/admin_live/modal_component.ex b/lib/claper_web/live/admin_live/modal_component.ex new file mode 100644 index 0000000..2fc3003 --- /dev/null +++ b/lib/claper_web/live/admin_live/modal_component.ex @@ -0,0 +1,196 @@ +defmodule ClaperWeb.AdminLive.ModalComponent do + use ClaperWeb, :live_component + alias Phoenix.LiveView.JS + + @impl true + def render(assigns) do + ~H""" + + """ + end + + @impl true + def mount(socket) do + {:ok, assign(socket, show: false)} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:show, fn -> false end) + |> assign_new(:icon, fn -> nil end) + |> assign_new(:icon_bg_class, fn -> "bg-red-100" end) + |> assign_new(:icon_text_class, fn -> "text-red-600" end) + |> assign_new(:description, fn -> nil end) + |> assign_new(:content, fn -> [] end) + |> assign_new(:confirm_action, fn -> nil end) + |> assign_new(:confirm_class, fn -> "bg-red-600 hover:bg-red-700 focus:ring-red-500" end) + |> assign_new(:cancel_action, fn -> "Cancel" end) + |> assign_new(:custom_actions, fn -> [] end) + |> assign_new(:size_class, fn -> "sm:max-w-lg sm:w-full" end) + + {:ok, socket} + end + + @impl true + def handle_event("hide", _params, socket) do + send(self(), {:modal_cancelled, socket.assigns.id}) + {:noreply, assign(socket, show: false)} + end + + def handle_event("confirm", _params, socket) do + send(self(), {:modal_confirmed, socket.assigns.id}) + {:noreply, assign(socket, show: false)} + end + + # Public API for controlling the modal + def show_modal(js \\ %JS{}, modal_id) do + js + |> JS.show(to: "##{modal_id}") + |> JS.add_class("animate-fade-in", to: "##{modal_id}") + end + + def hide_modal(js \\ %JS{}, modal_id) do + js + |> JS.add_class("animate-fade-out", to: "##{modal_id}") + |> JS.hide(to: "##{modal_id}", transition: "animate-fade-out", time: 200) + end + + # Preset configurations for common modal types + def delete_modal_config(title, description) do + %{ + icon: "fa-exclamation-triangle", + icon_bg_class: "bg-red-100", + icon_text_class: "text-red-600", + title: title, + description: description, + confirm_action: "Delete", + confirm_class: "bg-red-600 hover:bg-red-700 focus:ring-red-500", + cancel_action: "Cancel" + } + end + + def warning_modal_config(title, description) do + %{ + icon: "fa-exclamation-triangle", + icon_bg_class: "bg-yellow-100", + icon_text_class: "text-yellow-600", + title: title, + description: description, + confirm_action: "Continue", + confirm_class: "bg-yellow-600 hover:bg-yellow-700 focus:ring-yellow-500", + cancel_action: "Cancel" + } + end + + def info_modal_config(title, description) do + %{ + icon: "fa-info-circle", + icon_bg_class: "bg-blue-100", + icon_text_class: "text-blue-600", + title: title, + description: description, + confirm_action: "OK", + confirm_class: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500", + cancel_action: nil + } + end +end diff --git a/lib/claper_web/live/admin_live/oidc_provider_live.ex b/lib/claper_web/live/admin_live/oidc_provider_live.ex new file mode 100644 index 0000000..71d9b8d --- /dev/null +++ b/lib/claper_web/live/admin_live/oidc_provider_live.ex @@ -0,0 +1,155 @@ +defmodule ClaperWeb.AdminLive.OidcProviderLive do + use ClaperWeb, :live_view + + alias Claper.Accounts.Oidc + alias Claper.Accounts.Oidc.Provider + + @impl true + def mount(_params, session, socket) do + with %{"locale" => locale} <- session do + Gettext.put_locale(ClaperWeb.Gettext, locale) + end + + {:ok, + socket + |> assign(:page_title, gettext("OIDC Providers")) + |> assign(:providers, list_providers()) + |> assign(:search, "") + |> assign(:current_sort, %{field: :na, order: :asc})} + end + + @impl true + def handle_params(params, _url, socket) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} + end + + defp apply_action(socket, :index, _params) do + socket + |> assign(:page_title, "OIDC Providers") + |> assign(:provider, nil) + end + + defp apply_action(socket, :show, %{"id" => id}) do + socket + |> assign(:page_title, gettext("Provider details")) + |> assign(:provider, Oidc.get_provider!(id)) + end + + defp apply_action(socket, :new, _params) do + socket + |> assign(:page_title, gettext("New provider")) + |> assign(:provider, %Provider{}) + end + + defp apply_action(socket, :edit, %{"id" => id}) do + socket + |> assign(:page_title, gettext("Edit provider")) + |> assign(:provider, Oidc.get_provider!(id)) + end + + @impl true + def handle_event("delete", %{"id" => id}, socket) do + provider = Oidc.get_provider!(id) + {:ok, _} = Oidc.delete_provider(provider) + + {:noreply, + socket + |> put_flash(:info, gettext("Provider deleted successfully")) + |> assign(:providers, list_providers())} + end + + @impl true + def handle_event("search", %{"search" => search}, socket) do + providers = search_providers(search) + {:noreply, socket |> assign(:search, search) |> assign(:providers, providers)} + end + + @impl true + def handle_event("sort", %{"field" => field}, socket) do + %{current_sort: %{field: current_field, order: current_order}} = socket.assigns + + {field, order} = + if current_field == String.to_existing_atom(field) do + {current_field, if(current_order == :asc, do: :desc, else: :asc)} + else + {String.to_existing_atom(field), :asc} + end + + providers = sort_providers(socket.assigns.providers, field, order) + + {:noreply, + socket + |> assign(:providers, providers) + |> assign(:current_sort, %{field: field, order: order})} + end + + @impl true + def handle_info( + {ClaperWeb.AdminLive.OidcProviderLive.FormComponent, {:saved, _provider}}, + socket + ) do + {:noreply, assign(socket, :providers, list_providers())} + end + + defp list_providers do + Oidc.list_providers() + end + + defp search_providers(search) when search == "", do: list_providers() + + defp search_providers(search) do + search_term = "%#{search}%" + Oidc.search_providers(search_term) + end + + defp sort_providers(providers, field, order) do + Enum.sort_by(providers, &Map.get(&1, field), order) + end + + def sort_indicator(assigns) do + ~H""" + <%= if @current_sort.field == @field do %> + <%= if @current_sort.order == :asc do %> + + + + <% else %> + + + + <% end %> + <% else %> + + + + <% end %> + """ + end +end diff --git a/lib/claper_web/live/admin_live/oidc_provider_live.html.heex b/lib/claper_web/live/admin_live/oidc_provider_live.html.heex new file mode 100644 index 0000000..6369326 --- /dev/null +++ b/lib/claper_web/live/admin_live/oidc_provider_live.html.heex @@ -0,0 +1,358 @@ +<%= case @live_action do %> + <% :index -> %> +
+
+
+

{gettext("OIDC Providers")}

+
+ <.link navigate={~p"/admin/oidc_providers/new"} class="btn btn-primary btn-sm"> + + + + {gettext("New provider")} + +
+
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ + + + + + + + + + + + <%= if Enum.empty?(@providers) do %> + + + + <% else %> + <%= for provider <- @providers do %> + + + + + + + + <% end %> + <% end %> + +
+ + + + + + + + + {gettext("Actions")} +
+ {gettext("No providers found")} +
+ {provider.name} + + {provider.issuer} + + <%= if provider.active do %> + + {gettext("Active")} + + <% else %> + + {gettext("Inactive")} + + <% end %> + + {Calendar.strftime(provider.inserted_at, "%Y-%m-%d %H:%M")} + +
+ <.link + navigate={~p"/admin/oidc_providers/#{provider}"} + class="btn btn-link btn-sm" + title={gettext("View provider")} + > + + + + + + <.link + navigate={~p"/admin/oidc_providers/#{provider}/edit"} + class="btn btn-link btn-sm text-primary" + title={gettext("Edit provider")} + > + + + + + + + + + +
+
+
+
+
+
+
+
+ <% :show -> %> +
+
+
+

{gettext("OIDC Provider details")}

+
+ <.link navigate={~p"/admin/oidc_providers"} class="btn btn-outline btn-sm"> + {gettext("Back to providers")} + + <.link + navigate={~p"/admin/oidc_providers/#{@provider}/edit"} + class="btn btn-primary btn-sm" + > + {gettext("Edit")} + +
+
+
+ +
+
+
+

{@provider.name}

+

{gettext("OIDC Provider")}

+
+
+
+
{gettext("Name")}
+
{@provider.name}
+
+
+
{gettext("Issuer")}
+
+ {@provider.issuer} +
+
+
+
{gettext("Client ID")}
+
+ {@provider.client_id} +
+
+
+
{gettext("Response Type")}
+
+ {@provider.response_type} +
+
+
+
{gettext("Scope")}
+
+ {@provider.scope} +
+
+
+
{gettext("Status")}
+
+ <%= if @provider.active do %> + + {gettext("Active")} + + <% else %> + + {gettext("Inactive")} + + <% end %> +
+
+
+
{gettext("Created At")}
+
+ {Calendar.strftime(@provider.inserted_at, "%Y-%m-%d %H:%M")} +
+
+
+
{gettext("Last Updated")}
+
+ {Calendar.strftime(@provider.updated_at, "%Y-%m-%d %H:%M")} +
+
+
+
+
+
+
+ <% :new -> %> +
+
+
+

{gettext("New provider")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.OidcProviderLive.FormComponent} + id="provider-form" + title={gettext("New provider")} + action={:new} + provider={@provider} + navigate={~p"/admin/oidc_providers"} + /> +
+
+
+
+ <% :edit -> %> +
+
+
+

{gettext("Edit OIDC Provider")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.OidcProviderLive.FormComponent} + id={"provider-form-#{@provider.id}"} + title={gettext("Edit provider")} + action={:edit} + provider={@provider} + navigate={~p"/admin/oidc_providers"} + /> +
+
+
+
+<% end %> diff --git a/lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex b/lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex new file mode 100644 index 0000000..f9b6f63 --- /dev/null +++ b/lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex @@ -0,0 +1,222 @@ +defmodule ClaperWeb.AdminLive.OidcProviderLive.FormComponent do + use ClaperWeb, :live_component + + alias Claper.Accounts.Oidc + + @impl true + def render(assigns) do + ~H""" +
+ <.form + for={@form} + id="provider-form" + phx-target={@myself} + phx-change="validate" + phx-submit="save" + > +
+ <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="name-field" + form={@form} + field={:name} + type="text" + label={gettext("Name")} + placeholder={gettext("Enter provider name")} + required={true} + width_class="sm:col-span-6" + description={gettext("A unique name to identify this OIDC provider")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="issuer-field" + form={@form} + field={:issuer} + type="text" + label={gettext("Issuer URL")} + placeholder={gettext("https://example.com")} + required={true} + width_class="sm:col-span-6" + description={gettext("The OIDC issuer URL (must start with http:// or https://)")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="client_id-field" + form={@form} + field={:client_id} + type="text" + label={gettext("Client ID")} + placeholder={gettext("Enter client ID")} + required={true} + width_class="sm:col-span-3" + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="client_secret-field" + form={@form} + field={:client_secret} + type="text" + label={gettext("Client Secret")} + placeholder={gettext("Enter client secret")} + required={true} + width_class="sm:col-span-3" + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="redirect_uri-field" + form={@form} + field={:redirect_uri} + type="text" + label={gettext("Redirect URI")} + placeholder={gettext("https://yourapp.com/auth/callback")} + required={true} + width_class="sm:col-span-6" + description={ + gettext("The callback URL for your application (must start with http:// or https://)") + } + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="scope-field" + form={@form} + field={:scope} + type="text" + label={gettext("Scope")} + placeholder={gettext("openid email profile")} + width_class="sm:col-span-3" + description={gettext("OIDC scopes to request (defaults to 'openid email profile')")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="response_type-field" + form={@form} + field={:response_type} + type="select" + label={gettext("Response Type")} + select_options={[ + {gettext("Authorization Code"), "code"}, + {gettext("Implicit"), "token"}, + {gettext("Hybrid"), "code token"} + ]} + width_class="sm:col-span-3" + description={gettext("OAuth 2.0 response type (defaults to 'code')")} + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="response_mode-field" + form={@form} + field={:response_mode} + type="select" + label={gettext("Response Mode")} + select_options={[ + {gettext("Query"), "query"}, + {gettext("Fragment"), "fragment"}, + {gettext("Form Post"), "form_post"} + ]} + width_class="sm:col-span-3" + description={ + gettext("How the authorization response should be returned (defaults to 'query')") + } + /> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="active-field" + form={@form} + field={:active} + type="checkbox" + label={gettext("Active")} + checkbox_label={gettext("Enable this OIDC provider")} + width_class="sm:col-span-3" + description={ + gettext("Whether this provider is currently active and available for authentication") + } + /> +
+ +
+
+ + +
+
+ +
+ """ + end + + @impl true + def update(%{provider: provider} = assigns, socket) do + changeset = Oidc.change_provider(provider) + + {:ok, + socket + |> assign(assigns) + |> assign_form(changeset)} + end + + @impl true + def handle_event("validate", %{"provider" => provider_params}, socket) do + changeset = + socket.assigns.provider + |> Oidc.change_provider(provider_params) + |> Map.put(:action, :validate) + + {:noreply, assign_form(socket, changeset)} + end + + def handle_event("save", %{"provider" => provider_params}, socket) do + save_provider(socket, socket.assigns.action, provider_params) + end + + def handle_event("cancel", _params, socket) do + {:noreply, push_navigate(socket, to: socket.assigns.navigate)} + end + + defp save_provider(socket, :edit, provider_params) do + case Oidc.update_provider(socket.assigns.provider, provider_params) do + {:ok, provider} -> + notify_parent({:saved, provider}) + + {:noreply, + socket + |> put_flash(:info, gettext("Provider updated successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp save_provider(socket, :new, provider_params) do + case Oidc.create_provider(provider_params) do + {:ok, provider} -> + notify_parent({:saved, provider}) + + {:noreply, + socket + |> put_flash(:info, gettext("Provider created successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp assign_form(socket, %Ecto.Changeset{} = changeset) do + assign(socket, :form, to_form(changeset)) + end + + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) +end diff --git a/lib/claper_web/live/admin_live/search_filter_component.ex b/lib/claper_web/live/admin_live/search_filter_component.ex new file mode 100644 index 0000000..9380f58 --- /dev/null +++ b/lib/claper_web/live/admin_live/search_filter_component.ex @@ -0,0 +1,175 @@ +defmodule ClaperWeb.AdminLive.SearchFilterComponent do + use ClaperWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+
+
+
+
+
+ +
+ +
+ + <%= if @filters && length(@filters) > 0 do %> +
+ <%= for filter <- @filters do %> + + <% end %> +
+ <% end %> + + + + <%= if @show_clear and (@search_value || has_active_filters?(@filter_values)) do %> + + <% end %> +
+
+ +
+ <%= if @export_csv_enabled do %> + + <% end %> + + <%= if @new_path do %> + <.link + navigate={@new_path} + class="ml-3 relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" + > + + {@new_label || "New"} + + <% end %> + + <%= if @custom_actions do %> + {render_slot(@custom_actions)} + <% end %> +
+
+
+ """ + end + + @impl true + def mount(socket) do + {:ok, assign(socket, search_value: "", filter_values: %{})} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:search_placeholder, fn -> "Search..." end) + |> assign_new(:filters, fn -> [] end) + |> assign_new(:filter_values, fn -> %{} end) + |> assign_new(:search_value, fn -> "" end) + |> assign_new(:show_clear, fn -> true end) + |> assign_new(:export_csv_enabled, fn -> false end) + |> assign_new(:new_path, fn -> nil end) + |> assign_new(:new_label, fn -> "New" end) + |> assign_new(:custom_actions, fn -> [] end) + + {:ok, socket} + end + + @impl true + def handle_event("search", %{"search" => search_value}, socket) do + send( + self(), + {:search_filter_changed, %{search: search_value, filters: socket.assigns.filter_values}} + ) + + {:noreply, assign(socket, search_value: search_value)} + end + + def handle_event("search_change", %{"search" => search_value}, socket) do + send( + self(), + {:search_filter_changed, %{search: search_value, filters: socket.assigns.filter_values}} + ) + + {:noreply, assign(socket, search_value: search_value)} + end + + def handle_event("filter_change", %{"filter" => filter_name, "value" => filter_value}, socket) do + filter_values = Map.put(socket.assigns.filter_values, filter_name, filter_value) + + send( + self(), + {:search_filter_changed, %{search: socket.assigns.search_value, filters: filter_values}} + ) + + {:noreply, assign(socket, filter_values: filter_values)} + end + + def handle_event("clear_all", _params, socket) do + send(self(), {:search_filter_changed, %{search: "", filters: %{}}}) + {:noreply, assign(socket, search_value: "", filter_values: %{})} + end + + def handle_event("export_csv", _params, socket) do + send( + self(), + {:export_csv_requested, + %{search: socket.assigns.search_value, filters: socket.assigns.filter_values}} + ) + + {:noreply, socket} + end + + defp has_active_filters?(filter_values) do + Enum.any?(filter_values, fn {_key, value} -> value != nil and value != "" end) + end +end diff --git a/lib/claper_web/live/admin_live/searchable_select_component.ex b/lib/claper_web/live/admin_live/searchable_select_component.ex new file mode 100644 index 0000000..7cfc2c2 --- /dev/null +++ b/lib/claper_web/live/admin_live/searchable_select_component.ex @@ -0,0 +1,170 @@ +defmodule ClaperWeb.AdminLive.SearchableSelectComponent do + use ClaperWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+
+ + + + + +
+
+ """ + end + + @impl true + def mount(socket) do + {:ok, + socket + |> assign(:show_dropdown, false) + |> assign(:search_term, "") + |> assign(:filtered_options, []) + |> assign(:selected_value, nil) + |> assign(:display_value, "")} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:placeholder, fn -> gettext("Select...") end) + |> assign_new(:required, fn -> false end) + |> assign_new(:description, fn -> nil end) + |> assign_new(:width_class, fn -> nil end) + |> assign_new(:options, fn -> [] end) + |> update_filtered_options() + |> update_display_value() + + {:ok, socket} + end + + @impl true + def handle_event("search", %{"value" => search_term}, socket) do + socket = + socket + |> assign(:search_term, search_term) + |> assign(:show_dropdown, true) + |> update_filtered_options() + + {:noreply, socket} + end + + def handle_event("select_option", %{"value" => value, "label" => label}, socket) do + socket = + socket + |> assign(:selected_value, value) + |> assign(:display_value, label) + |> assign(:show_dropdown, false) + |> assign(:search_term, label) + + {:noreply, socket} + end + + def handle_event("open_dropdown", _params, socket) do + socket = + socket + |> assign(:show_dropdown, true) + |> update_filtered_options() + + {:noreply, socket} + end + + def handle_event("close_dropdown", _params, socket) do + {:noreply, assign(socket, :show_dropdown, false)} + end + + defp update_filtered_options(socket) do + search_term = String.downcase(socket.assigns[:search_term] || "") + + filtered = + if search_term == "" do + socket.assigns.options + else + Enum.filter(socket.assigns.options, fn {label, _value} -> + String.contains?(String.downcase(label), search_term) + end) + end + + assign(socket, :filtered_options, filtered) + end + + defp update_display_value(socket) do + current_value = get_field_value(socket.assigns.form, socket.assigns.field) + display_value = find_display_value(current_value, socket.assigns.options) + + socket + |> assign(:selected_value, current_value) + |> assign(:display_value, display_value) + |> assign(:search_term, display_value) + end + + defp find_display_value(nil, _options), do: "" + + defp find_display_value(current_value, options) do + case Enum.find(options, fn {_label, value} -> + to_string(value) == to_string(current_value) + end) do + {label, _value} -> label + nil -> "" + end + end + + defp get_field_value(form, field) do + Map.get(form.data, field) || Map.get(form.params, to_string(field)) + end +end diff --git a/lib/claper_web/live/admin_live/table_actions_component.ex b/lib/claper_web/live/admin_live/table_actions_component.ex new file mode 100644 index 0000000..4ccd225 --- /dev/null +++ b/lib/claper_web/live/admin_live/table_actions_component.ex @@ -0,0 +1,242 @@ +defmodule ClaperWeb.AdminLive.TableActionsComponent do + use ClaperWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+ <%= if @view_enabled do %> + + <% end %> + + <%= if @edit_enabled do %> + + <% end %> + + <%= if @delete_enabled do %> + + <% end %> + + <%= if @duplicate_enabled do %> + + <% end %> + + <%= if @archive_enabled do %> + + <% end %> + + <%= if @toggle_enabled do %> + + <% end %> + + <%= if @dropdown_actions && length(@dropdown_actions) > 0 do %> +
+ + + <%= if @dropdown_open do %> +
+
+ <%= for action <- @dropdown_actions do %> + + <% end %> +
+
+ <% end %> +
+ <% end %> + + <%= if @custom_actions do %> + {render_slot(@custom_actions)} + <% end %> +
+ """ + end + + @impl true + def mount(socket) do + {:ok, assign(socket, dropdown_open: false)} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:view_enabled, fn -> false end) + |> assign_new(:edit_enabled, fn -> true end) + |> assign_new(:delete_enabled, fn -> true end) + |> assign_new(:duplicate_enabled, fn -> false end) + |> assign_new(:archive_enabled, fn -> false end) + |> assign_new(:toggle_enabled, fn -> false end) + |> assign_new(:item_archived, fn -> false end) + |> assign_new(:item_active, fn -> true end) + |> assign_new(:delete_confirm_message, fn -> nil end) + |> assign_new(:toggle_active_title, fn -> nil end) + |> assign_new(:toggle_inactive_title, fn -> nil end) + |> assign_new(:dropdown_actions, fn -> [] end) + |> assign_new(:custom_actions, fn -> [] end) + |> assign_new(:dropdown_open, fn -> false end) + + {:ok, socket} + end + + @impl true + def handle_event("view_item", _params, socket) do + send(self(), {:table_action, :view, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("edit_item", _params, socket) do + send(self(), {:table_action, :edit, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("delete_item", _params, socket) do + send(self(), {:table_action, :delete, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("duplicate_item", _params, socket) do + send(self(), {:table_action, :duplicate, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("archive_item", _params, socket) do + action = if socket.assigns.item_archived, do: :unarchive, else: :archive + send(self(), {:table_action, action, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("toggle_item", _params, socket) do + action = if socket.assigns.item_active, do: :deactivate, else: :activate + send(self(), {:table_action, action, socket.assigns.item, socket.assigns.item_id}) + {:noreply, socket} + end + + def handle_event("toggle_dropdown", _params, socket) do + {:noreply, assign(socket, dropdown_open: !socket.assigns.dropdown_open)} + end + + def handle_event("close_dropdown", _params, socket) do + {:noreply, assign(socket, dropdown_open: false)} + end + + def handle_event("dropdown_action", %{"action" => action_key}, socket) do + action = Enum.find(socket.assigns.dropdown_actions, &(&1.key == action_key)) + + if action do + send( + self(), + {:table_action, String.to_atom(action_key), socket.assigns.item, socket.assigns.item_id} + ) + end + + {:noreply, assign(socket, dropdown_open: false)} + end +end diff --git a/lib/claper_web/live/admin_live/table_component.ex b/lib/claper_web/live/admin_live/table_component.ex new file mode 100644 index 0000000..cc4e20b --- /dev/null +++ b/lib/claper_web/live/admin_live/table_component.ex @@ -0,0 +1,282 @@ +defmodule ClaperWeb.AdminLive.TableComponent do + use ClaperWeb, :live_component + + @impl true + def render(assigns) do + ~H""" +
+
+ + + + <%= for {header, _index} <- Enum.with_index(@headers) do %> + + <% end %> + + + + <%= if length(@rows) > 0 do %> + <%= for {row, row_index} <- Enum.with_index(@rows) do %> + + <%= for {cell_content, _cell_index} <- Enum.with_index(get_row_cells(row, @headers, @row_func)) do %> + + <% end %> + + <% end %> + <% else %> + + + + <% end %> + +
+
+ {if is_binary(header), do: header, else: header.label} + <%= if @sortable && header.sortable do %> + <%= case @sort_config do %> + <% %{field: field, direction: :asc} when field == header.field -> %> + + <% %{field: field, direction: :desc} when field == header.field -> %> + + <% _ -> %> + + <% end %> + <% end %> +
+
+ <%= case cell_content do %> + <% {:safe, content} -> %> + {raw(content)} + <% content when is_binary(content) -> %> + {content} + <% content -> %> + {to_string(content)} + <% end %> +
+
+ <%= if @empty_icon do %> + + <% end %> +

+ {@empty_title || "No items found"} +

+

+ {@empty_message || "There are no items to display."} +

+ <%= if @empty_action do %> +
+ {render_slot(@empty_action)} +
+ <% end %> +
+
+
+ + <%= if @pagination do %> +
+
+ <%= if @pagination.page_number > 1 do %> + + <% else %> + + Previous + + <% end %> + + <%= if @pagination.page_number < @pagination.total_pages do %> + + <% else %> + + Next + + <% end %> +
+ + +
+ <% end %> +
+ """ + end + + @impl true + def mount(socket) do + {:ok, assign(socket, sort_config: %{field: nil, direction: :asc})} + end + + @impl true + def update(assigns, socket) do + socket = + socket + |> assign(assigns) + |> assign_new(:sortable, fn -> false end) + |> assign_new(:sort_config, fn -> %{field: nil, direction: :asc} end) + |> assign_new(:row_click_enabled, fn -> false end) + |> assign_new(:empty_title, fn -> nil end) + |> assign_new(:empty_message, fn -> nil end) + |> assign_new(:empty_icon, fn -> nil end) + |> assign_new(:empty_action, fn -> [] end) + |> assign_new(:pagination, fn -> nil end) + |> assign_new(:row_func, fn -> nil end) + + {:ok, socket} + end + + @impl true + def handle_event("sort", %{"field" => field}, socket) do + current_sort = socket.assigns.sort_config + + new_direction = + if current_sort.field == field and current_sort.direction == :asc do + :desc + else + :asc + end + + sort_config = %{field: field, direction: new_direction} + + send(self(), {:table_sort_changed, sort_config}) + {:noreply, assign(socket, sort_config: sort_config)} + end + + def handle_event("paginate", %{"page" => page}, socket) do + page_number = String.to_integer(page) + send(self(), {:table_page_changed, page_number}) + {:noreply, socket} + end + + def handle_event("row_clicked", %{"row-index" => row_index}, socket) do + index = String.to_integer(row_index) + row = Enum.at(socket.assigns.rows, index) + send(self(), {:table_row_clicked, row, index}) + {:noreply, socket} + end + + defp get_row_cells(row, headers, nil) do + # Default behavior: assume row is a list/tuple matching header count + case row do + row when is_list(row) -> row + row when is_tuple(row) -> Tuple.to_list(row) + _ -> List.duplicate("", length(headers)) + end + end + + defp get_row_cells(row, _headers, row_func) when is_function(row_func) do + row_func.(row) + end + + defp get_page_range(pagination) do + start_page = max(1, pagination.page_number - 2) + end_page = min(pagination.total_pages, pagination.page_number + 2) + start_page..end_page + end +end diff --git a/lib/claper_web/live/admin_live/user_live.ex b/lib/claper_web/live/admin_live/user_live.ex new file mode 100644 index 0000000..df6266c --- /dev/null +++ b/lib/claper_web/live/admin_live/user_live.ex @@ -0,0 +1,192 @@ +defmodule ClaperWeb.AdminLive.UserLive do + use ClaperWeb, :live_view + + alias Claper.Admin + alias Claper.Accounts + alias Claper.Accounts.User + alias ClaperWeb.Helpers.CSVExporter + + @impl true + def mount(_params, session, socket) do + with %{"locale" => locale} <- session do + Gettext.put_locale(ClaperWeb.Gettext, locale) + end + + {:ok, + socket + |> assign(:page_title, gettext("Users")) + |> assign(:users, list_users()) + |> assign(:search, "") + |> assign(:current_sort, %{field: :na, order: :asc})} + end + + @impl true + def handle_params(params, _url, socket) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} + end + + defp apply_action(socket, :index, _params) do + socket + |> assign(:page_title, "Users") + |> assign(:user, nil) + end + + defp apply_action(socket, :new, _params) do + socket + |> assign(:page_title, gettext("New user")) + |> assign(:user, %User{}) + end + + defp apply_action(socket, :edit, %{"id" => id}) do + socket + |> assign(:page_title, gettext("Edit user")) + |> assign(:user, Accounts.get_user!(id) |> Claper.Repo.preload(:role)) + end + + defp apply_action(socket, :show, %{"id" => id}) do + socket + |> assign(:page_title, gettext("User details")) + |> assign(:user, Accounts.get_user!(id) |> Claper.Repo.preload(:role)) + end + + @impl true + def handle_event("delete", %{"id" => id}, socket) do + user = Accounts.get_user!(id) + {:ok, _} = Accounts.delete_user(user) + + {:noreply, + socket + |> put_flash(:info, gettext("User deleted successfully")) + |> assign(:users, list_users())} + end + + @impl true + def handle_event("sort", %{"field" => field}, socket) do + field_atom = String.to_existing_atom(field) + current_sort = socket.assigns.current_sort + + new_direction = + if current_sort.field == field_atom do + if current_sort.order == :asc, do: :desc, else: :asc + else + :asc + end + + users = sort_users(socket.assigns.users, field_atom, new_direction) + current_sort = %{field: field_atom, order: new_direction} + + {:noreply, + socket + |> assign(:users, users) + |> assign(:current_sort, current_sort)} + end + + @impl true + def handle_info({:search_filter_changed, %{search: search, filters: _filters}}, socket) do + users = search_users(search) + {:noreply, socket |> assign(:search, search) |> assign(:users, users)} + end + + @impl true + def handle_info({:export_csv_requested, _params}, socket) do + filename = CSVExporter.generate_filename("users") + csv_content = CSVExporter.export_users_to_csv(socket.assigns.users) + + {:noreply, + socket + |> put_flash(:info, gettext("Users exported successfully")) + |> push_event("download_csv", %{filename: filename, content: csv_content})} + end + + @impl true + def handle_info({:table_sort_changed, sort_config}, socket) do + %{field: field, direction: direction} = sort_config + users = sort_users(socket.assigns.users, field, direction) + current_sort = %{field: field, order: direction} + + {:noreply, + socket + |> assign(:users, users) + |> assign(:current_sort, current_sort)} + end + + @impl true + def handle_info({:table_action, action, user, _user_id}, socket) do + case action do + :view -> + {:noreply, push_navigate(socket, to: ~p"/admin/users/#{user}")} + + :edit -> + {:noreply, push_navigate(socket, to: ~p"/admin/users/#{user}/edit")} + + :delete -> + {:ok, _} = Accounts.delete_user(user) + + {:noreply, + socket + |> put_flash(:info, gettext("User deleted successfully")) + |> assign(:users, list_users())} + end + end + + def list_users do + Admin.list_all_users() + end + + defp search_users(search) when search == "", do: list_users() + + defp search_users(search) do + Admin.list_all_users(%{"search" => search}) + end + + defp sort_users(users, field, order) do + Enum.sort_by(users, &Map.get(&1, field), order) + end + + def sort_indicator(assigns) do + ~H""" + <%= if @current_sort.field == @field do %> + <%= if @current_sort.order == :asc do %> + + + + <% else %> + + + + <% end %> + <% else %> + + + + <% end %> + """ + end +end diff --git a/lib/claper_web/live/admin_live/user_live.html.heex b/lib/claper_web/live/admin_live/user_live.html.heex new file mode 100644 index 0000000..283b05c --- /dev/null +++ b/lib/claper_web/live/admin_live/user_live.html.heex @@ -0,0 +1,348 @@ +<%= case @live_action do %> + <% :index -> %> +
+
+
+

{gettext("Users")}

+
+ <%!-- <.link navigate={~p"/admin/users/new"} class="btn btn-primary btn-sm"> + + + + {gettext("New user")} + --%> +
+
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ + + + + + + + + + + + <%= if Enum.empty?(@users) do %> + + + + <% else %> + <%= for user <- @users do %> + + + + + + + + <% end %> + <% end %> + +
+ + + + + + + + + {gettext("Actions")} +
+ {gettext("No users found")} +
+ {user.email} + + {if user.role, do: user.role.name, else: gettext("No role")} + + <%= if user.confirmed_at do %> + + {gettext("Confirmed")} + + <% else %> + + {gettext("Unconfirmed")} + + <% end %> + + {Calendar.strftime(user.inserted_at, "%Y-%m-%d %H:%M")} + +
+ <.link + navigate={~p"/admin/users/#{user}"} + class="btn btn-link btn-sm" + title={gettext("View user")} + > + + + + + + <.link + navigate={~p"/admin/users/#{user}/edit"} + class="btn btn-link btn-sm text-primary" + title={gettext("Edit user")} + > + + + + + + + + + +
+
+
+
+
+
+
+
+ <% :show -> %> +
+
+
+

{gettext("User details")}

+
+ <.link navigate={~p"/admin/users"} class="btn btn-outline btn-sm"> + {gettext("Back to users")} + + <.link navigate={~p"/admin/users/#{@user}/edit"} class="btn btn-primary btn-sm"> + {gettext("Edit")} + +
+
+
+ +
+
+
+

{@user.email}

+

{gettext("User Account")}

+
+
+
+
{gettext("Email")}
+
{@user.email}
+
+
+
{gettext("Role")}
+
+ {if @user.role, do: @user.role.name, else: gettext("No role")} +
+
+
+
{gettext("Status")}
+
+ <%= if @user.confirmed_at do %> + + {gettext("Confirmed")} + + <% else %> + + {gettext("Unconfirmed")} + + <% end %> +
+
+
+
{gettext("Created At")}
+
+ {Calendar.strftime(@user.inserted_at, "%Y-%m-%d %H:%M")} +
+
+
+
{gettext("Last Updated")}
+
+ {Calendar.strftime(@user.updated_at, "%Y-%m-%d %H:%M")} +
+
+ <%= if @user.confirmed_at do %> +
+
{gettext("Confirmed At")}
+
+ {Calendar.strftime(@user.confirmed_at, "%Y-%m-%d %H:%M")} +
+
+ <% end %> +
+
+
+
+
+ <% :new -> %> +
+
+
+

{gettext("New user")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.UserLive.FormComponent} + id="user-form" + title={gettext("New user")} + action={:new} + user={@user} + navigate={~p"/admin/users"} + /> +
+
+
+
+ <% :edit -> %> +
+
+
+

{gettext("Edit user")}

+
+
+ +
+
+
+ <.live_component + module={ClaperWeb.AdminLive.UserLive.FormComponent} + id={"user-form-#{@user.id}"} + title={gettext("Edit user")} + action={:edit} + user={@user} + navigate={~p"/admin/users"} + /> +
+
+
+
+<% end %> diff --git a/lib/claper_web/live/admin_live/user_live/form_component.ex b/lib/claper_web/live/admin_live/user_live/form_component.ex new file mode 100644 index 0000000..ae9d08e --- /dev/null +++ b/lib/claper_web/live/admin_live/user_live/form_component.ex @@ -0,0 +1,196 @@ +defmodule ClaperWeb.AdminLive.UserLive.FormComponent do + use ClaperWeb, :live_component + + alias Claper.Accounts + + @impl true + def render(assigns) do + ~H""" +
+ <.form for={@form} id="user-form" phx-target={@myself} phx-change="validate" phx-submit="save"> +
+ <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="user-email" + form={@form} + field={:email} + type="email" + label={gettext("Email")} + placeholder={gettext("Enter user email")} + required={true} + width_class="sm:col-span-6" + description={gettext("User's email address (must be unique)")} + /> + + <%= if @action == :new do %> + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="user-password" + form={@form} + field={:password} + type="password" + label={gettext("Password")} + placeholder={gettext("Enter password")} + required={true} + width_class="sm:col-span-3" + description={gettext("Initial password for the user")} + /> + <% end %> + + <.live_component + module={ClaperWeb.AdminLive.FormFieldComponent} + id="user-role-id" + form={@form} + field={:role_id} + type="select" + label={gettext("Role")} + select_options={@role_options} + required={true} + width_class="sm:col-span-3" + description={gettext("User's access level")} + /> + +
+
+ +
+
+
+ +
+
+ + +
+
+ +
+ """ + end + + @impl true + def update(%{user: user} = assigns, socket) do + # For edit action, ensure we have the current role_id in the changeset + # attrs = + # case assigns.action do + # :edit -> %{"role_id" => user.role_id} + # :new -> %{} + # end + + changeset = Accounts.change_user(user) + + role_options = + Accounts.list_roles() + |> Enum.map(&{String.capitalize(&1.name), &1.id}) + + # Determine if confirmed checkbox should be checked + confirmed_checked = + case assigns.action do + :edit -> !is_nil(user.confirmed_at) + :new -> false + end + + {:ok, + socket + |> assign(assigns) + |> assign(:role_options, role_options) + |> assign(:confirmed_checked, confirmed_checked) + |> assign_form(changeset)} + end + + @impl true + def handle_event("validate", %{"user" => user_params}, socket) do + # Update the confirmed_checked state based on form params + confirmed_checked = Map.get(user_params, "confirmed") == "true" + + # Convert confirmed checkbox to confirmed_at datetime + user_params = maybe_convert_confirmed_field(user_params) + + changeset = + socket.assigns.user + |> Accounts.change_user(user_params) + |> Map.put(:action, :validate) + + {:noreply, + socket + |> assign(:confirmed_checked, confirmed_checked) + |> assign_form(changeset)} + end + + def handle_event("save", %{"user" => user_params}, socket) do + # Convert confirmed checkbox to confirmed_at datetime + user_params = maybe_convert_confirmed_field(user_params) + save_user(socket, socket.assigns.action, user_params) + end + + def handle_event("cancel", _params, socket) do + {:noreply, push_navigate(socket, to: socket.assigns.navigate)} + end + + defp save_user(socket, :edit, user_params) do + case Accounts.update_user(socket.assigns.user, user_params) do + {:ok, user} -> + notify_parent({:saved, user}) + + {:noreply, + socket + |> put_flash(:info, gettext("User updated successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp save_user(socket, :new, user_params) do + case Accounts.create_user(user_params) do + {:ok, user} -> + notify_parent({:saved, user}) + + {:noreply, + socket + |> put_flash(:info, gettext("User created successfully")) + |> push_navigate(to: socket.assigns.navigate)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign_form(socket, changeset)} + end + end + + defp assign_form(socket, %Ecto.Changeset{} = changeset) do + form = to_form(changeset, as: :user) + assign(socket, :form, form) + end + + defp maybe_convert_confirmed_field(user_params) do + case Map.get(user_params, "confirmed") do + "true" -> + user_params + |> Map.delete("confirmed") + |> Map.put("confirmed_at", NaiveDateTime.utc_now()) + + "false" -> + user_params + |> Map.delete("confirmed") + |> Map.put("confirmed_at", nil) + + _ -> + user_params + end + end + + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) +end diff --git a/lib/claper_web/live/embed_live/form_component.html.heex b/lib/claper_web/live/embed_live/form_component.html.heex index 2d17912..ec67b28 100644 --- a/lib/claper_web/live/embed_live/form_component.html.heex +++ b/lib/claper_web/live/embed_live/form_component.html.heex @@ -12,8 +12,6 @@ form={f} key={:title} name={gettext("Title")} - labelClass={if @dark, do: "text-white"} - fieldClass={if @dark, do: "bg-gray-700 text-white"} autofocus="true" required="true" /> @@ -24,8 +22,6 @@ key={:provider} name={gettext("Provider")} array={@providers} - labelClass={if @dark, do: "text-white"} - fieldClass={if @dark, do: "bg-gray-700 text-white h-full"} required="true" />
@@ -38,24 +34,22 @@ do: gettext("Iframe code"), else: gettext("Link to the content") } - labelClass={if @dark, do: "text-white"} - fieldClass={if @dark, do: "bg-gray-700 text-white"} autofocus="true" required="true" />
-

<%= gettext("Options") %>

+

{gettext("Options")}

- <%= checkbox(f, :attendee_visibility, class: "h-4 w-5") %> - <%= label( + {checkbox(f, :attendee_visibility, class: "h-4 w-5")} + {label( f, :attendee_visibility, gettext("Attendees can view the web content on their device"), class: "text-sm font-medium" - ) %> + )}
@@ -63,15 +57,15 @@ <%= if @live_action == :edit do %> - <%= link(gettext("Delete"), + {link(gettext("Delete"), to: "#", phx_click: "delete", phx_target: @myself, @@ -80,8 +74,8 @@ confirm: gettext("This will delete the web content, are you sure?") ], class: - "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-gradient-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" - ) %> + "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-linear-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" + )} <% end %> diff --git a/lib/claper_web/live/event_live/embed_component.ex b/lib/claper_web/live/event_live/embed_component.ex index b73d5bc..e7c0c54 100644 --- a/lib/claper_web/live/event_live/embed_component.ex +++ b/lib/claper_web/live/event_live/embed_component.ex @@ -29,7 +29,7 @@ defmodule ClaperWeb.EventLive.EmbedComponent do d="M14.25 9.75L16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0020.25 18V6A2.25 2.25 0 0018 3.75H6A2.25 2.25 0 003.75 6v12A2.25 2.25 0 006 20.25z" /> - <%= gettext("See current web content") %> + {gettext("See current web content")} @@ -52,8 +52,8 @@ defmodule ClaperWeb.EventLive.EmbedComponent do -

<%= gettext("Current web content") %>

-

<%= @embed.title %>

+

{gettext("Current web content")}

+

{@embed.title}

<.live_component diff --git a/lib/claper_web/live/event_live/embed_iframe_component.ex b/lib/claper_web/live/event_live/embed_iframe_component.ex index ef53356..d746cca 100644 --- a/lib/claper_web/live/event_live/embed_iframe_component.ex +++ b/lib/claper_web/live/event_live/embed_iframe_component.ex @@ -39,7 +39,7 @@ defmodule ClaperWeb.EventLive.EmbedIframeComponent do > <% "custom" -> %> - <%= raw(@content) %> + {raw(@content)} <% end %>
""" diff --git a/lib/claper_web/live/event_live/event_card_component.ex b/lib/claper_web/live/event_live/event_card_component.ex index 52acac6..a82016f 100644 --- a/lib/claper_web/live/event_live/event_card_component.ex +++ b/lib/claper_web/live/event_live/event_card_component.ex @@ -20,7 +20,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do class="text-lg font-medium text-primary-600 truncate" href={~p"/e/#{@event.code}/manage"} > - <%= @event.name %> + {@event.name}

LTI

-
+
<%= if Event.started?(@event) && !Event.finished?(@event) do %>
- <%= gettext("Live") %> + {gettext("Live")}
<% end %> <%= if !Event.started?(@event) && !Event.finished?(@event) do %>

- <%= gettext("Incoming") %> + {gettext("Incoming")}

<% end %> <%= if Event.finished?(@event) do %>

- <%= gettext("Finished") %> + {gettext("Finished")}

<% end %>
@@ -66,7 +66,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do

- <%= @event.code %> + {@event.code}

- <%= gettext("Starting on") %> + {gettext("Starting on")}

- <%= gettext("Finished on") %> + {gettext("Finished on")}

@@ -106,9 +106,9 @@ defmodule ClaperWeb.EventLive.EventCardComponent do phx-click-away={JS.hide(to: "#dropdown-#{@event.uuid}")} phx-click={JS.toggle(to: "#dropdown-#{@event.uuid}")} phx-target={@myself} - class="flex w-full lg:w-auto pl-3 pr-4 text-white items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline hover:bg-primary-600 bg-primary-500" + class="flex w-full lg:w-auto pl-3 pr-4 text-white items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline hover:bg-primary-600 bg-primary-500" > - <%= gettext("Join") %> + {gettext("Join")} @@ -186,7 +186,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do } phx-value-id={@event.uuid} phx-click="terminate" - class="flex w-full lg:w-auto pl-3 pr-4 text-white items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-red-500 hover:bg-red-600 transition" + class="flex w-full lg:w-auto pl-3 pr-4 text-white items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-red-500 hover:bg-red-600 transition" > - <%= gettext("End") %> + {gettext("End")}
@@ -207,9 +207,9 @@ defmodule ClaperWeb.EventLive.EventCardComponent do phx-click-away={JS.hide(to: "#dropdown-action-#{@event.uuid}")} phx-click={JS.toggle(to: "#dropdown-action-#{@event.uuid}")} phx-target={@myself} - class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline hover:bg-gray-300 bg-gray-200" + class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline hover:bg-gray-300 bg-gray-200" > - <%= gettext("More options") %> + {gettext("More options")} @@ -279,7 +279,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do class="mt-2 flex flex-col space-y-2 sm:space-y-0 justify-between sm:flex-row items-center" > - <%= gettext("Error when processing the file") %> + {gettext("Error when processing the file")}
<%= if not @is_leader do %> @@ -287,9 +287,9 @@ defmodule ClaperWeb.EventLive.EventCardComponent do phx-click-away={JS.hide(to: "#dropdown-action-#{@event.uuid}")} phx-click={JS.toggle(to: "#dropdown-action-#{@event.uuid}")} phx-target={@myself} - class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline hover:bg-gray-300 bg-gray-200" + class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline hover:bg-gray-300 bg-gray-200" > - <%= gettext("More options") %> + {gettext("More options")} @@ -341,7 +341,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do class="flex space-x-1 items-center" > - <%= gettext("Processing your file...") %> + {gettext("Processing your file...")}
<% end %> @@ -356,7 +356,7 @@ defmodule ClaperWeb.EventLive.EventCardComponent do > - <%= gettext("View report") %> + {gettext("View report")}
@@ -376,9 +376,9 @@ defmodule ClaperWeb.EventLive.EventCardComponent do phx-click-away={JS.hide(to: "#dropdown-action-#{@event.uuid}")} phx-click={JS.toggle(to: "#dropdown-action-#{@event.uuid}")} phx-target={@myself} - class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline hover:bg-gray-300 bg-gray-200" + class="flex w-full lg:w-auto pl-3 pr-4 text-gray-700 items-center justify-between py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline hover:bg-gray-300 bg-gray-200" > - <%= gettext("More options") %> + {gettext("More options")} diff --git a/lib/claper_web/live/event_live/event_form_component.html.heex b/lib/claper_web/live/event_live/event_form_component.html.heex index 86edde9..e60981a 100644 --- a/lib/claper_web/live/event_live/event_form_component.html.heex +++ b/lib/claper_web/live/event_live/event_form_component.html.heex @@ -33,13 +33,13 @@ /> - <%= gettext("How it works ?") %> + {gettext("How it works ?")}

- <%= @page_title %> + {@page_title}

@@ -48,30 +48,30 @@ type="submit" form="event-form" phx_disable_with="Loading..." - class="w-full lg:w-auto px-6 text-white py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-gradient-to-tl from-primary-500 to-secondary-500 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" + class="w-full lg:w-auto px-6 text-white py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-linear-to-tl from-primary-500 to-secondary-500 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" > - <%= case @action do + {case @action do :edit -> gettext("Save") :new -> gettext("Create") - end %> + end} <% else %> -
- <%= case @action do +
+ {case @action do :edit -> gettext("Save") :new -> gettext("Create") - end %> + end}
<% end %> <%= if @action == :edit && !@event.expired_at do %> - <%= link(gettext("Delete"), + {link(gettext("Delete"), to: "#", phx_click: "delete", phx_value_id: @event.uuid, data: [confirm: gettext("Are you sure?")], class: - "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-gradient-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" - ) %> + "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-linear-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" + )} <% end %>
@@ -85,7 +85,7 @@ data-tg-title={"📄 #{gettext("Presentation file (optional)")}"} >
<%= if @uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) < 100 do %> @@ -112,22 +112,22 @@ phx-submit="save-file" phx-target={@myself} > - <%= gettext("Upload a file") %> + {gettext("Upload a file")} <.live_file_input upload={@uploads.presentation_file} class="sr-only" /> -

<%= gettext("or drag and drop") %>

+

{gettext("or drag and drop")}

- <%= gettext("PDF, PPT, PPTX up to %{size} MB", size: @max_file_size) %> + {gettext("PDF, PPT, PPTX up to %{size} MB", size: @max_file_size)}

<%= for entry <- @uploads.presentation_file.entries do %> - <%= entry.progress %> + {entry.progress} <%= for err <- upload_errors(@uploads.presentation_file, entry) do %>

- <%= error_to_string(err) %> + {error_to_string(err)}

<% end %> <% end %> @@ -149,9 +149,9 @@ d="M5 13l4 4L19 7" /> -

<%= gettext("Presentation uploaded") %>

+

{gettext("Presentation uploaded")}

-

<%= entry.client_name %>

+

{entry.client_name}

- <%= gettext("Remove") %> + {gettext("Remove")}

<% end %> @@ -170,7 +170,7 @@ <% else %>
<%= if @uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) < 100 do %> @@ -189,7 +189,7 @@ d="M5 13l4 4L19 7" /> -

<%= gettext("Presentation attached") %>

+

{gettext("Presentation attached")}

<%= for entry <- @uploads.presentation_file.entries do %> - <%= entry.progress %> + {entry.progress} <%= for err <- upload_errors(@uploads.presentation_file, entry) do %>

- <%= error_to_string(err) %> + {error_to_string(err)}

<% end %> <% end %>
<% else %> @@ -235,19 +235,19 @@ d="M5 13l4 4L19 7" /> -

<%= gettext("Presentation replaced") %>

+

{gettext("Presentation replaced")}

<%= for entry <- @uploads.presentation_file.entries do %> -

<%= entry.client_name %>

+

{entry.client_name}

- <%= entry.progress %> + {entry.progress}
<%= for err <- upload_errors(@uploads.presentation_file, entry) do %>

- <%= error_to_string(err) %> + {error_to_string(err)}

<% end %>

@@ -258,7 +258,7 @@ phx-target={@myself} class="text-red-500 text-sm" > - <%= gettext("Remove") %> + {gettext("Remove")}

<% end %> @@ -267,7 +267,7 @@ <%= for entry <- @uploads.presentation_file.entries do %> <%= for err <- upload_errors(@uploads.presentation_file, entry) do %>

- <%= error_to_string(err) %> + {error_to_string(err)}

<% end %> <% end %> @@ -339,7 +339,7 @@ data-tg-order="4" > - <%= gettext("Facilitators can present and manage interactions") %> + {gettext("Facilitators can present and manage interactions")} @@ -381,15 +381,15 @@ key={:email} name="" /> - <%= hidden_input(l, :user_email, value: @current_user.email) %> + {hidden_input(l, :user_email, value: @current_user.email)} <% else %>
@@ -401,9 +401,9 @@ />
- <%= hidden_input(l, :temp_id) %> - <%= hidden_input(l, :event_id, value: @event.id) %> - <%= hidden_input(l, :user_email, value: @current_user.email) %> + {hidden_input(l, :temp_id)} + {hidden_input(l, :event_id, value: @event.id)} + {hidden_input(l, :user_email, value: @current_user.email)} <% end %> diff --git a/lib/claper_web/live/event_live/form_component.ex b/lib/claper_web/live/event_live/form_component.ex index 6cd8dce..2862ad5 100644 --- a/lib/claper_web/live/event_live/form_component.ex +++ b/lib/claper_web/live/event_live/form_component.ex @@ -29,7 +29,7 @@ defmodule ClaperWeb.EventLive.FormComponent do - <%= gettext("See current form") %> + {gettext("See current form")} @@ -48,8 +48,8 @@ defmodule ClaperWeb.EventLive.FormComponent do -

<%= gettext("Current form") %>

-

<%= @form.title %>

+

{gettext("Current form")}

+

{@form.title}

<%= form_for :form_submit, "#", [id: @id, phx_change: "validate", phx_target: @myself, phx_submit: "submit"], fn f -> %>
@@ -63,7 +63,7 @@ defmodule ClaperWeb.EventLive.FormComponent do fieldClass="bg-gray-700 text-white" key={String.to_atom(field.name)} name={field.name} - required="true" + required={field.required} value={ if is_nil(assigns.current_form_submit), do: ~c"", @@ -77,7 +77,7 @@ defmodule ClaperWeb.EventLive.FormComponent do fieldClass="bg-gray-700 text-white" key={String.to_atom(field.name)} name={field.name} - required="true" + required={field.required} value={ if is_nil(assigns.current_form_submit), do: ~c"", @@ -94,7 +94,7 @@ defmodule ClaperWeb.EventLive.FormComponent do type="submit" class="px-3 py-2 text-white font-semibold bg-primary-500 hover:bg-primary-600 rounded-md my-5" > - <%= if is_nil(assigns.current_form_submit), do: gettext("Submit"), else: gettext("Edit") %> + {if is_nil(assigns.current_form_submit), do: gettext("Submit"), else: gettext("Edit")} <%= unless is_nil(assigns.current_form_submit) do %> @@ -111,7 +111,7 @@ defmodule ClaperWeb.EventLive.FormComponent do > - <%= gettext("Saved") %> + {gettext("Saved")}
<% end %> diff --git a/lib/claper_web/live/event_live/index.ex b/lib/claper_web/live/event_live/index.ex index 02c4e13..9e0fdf3 100644 --- a/lib/claper_web/live/event_live/index.ex +++ b/lib/claper_web/live/event_live/index.ex @@ -1,7 +1,7 @@ defmodule ClaperWeb.EventLive.Index do use ClaperWeb, :live_view - alias Claper.Events + alias Claper.{Events, Presentations} alias Claper.Events.Event on_mount(ClaperWeb.UserLiveAuth) @@ -22,7 +22,7 @@ defmodule ClaperWeb.EventLive.Index do }) if connected?(socket) do - Phoenix.PubSub.subscribe(Claper.PubSub, "events:#{socket.assigns.current_user.id}") + Events.subscribe_user_events(socket.assigns.current_user.id) end expired_events_count = Events.count_expired_events(socket.assigns.current_user.id) @@ -50,11 +50,22 @@ defmodule ClaperWeb.EventLive.Index do end @impl true - def handle_info({:presentation_file_process_done, presentation}, socket) do - event = Claper.Events.get_event!(presentation.event.uuid, [:presentation_file]) + def handle_info({type, %Events.Event{}}, socket) + when type in [:created, :updated, :deleted] do + {:noreply, refresh_events(socket)} + end - {:noreply, - socket |> assign(:events, [event | socket.assigns.events]) |> put_flash(:info, nil)} + @impl true + def handle_info({type, %Presentations.PresentationFile{}}, socket) + when type in [:presentation_file_process_done] do + {:noreply, refresh_events(socket)} + end + + @impl true + def handle_info(message, socket) do + IO.puts("Received unknown message `#{inspect(message)}` in #{__MODULE__} #{inspect(self())}") + + {:noreply, socket} end @impl true @@ -245,4 +256,16 @@ defmodule ClaperWeb.EventLive.Index do if(socket.assigns.page == 1, do: events, else: socket.assigns.events ++ events) ) end + + defp refresh_events(socket) do + expired_events_count = Events.count_expired_events(socket.assigns.current_user.id) + invited_events_count = Events.count_managed_events_by(socket.assigns.current_user.email) + + socket + |> assign(:has_expired_events, expired_events_count > 0) + |> assign(:has_invited_events, invited_events_count > 0) + |> assign(:events, []) + |> assign(:page, 1) + |> load_events() + end end diff --git a/lib/claper_web/live/event_live/index.html.heex b/lib/claper_web/live/event_live/index.html.heex index e12315d..e242d37 100644 --- a/lib/claper_web/live/event_live/index.html.heex +++ b/lib/claper_web/live/event_live/index.html.heex @@ -25,7 +25,7 @@ /> - <%= gettext("How it works ?") %> + {gettext("How it works ?")} <%= if @live_action in [:new, :edit] do %> @@ -48,11 +48,11 @@ > -
+
@@ -108,7 +109,7 @@ >

- <%= gettext("My events") %> + {gettext("My events")}

@@ -138,7 +139,7 @@ /> - <%= gettext("Quick event") %> + {gettext("Quick event")} <.link @@ -147,7 +148,7 @@ data-tg-tour={gettext("Welcome to Claper! You can create a new event here.")} data-tg-title={"#{gettext("Your first steps with Claper")} 👋"} href={~p"/events/new"} - class="relative w-full sm:w-auto inline-flex justify-center items-center px-5 py-2 text-lg font-medium rounded-md text-white bg-gradient-to-tl from-primary-500 to-secondary-500 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" + class="relative w-full sm:w-auto inline-flex justify-center items-center px-5 py-2 text-lg font-medium rounded-md text-white bg-linear-to-tl from-primary-500 to-secondary-500 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" > - <%= gettext("Create event") %> + {gettext("Create event")}
@@ -175,7 +176,7 @@ phx-value-tab="not_expired" class={"#{if @active_tab == "not_expired", do: "bg-primary-100 text-primary-700", else: "text-gray-500 hover:text-gray-700"} px-3 py-2 font-medium rounded-md"} > - <%= gettext("Active") %> + {gettext("Active")} @@ -212,16 +213,16 @@
<% end %> <%= if Enum.count(@events) == 0 do %>
-

<%= gettext("Create your first event") %>

+

{gettext("Create your first event")}

<% end %>
diff --git a/lib/claper_web/live/event_live/join.html.heex b/lib/claper_web/live/event_live/join.html.heex index 0624078..7b51cf0 100644 --- a/lib/claper_web/live/event_live/join.html.heex +++ b/lib/claper_web/live/event_live/join.html.heex @@ -21,21 +21,21 @@ @click.away="open = false" > - <%= gettext("About") %> + {gettext("About")} <%= if @current_user do %> <.link href={~p"/events"} - class="relative inline-flex items-center px-4 py-1 text-base font-sm rounded-md text-white bg-gradient-to-tl from-primary-500 to-secondary-500 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" + class="relative inline-flex items-center px-4 py-1 text-base font-sm rounded-md text-white bg-linear-to-tl from-primary-500 to-secondary-500 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" > - <%= gettext("Dashboard") %> + {gettext("Dashboard")} <% else %> <.link href={~p"/users/log_in"} - class="relative inline-flex items-center px-4 py-1 text-base font-sm rounded-md text-white bg-gradient-to-tl from-primary-500 to-secondary-500 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" + class="relative inline-flex items-center px-4 py-1 text-base font-sm rounded-md text-white bg-linear-to-tl from-primary-500 to-secondary-500 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" > - <%= gettext("Login") %> + {gettext("Login")} <% end %> @@ -44,21 +44,21 @@ @@ -71,13 +71,13 @@ <%= form_for :event, ~p"/join", ["phx-submit": "join", "phx-hook": "JoinEvent", id: "form"], fn f -> %>
- <%= text_input(f, :code, + {text_input(f, :code, required: true, autofocus: true, id: "input", class: - "transition-all bg-transparent tracking-widest w-full uppercase text-white text-2xl px-3 border-b border-gray-200 focus:border-b-2 pt-5 pl-12 pb-3 outline-none" - ) %> + "transition-all bg-transparent tracking-widest w-full uppercase text-white text-2xl px-3 border-b border-gray-200 focus:border-b-2 pt-5 pl-12 pb-3 outline-hidden" + )} - <%= gettext("Join") %> + {gettext("Join")}
<%= if @last_event do %> <.link href={~p"/e/#{@last_event.code}"}> -
+

- <%= gettext("Return to your last event") %> (<%= @last_event.name %>) + {gettext("Return to your last event")} ({@last_event.name})

diff --git a/lib/claper_web/live/event_live/manage.ex b/lib/claper_web/live/event_live/manage.ex index 6a95a9a..e5c3b80 100644 --- a/lib/claper_web/live/event_live/manage.ex +++ b/lib/claper_web/live/event_live/manage.ex @@ -1,12 +1,8 @@ defmodule ClaperWeb.EventLive.Manage do use ClaperWeb, :live_view + alias Claper.{Embeds, Forms, Polls, Presentations, Quizzes} alias ClaperWeb.Presence - alias Claper.Polls - alias Claper.Forms - alias Claper.Embeds - # Add this line - alias Claper.Quizzes @impl true def mount(%{"code" => code}, session, socket) do @@ -39,6 +35,7 @@ defmodule ClaperWeb.EventLive.Manage do socket = socket + |> assign(:interaction_modal, false) |> assign(:settings_modal, false) |> assign(:attendees_nb, 1) |> assign(:event, event) @@ -74,7 +71,7 @@ defmodule ClaperWeb.EventLive.Manage do end defp leader?(%{assigns: %{current_user: current_user}} = _socket, event) do - Claper.Events.leaded_by?(current_user.email, event) || event.user.id == current_user.id + Claper.Events.led_by?(current_user.email, event) || event.user.id == current_user.id end defp leader?(_socket, _event), do: false @@ -585,6 +582,23 @@ defmodule ClaperWeb.EventLive.Manage do {:noreply, socket |> assign(:state, new_state)} end + @impl true + def handle_event( + "checked", + %{"key" => "show_attendee_count", "value" => value}, + %{assigns: %{event: _event, state: state}} = socket + ) do + {:ok, new_state} = + Claper.Presentations.update_presentation_state( + state, + %{ + :show_attendee_count => value + } + ) + + {:noreply, socket |> assign(:state, new_state)} + end + @impl true def handle_event( "checked", @@ -762,18 +776,26 @@ defmodule ClaperWeb.EventLive.Manage do end @impl true - def handle_params(params, _url, socket) do - {:noreply, apply_action(socket, socket.assigns.live_action, params)} + def handle_event( + "toggle-interaction-modal", + _params, + %{assigns: %{interaction_modal: _interaction_modal = true}} = socket + ) do + {:noreply, socket |> push_navigate(to: ~p"/e/#{socket.assigns.event.code}/manage")} end - def toggle_add_modal(js \\ %JS{}) do - js - |> JS.toggle( - to: "#add-modal", - out: "animate__animated animate__fadeOut", - in: "animate__animated animate__fadeIn" - ) - |> JS.push("maybe-redirect", target: "#add-modal") + @impl true + def handle_event( + "toggle-interaction-modal", + _params, + %{assigns: %{interaction_modal: _interaction_modal}} = socket + ) do + {:noreply, socket |> assign(:interaction_modal, true)} + end + + @impl true + def handle_params(params, _url, socket) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} end def toggle_settings_modal(js \\ %JS{}) do @@ -802,6 +824,7 @@ defmodule ClaperWeb.EventLive.Manage do socket |> assign(:create, "poll") + |> assign(:interaction_modal, true) |> assign(:create_action, :edit) |> assign(:poll, poll) end @@ -834,6 +857,7 @@ defmodule ClaperWeb.EventLive.Manage do socket |> assign(:create, "form") + |> assign(:interaction_modal, true) |> assign(:create_action, :edit) |> assign(:form, form) end @@ -843,6 +867,7 @@ defmodule ClaperWeb.EventLive.Manage do socket |> assign(:create, "embed") + |> assign(:interaction_modal, true) |> assign(:create_action, :edit) |> assign(:embed, embed) end @@ -873,6 +898,7 @@ defmodule ClaperWeb.EventLive.Manage do socket |> assign(:create, "quiz") + |> assign(:interaction_modal, true) |> assign(:create_action, :edit) |> assign(:quiz, quiz) end diff --git a/lib/claper_web/live/event_live/manage.html.heex b/lib/claper_web/live/event_live/manage.html.heex index d1832cb..573a0e6 100644 --- a/lib/claper_web/live/event_live/manage.html.heex +++ b/lib/claper_web/live/event_live/manage.html.heex @@ -32,7 +32,7 @@ /> - <%= gettext("How it works ?") %> + {gettext("How it works ?")}

-
+
<.live_component @@ -134,22 +134,21 @@
-
@@ -146,7 +146,7 @@ defmodule ClaperWeb.EventLive.ManageablePostComponent do <%= if @post.lol_count> 0 do %> - <%= @post.lol_count %> + {@post.lol_count} <% end %>
diff --git a/lib/claper_web/live/event_live/manageable_quiz_component.ex b/lib/claper_web/live/event_live/manageable_quiz_component.ex index 7a8ae47..0a4a953 100644 --- a/lib/claper_web/live/event_live/manageable_quiz_component.ex +++ b/lib/claper_web/live/event_live/manageable_quiz_component.ex @@ -12,13 +12,13 @@ defmodule ClaperWeb.EventLive.ManageableQuizComponent do ~H"""

- <%= @quiz.title %> + {@quiz.title} = 0}> - <%= Enum.at(@quiz.quiz_questions, @current_question_idx).content %> + {Enum.at(@quiz.quiz_questions, @current_question_idx).content}

@@ -26,9 +26,9 @@ defmodule ClaperWeb.EventLive.ManageableQuizComponent do :if={@current_question_idx == -1} class={"#{if @iframe, do: "space-y-5", else: "space-y-8"} flex flex-col text-white text-center"} > -

<%= gettext("Average score") %>:

+

{gettext("Average score")}:

- <%= Claper.Quizzes.calculate_average_score(@quiz.id) %>/<%= length(@quiz.quiz_questions) %> + {Claper.Quizzes.calculate_average_score(@quiz.id)}/{length(@quiz.quiz_questions)}

@@ -38,11 +38,11 @@ defmodule ClaperWeb.EventLive.ManageableQuizComponent do > <%= for {opt, _idx} <- Enum.with_index(Enum.at(@quiz.quiz_questions, @current_question_idx).quiz_question_opts) do %>
-
+
- <%= opt.content %> - <%= opt.percentage %>% (<%= opt.response_count %>) + {opt.content} + {opt.percentage}% ({opt.response_count})
<% end %> diff --git a/lib/claper_web/live/event_live/manager_settings_component.ex b/lib/claper_web/live/event_live/manager_settings_component.ex index 790d384..69677aa 100644 --- a/lib/claper_web/live/event_live/manager_settings_component.ex +++ b/lib/claper_web/live/event_live/manager_settings_component.ex @@ -5,7 +5,7 @@ defmodule ClaperWeb.EventLive.ManagerSettingsComponent do assigns = assigns |> assign_new(:show_shortcut, fn -> true end) ~H""" -
+
- <%= gettext("Interaction") %> + {gettext("Interaction")}
<%= case @current_interaction do %> @@ -59,10 +59,10 @@ defmodule ClaperWeb.EventLive.ManagerSettingsComponent do - <%= gettext("Hide results on presentation") %> + {gettext("Hide results on presentation")} - <%= gettext("Show results on presentation") %> + {gettext("Show results on presentation")} - <%= gettext("Hide results on presentation") %> + {gettext("Hide results on presentation")} - <%= gettext("Show results on presentation") %> + {gettext("Show results on presentation")} - <%= gettext("Review questions") %> + {gettext("Review questions")}
@@ -165,7 +165,7 @@ defmodule ClaperWeb.EventLive.ManagerSettingsComponent do - <%= gettext("Previous") %> + {gettext("Previous")} - <%= gettext("Next") %> + {gettext("Next")}
-
-
-
- - - +
+
+
+
+ + + - <%= gettext("Presentation") %> + {gettext("Presentation")} +
+ +
+ + + + + + + + +
+ + {gettext("Show instructions to join")} + + + {gettext("Hide instructions to join")} + +
+ + q + +
+
+
+ +
+ + + + + + + +
+ {gettext("Show messages")} + {gettext("Hide messages")} +
+ + w + +
+
+
+ +
+ + + + + + + +
+ + {gettext("Show only pinned messages")} + + {gettext("Show all messages")} +
+ + e + +
+
+
+
+ + + + + + + +
+ + {gettext("Show attendee count")} + + + {gettext("Hide attendee count")} + +
+ + r + +
+
+
-
- +
+ + + + + + {gettext("Attendees")} +
+ +
+ + + + + + + +
+ {gettext("Enable messages")} + {gettext("Disable messages")} +
+ + a + +
+
+
+ +
- - - + + + + + + - - - -
- - <%= gettext("Show instructions to join") %> - - - <%= gettext("Hide instructions to join") %> - -
- - q - -
- -
+
+ + {gettext("Allow anonymous messages")} + + + {gettext("Deny anonymous messages")} + +
+ + s + +
+
+
-
- - + - - - - - -
- <%= gettext("Show messages") %> - <%= gettext("Hide messages") %> -
- - w - -
-
-
+ + + + + + -
- - - - - - - -
- - <%= gettext("Show only pinned messages") %> - - <%= gettext("Show all messages") %> -
- - e - -
-
-
-
- -
-
- - - - - - <%= gettext("Attendees") %> -
- -
- - - - - - - -
- <%= gettext("Enable messages") %> - <%= gettext("Disable messages") %> -
- - a - -
-
-
- -
- - - - - - - - -
- - <%= gettext("Allow anonymous messages") %> - - - <%= gettext("Deny anonymous messages") %> - -
- - s - -
-
-
- -
- - - - - - - - -
- - <%= gettext("Enable reactions") %> - - - <%= gettext("Disable reactions") %> - -
- - d - -
-
+
+ + {gettext("Enable reactions")} + + + {gettext("Disable reactions")} + +
+ + d + +
+ +
diff --git a/lib/claper_web/live/event_live/poll_component.ex b/lib/claper_web/live/event_live/poll_component.ex index 4079a5a..fda8e80 100644 --- a/lib/claper_web/live/event_live/poll_component.ex +++ b/lib/claper_web/live/event_live/poll_component.ex @@ -25,7 +25,7 @@ defmodule ClaperWeb.EventLive.PollComponent do d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" /> - <%= gettext("See current poll") %> + {gettext("See current poll")}
@@ -44,12 +44,12 @@ defmodule ClaperWeb.EventLive.PollComponent do
-

<%= gettext("Current poll") %>

-

<%= @poll.title %>

+

{gettext("Current poll")}

+

{@poll.title}

<%= if @poll.multiple do %> -

<%= gettext("Select one or multiple options") %>

+

{gettext("Select one or multiple options")}

<% else %> -

<%= gettext("Select one option") %>

+

{gettext("Select one option")}

<% end %>
@@ -60,7 +60,7 @@ defmodule ClaperWeb.EventLive.PollComponent do <% else %> @@ -93,7 +93,7 @@ defmodule ClaperWeb.EventLive.PollComponent do >
@@ -111,10 +111,10 @@ defmodule ClaperWeb.EventLive.PollComponent do <% end %> <% end %> - <%= opt.content %> + {opt.content}
- <%= opt.percentage %>% (<%= opt.vote_count %>) + {opt.percentage}% ({opt.vote_count}) <% end %> @@ -124,7 +124,7 @@ defmodule ClaperWeb.EventLive.PollComponent do <%= if (length @selected_poll_opt) == 0 || (length @current_poll_vote) > 0 do %> <% else %> <% end %>
diff --git a/lib/claper_web/live/event_live/post_component.ex b/lib/claper_web/live/event_live/post_component.ex index 3d54dc3..34ba6fc 100644 --- a/lib/claper_web/live/event_live/post_component.ex +++ b/lib/claper_web/live/event_live/post_component.ex @@ -25,12 +25,12 @@ defmodule ClaperWeb.EventLive.PostComponent do <%= if @post.name || leader?(@post, @event, @leaders) || pinned?(@post) do %>
<%= if @post.name do %> -

<%= @post.name %>

+

{@post.name}

<% end %> <%= if leader?(@post, @event, @leaders) do %>
- <%= gettext("Host") %> + {gettext("Host")}
<% end %> @@ -56,7 +56,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > - <%= gettext("Pinned") %> + {gettext("Pinned")}
<% end %>
@@ -67,34 +67,34 @@ defmodule ClaperWeb.EventLive.PostComponent do class="hidden absolute right-4 top-7 bg-white rounded-lg px-5 py-2 animate__faster" > - <%= link(gettext("Delete"), + {link(gettext("Delete"), to: "#", phx_click: "delete", phx_value_id: @post.uuid, phx_value_event_id: @event.uuid, data: [confirm: gettext("Are you sure?")] - ) %> + )}
-

<%= ClaperWeb.Helpers.format_body(@post.body) %>

+

{ClaperWeb.Helpers.format_body(@post.body)}

<%= if @post.like_count > 0 do %>
- <%= @post.like_count %> + {@post.like_count}
<% end %> <%= if @post.love_count > 0 do %>
- <%= @post.love_count %> + {@post.love_count}
<% end %> <%= if @post.lol_count > 0 do %>
- <%= @post.lol_count %> + {@post.lol_count}
<% end %>
@@ -104,12 +104,12 @@ defmodule ClaperWeb.EventLive.PostComponent do <%= if @post.name || leader?(@post, @event, @leaders) do %>
<%= if @post.name do %> -

<%= @post.name %>

+

{@post.name}

<% end %> <%= if leader?(@post, @event, @leaders) do %>
- <%= gettext("Host") %> + {gettext("Host")}
<% end %>
@@ -139,13 +139,13 @@ defmodule ClaperWeb.EventLive.PostComponent do class="hidden absolute right-4 top-7 bg-gray-900 rounded-lg px-5 py-2" > - <%= link(gettext("Delete"), + {link(gettext("Delete"), to: "#", phx_click: "delete", phx_value_id: @post.uuid, phx_value_event_id: @event.uuid, data: [confirm: gettext("Are you sure?")] - ) %> + )} <% end %> @@ -172,11 +172,11 @@ defmodule ClaperWeb.EventLive.PostComponent do > - <%= gettext("Pinned") %> + {gettext("Pinned")} <% end %> -

<%= ClaperWeb.Helpers.format_body(@post.body) %>

+

{ClaperWeb.Helpers.format_body(@post.body)}

<%= if @reaction_enabled do %> @@ -189,7 +189,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > <%= if @post.like_count > 0 do %> - <%= @post.like_count %> + {@post.like_count} <% end %> <% else %> @@ -203,7 +203,7 @@ defmodule ClaperWeb.EventLive.PostComponent do <%= if @post.like_count > 0 do %> - <%= @post.like_count %> + {@post.like_count} <% end %> <% end %> @@ -216,7 +216,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > <%= if @post.love_count > 0 do %> - <%= @post.love_count %> + {@post.love_count} <% end %> <% else %> @@ -228,7 +228,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > <%= if @post.love_count > 0 do %> - <%= @post.love_count %> + {@post.love_count} <% end %> <% end %> @@ -241,7 +241,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > <%= if @post.lol_count > 0 do %> - <%= @post.lol_count %> + {@post.lol_count} <% end %> <% else %> @@ -253,7 +253,7 @@ defmodule ClaperWeb.EventLive.PostComponent do > <%= if @post.lol_count > 0 do %> - <%= @post.lol_count %> + {@post.lol_count} <% end %> <% end %> diff --git a/lib/claper_web/live/event_live/presenter.ex b/lib/claper_web/live/event_live/presenter.ex index 93bc610..06fcffc 100644 --- a/lib/claper_web/live/event_live/presenter.ex +++ b/lib/claper_web/live/event_live/presenter.ex @@ -6,6 +6,8 @@ defmodule ClaperWeb.EventLive.Presenter do alias Claper.Polls.Poll alias Claper.Forms.Form alias Claper.Quizzes.Quiz + alias Claper.Presentations + @impl true def mount(%{"code" => code} = params, session, socket) do with %{"locale" => locale} <- session do @@ -70,7 +72,7 @@ defmodule ClaperWeb.EventLive.Presenter do end defp leader?(%{assigns: %{current_user: current_user}} = _socket, event) do - Claper.Events.leaded_by?(current_user.email, event) || event.user.id == current_user.id + Claper.Events.led_by?(current_user.email, event) || event.user.id == current_user.id end defp leader?(_socket, _event), do: false diff --git a/lib/claper_web/live/event_live/presenter.html.heex b/lib/claper_web/live/event_live/presenter.html.heex index 50ba0c1..7fb12c8 100644 --- a/lib/claper_web/live/event_live/presenter.html.heex +++ b/lib/claper_web/live/event_live/presenter.html.heex @@ -23,7 +23,7 @@ >
- <%= gettext("Scan to interact in real-time") %> + {gettext("Scan to interact in real-time")}
- <%= gettext("Or go to %{url} and use the code:", url: @host) %> + {gettext("Or go to %{url} and use the code:", url: @host)} - #<%= String.upcase(@event.code) %> + #{String.upcase(@event.code)}
@@ -46,11 +46,11 @@ <%= if @current_poll do %>

- <%= @current_poll.title %> + {@current_poll.title}

@@ -59,16 +59,16 @@
- <%= opt.content %> + {opt.content}
- <%= opt.percentage %>% (<%= opt.vote_count %>) + {opt.percentage}% ({opt.vote_count})
<% end %> @@ -107,10 +107,10 @@
<%= if post.name do %>

- <%= post.name %> + {post.name}

<% end %> -

<%= post.body %>

+

{post.body}

<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
@@ -120,7 +120,7 @@ src="/images/icons/thumb.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.like_count %> + {post.like_count} <% end %>
@@ -129,7 +129,7 @@ src="/images/icons/heart.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.love_count %> + {post.love_count} <% end %>
@@ -138,7 +138,7 @@ src="/images/icons/laugh.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.lol_count %> + {post.lol_count} <% end %>
@@ -154,10 +154,10 @@
<%= if post.name do %>

- <%= post.name %> + {post.name}

<% end %> -

<%= post.body %>

+

{post.body}

<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
@@ -167,7 +167,7 @@ src="/images/icons/thumb.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.like_count %> + {post.like_count} <% end %>
@@ -176,7 +176,7 @@ src="/images/icons/heart.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.love_count %> + {post.love_count} <% end %>
@@ -185,7 +185,7 @@ src="/images/icons/laugh.svg" class={"#{if @iframe, do: "h-4", else: "h-7"}"} /> - <%= post.lol_count %> + {post.lol_count} <% end %>
@@ -197,7 +197,7 @@ <% end %>
0) || (!@current_embed && @event.presentation_file.length == 0), do: "hidden"}"} + class={"gutter-1 row-span-full cursor-col-resize col-2 text-center text-sm leading-3 text-white #{if (!@state.chat_visible && @event.presentation_file.length > 0) || (!@current_embed && @event.presentation_file.length == 0), do: "hidden"}"} style="writing-mode: vertical-rl" > ••• @@ -216,27 +216,17 @@
<% end %>
- <%= for index <- 1..max(1, @event.presentation_file.length) do %> - <%= if @event.presentation_file.length > 0 do %> - <%= if Application.get_env(:claper, :presentations) |> Keyword.get(:storage) == "local" do %> - - <% else %> - Keyword.get(:aws_bucket)}.s3.#{Application.get_env(:ex_aws, :region)}.amazonaws.com/presentations/#{@event.presentation_file.hash}/#{index}.jpg"} - /> - <% end %> - <% end %> - <% end %> +
@@ -244,7 +234,7 @@
- <%= @attendees_nb %> + {@attendees_nb}
diff --git a/lib/claper_web/live/event_live/quiz_component.ex b/lib/claper_web/live/event_live/quiz_component.ex index 0d50032..b5a7d54 100644 --- a/lib/claper_web/live/event_live/quiz_component.ex +++ b/lib/claper_web/live/event_live/quiz_component.ex @@ -38,7 +38,7 @@ defmodule ClaperWeb.EventLive.QuizComponent do d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> - <%= gettext("See current quiz") %> + {gettext("See current quiz")} @@ -57,13 +57,13 @@ defmodule ClaperWeb.EventLive.QuizComponent do -

<%= gettext("Current quiz") %>

+

{gettext("Current quiz")}

<%= if is_nil(@current_question) do %> -

<%= @quiz.title %>

+

{@quiz.title}

<% else %> -

<%= @current_question.content %>

+

{@current_question.content}

- <%= @current_quiz_question_idx + 1 %>/<%= length(@quiz.quiz_questions) %> + {@current_quiz_question_idx + 1}/{length(@quiz.quiz_questions)}

<% end %> @@ -81,10 +81,10 @@ defmodule ClaperWeb.EventLive.QuizComponent do
<% end %> - <%= opt.content %> + {opt.content} - <%= opt.percentage %>% (<%= opt.response_count %>) + {opt.percentage}% ({opt.response_count}) <% else %> @@ -93,7 +93,7 @@ defmodule ClaperWeb.EventLive.QuizComponent do phx-value-opt={opt.id} class="bg-gray-500 px-3 py-2 rounded-lg flex justify-between items-center relative text-white" > -
+
<%= if Enum.member?(@selected_quiz_question_opts, opt) do %> @@ -102,7 +102,7 @@ defmodule ClaperWeb.EventLive.QuizComponent do <% end %> - <%= opt.content %> + {opt.content}
<% end %> @@ -110,18 +110,18 @@ defmodule ClaperWeb.EventLive.QuizComponent do <% else %>
<%= if @quiz.show_results do %> -

<%= gettext("Your score") %>

+

{gettext("Your score")}

- <%= elem(@quiz_score, 0) %>/<%= elem(@quiz_score, 1) %> + {elem(@quiz_score, 0)}/{elem(@quiz_score, 1)}

<% else %> -

<%= gettext("Waiting for results...") %>

+

{gettext("Waiting for results...")}

<%= if @current_quiz_question_idx > 0 do %> <% end %> @@ -158,21 +158,21 @@ defmodule ClaperWeb.EventLive.QuizComponent do class={"px-3 py-2 text-white font-medium rounded-md h-full #{if @has_selection, do: "bg-primary-400 hover:bg-primary-500", else: "bg-gray-500 cursor-not-allowed"}"} disabled={not @has_selection} > - <%= gettext("Next") %> + {gettext("Next")} <% else %> <%= if is_nil(@current_user) && !@quiz.allow_anonymous do %>
- <%= gettext("Please sign in to submit your answers") %> + {gettext("Please sign in to submit your answers")}
- <%= link( + {link( gettext("Sign in"), target: "_blank", to: ~p"/users/log_in", class: "inline px-3 py-2 text-white font-medium rounded-md h-full bg-primary-400 hover:bg-primary-500" - ) %> + )}
<% else %> <% end %> <% end %> @@ -195,7 +195,7 @@ defmodule ClaperWeb.EventLive.QuizComponent do > <%= if (@current_quiz_question_idx > 0 && @current_quiz_question_idx <= length(@quiz.quiz_questions) - 1) do %> <% else %>
@@ -206,7 +206,7 @@ defmodule ClaperWeb.EventLive.QuizComponent do phx-click="next-question" class="px-3 py-2 text-white font-medium bg-primary-400 hover:bg-primary-500 rounded-md h-full" > - <%= gettext("Next") %> + {gettext("Next")}
diff --git a/lib/claper_web/live/event_live/show.ex b/lib/claper_web/live/event_live/show.ex index 892b4b2..6b5a512 100644 --- a/lib/claper_web/live/event_live/show.ex +++ b/lib/claper_web/live/event_live/show.ex @@ -109,7 +109,7 @@ defmodule ClaperWeb.EventLive.Show do defp check_leader(%{assigns: %{current_user: current_user} = _assigns} = socket, event) when is_map(current_user) do is_leader = - current_user.id == event.user_id || Claper.Events.leaded_by?(current_user.email, event) + current_user.id == event.user_id || Claper.Events.led_by?(current_user.email, event) socket |> assign(:is_leader, is_leader) end @@ -187,7 +187,7 @@ defmodule ClaperWeb.EventLive.Show do end @impl true - def handle_info({:event_terminated, _event}, socket) do + def handle_info({:event_terminated, _event_uuid}, socket) do {:noreply, socket |> put_flash(:error, gettext("This event has been terminated")) @@ -291,10 +291,6 @@ defmodule ClaperWeb.EventLive.Show do @impl true def handle_info({:form_updated, %Claper.Forms.Form{enabled: true} = form}, socket) do - {:noreply, - socket - |> update(:current_interaction, fn _current_interaction -> nil end)} - {:noreply, socket |> load_current_interaction(form, true)} @@ -328,17 +324,6 @@ defmodule ClaperWeb.EventLive.Show do |> load_current_interaction(quiz, true)} end - @impl true - def handle_info({:quiz_deleted, %Claper.Quizzes.Quiz{enabled: true}}, socket) do - end - - @impl true - def handle_info({:quiz_updated, %Claper.Quizzes.Quiz{enabled: true} = quiz}, socket) do - {:noreply, - socket - |> load_current_interaction(quiz, true)} - end - @impl true def handle_info({:quiz_deleted, %Claper.Quizzes.Quiz{enabled: true}}, socket) do {:noreply, @@ -708,7 +693,7 @@ defmodule ClaperWeb.EventLive.Show do ) when is_map(current_user) do case Claper.Quizzes.submit_quiz( - current_user.id, + current_user, opts, socket.assigns.current_interaction.id ) do diff --git a/lib/claper_web/live/event_live/show.html.heex b/lib/claper_web/live/event_live/show.html.heex index a3bb9b7..4d20185 100644 --- a/lib/claper_web/live/event_live/show.html.heex +++ b/lib/claper_web/live/event_live/show.html.heex @@ -1,10 +1,10 @@ <%= if @started || @is_leader do %> -
+ @@ -35,23 +35,23 @@ >
- <%= @attendees_nb %> + {@attendees_nb}
@@ -162,7 +162,7 @@ <%= if @post_count == 0 && @state.chat_enabled do %>
- <%= gettext("Be the first to react !") %> + {gettext("Be the first to react !")}
<% end %> @@ -205,7 +205,7 @@ - <%= gettext("Anonymous") %> + {gettext("Anonymous")} <% else %> <% end %> @@ -246,13 +246,13 @@ - <%= gettext("Use your name") %> + {gettext("Use your name")}
@@ -275,15 +275,15 @@ backdrop-filter: blur(11.5px); -webkit-backdrop-filter: blur(11.5px);" > - <%= text_input(f, :name, + {text_input(f, :name, class: - "bg-transparent outline-none w-full text-white h-10 placeholder-white resize-none pr-20 leading-4 overflow-y-hidden focus:overflow-y-auto", + "bg-transparent outline-hidden w-full text-white h-10 placeholder-white resize-none pr-20 leading-4 overflow-y-hidden focus:overflow-y-auto", placeholder: gettext("Enter your name") - ) %> + )}

- <%= error_tag(f, :name) %> + {error_tag(f, :name)}

- <%= submit(gettext("Join"), class: "absolute right-5 top-2 p-2 bg-white rounded-md") %> + {submit(gettext("Join"), class: "absolute right-5 top-2 p-2 bg-white rounded-md")} <% else %> @@ -326,9 +326,9 @@ /> <%= if @nickname && @nickname == "" do %> - <%= gettext("Anonymous") %> + {gettext("Anonymous")} <% else %> - <%= @nickname %> + {@nickname} <% end %> @@ -338,15 +338,15 @@
- <%= textarea(f, :body, + {textarea(f, :body, id: "postFormTA", class: - "bg-transparent outline-none w-full text-white h-10 placeholder-white pt-3 resize-none pr-20 leading-4 overflow-y-hidden focus:overflow-y-auto", + "bg-transparent outline-hidden w-full text-white h-10 placeholder-white pt-3 resize-none pr-20 leading-4 overflow-y-hidden focus:overflow-y-auto", placeholder: gettext("Ask, comment...") - ) %> + )}
- <%= submit("Save", phx_disable_with: "Saving...", id: "hiddenSubmit", class: "hidden") %> + {submit("Save", phx_disable_with: "Saving...", id: "hiddenSubmit", class: "hidden")} <% end %> <% else %> @@ -361,8 +361,8 @@ -webkit-backdrop-filter: blur(11.5px);" >
-
- <%= gettext("Messages deactivated") %> +
+ {gettext("Messages deactivated")}
@@ -420,7 +420,7 @@
-

<%= @event.name %>

+

{@event.name}

- <%= if @remaining_days < 10, do: "0" %><%= @remaining_days %> + {if @remaining_days < 10, do: "0"}{@remaining_days} - <%= gettext("days") %> + {gettext("days")}
- <%= if @remaining_hours < 10, do: "0" %><%= @remaining_hours %> + {if @remaining_hours < 10, do: "0"}{@remaining_hours} - <%= gettext("hours") %> + {gettext("hours")}
- <%= if @remaining_minutes < 10, do: "0" %><%= @remaining_minutes %> + {if @remaining_minutes < 10, do: "0"}{@remaining_minutes} - <%= gettext("minutes") %> + {gettext("minutes")}
- <%= if @remaining_seconds < 10, do: "0" %><%= @remaining_seconds %> + {if @remaining_seconds < 10, do: "0"}{@remaining_seconds} - <%= gettext("seconds") %> + {gettext("seconds")}

diff --git a/lib/claper_web/live/modal_component.ex b/lib/claper_web/live/modal_component.ex index f61f38a..37b5405 100644 --- a/lib/claper_web/live/modal_component.ex +++ b/lib/claper_web/live/modal_component.ex @@ -15,20 +15,19 @@ defmodule ClaperWeb.ModalComponent do phx-window-keydown={hide_modal()} phx-key="escape" phx-target={@myself} - phx-page-loading >
-
+
@@ -36,16 +35,16 @@ defmodule ClaperWeb.ModalComponent do

- <%= @title %> + {@title}

- <%= @description %> + {@description}

- <%= render_slot(@inner_block) %> + {render_slot(@inner_block)}

@@ -64,6 +63,6 @@ defmodule ClaperWeb.ModalComponent do def hide_modal(js \\ %JS{}) do js |> JS.hide(to: "#modal", transition: "animate__animated animate__fadeOut", time: 300) - |> JS.push("hide", target: "#modal") + |> JS.push("hide", target: "#modal", page_loading: true) end end diff --git a/lib/claper_web/live/poll_live/form_component.html.heex b/lib/claper_web/live/poll_live/form_component.html.heex index 64fe502..d96fb91 100644 --- a/lib/claper_web/live/poll_live/form_component.html.heex +++ b/lib/claper_web/live/poll_live/form_component.html.heex @@ -12,8 +12,6 @@ form={f} key={:title} name={gettext("Title of your poll")} - labelClass={if @dark, do: "text-white"} - fieldClass={if @dark, do: "bg-gray-700 text-white"} autofocus="true" required="true" /> @@ -24,8 +22,6 @@
-

<%= gettext("Options") %>

+

{gettext("Options")}

- <%= checkbox(f, :show_results, class: "h-4 w-4") %> - <%= label( + {checkbox(f, :show_results, class: "h-4 w-4")} + {label( f, :show_results, gettext("Attendees can see the results on their device"), class: "text-sm font-medium" - ) %> + )}
- <%= checkbox(f, :multiple, class: "h-4 w-4") %> - <%= label(f, :multiple, gettext("Multiple answers"), class: "text-sm font-medium") %> + {checkbox(f, :multiple, class: "h-4 w-4")} + {label(f, :multiple, gettext("Multiple answers"), class: "text-sm font-medium")}
<%= if @live_action == :edit do %> - <%= link(gettext("Delete"), + {link(gettext("Delete"), to: "#", phx_click: "delete", phx_target: @myself, @@ -120,8 +116,8 @@ ) ], class: - "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-gradient-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" - ) %> + "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-linear-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" + )} <% end %>
diff --git a/lib/claper_web/live/quiz_live/quiz_component.html.heex b/lib/claper_web/live/quiz_live/quiz_component.html.heex index 0faf2c0..fa72d83 100644 --- a/lib/claper_web/live/quiz_live/quiz_component.html.heex +++ b/lib/claper_web/live/quiz_live/quiz_component.html.heex @@ -12,8 +12,6 @@ form={f} key={:title} name={gettext("Title")} - labelClass={if @dark, do: "text-white"} - fieldClass={if @dark, do: "bg-gray-700 text-white"} autofocus="true" required="true" /> @@ -33,7 +31,7 @@ if(i == 0, do: "rounded-tl-md") ]} > - <%= i + 1 %> + {i + 1} <% end %> <%= if Ecto.Changeset.get_field(@changeset, :quiz_questions) |> length() < 10 do %> @@ -43,7 +41,7 @@ class="text-xs px-3" phx-target={@myself} > - + <%= gettext("Add Question") %> + + {gettext("Add Question")} <% end %>
@@ -56,8 +54,6 @@

- <%= elem(Keyword.get(q.errors, :quiz_question_opts), 0) %> + {elem(Keyword.get(q.errors, :quiz_question_opts), 0)}

<% end %> @@ -78,8 +74,6 @@
<%= label(class: "mt-6 cursor-pointer flex items-center text-white rounded-md px-2.5 py-2.5 h-full #{if (o.source.changes[:is_correct] != nil && o.source.changes[:is_correct]) || (!Map.has_key?(o.source.changes, :is_correct) && o.source.data.is_correct), do: "bg-green-500", else: "bg-red-500"}") do %> - <%= checkbox(o, :is_correct, class: "hidden") %> + {checkbox(o, :is_correct, class: "hidden")} <%= if (o.source.changes[:is_correct] != nil && o.source.changes[:is_correct]) || (!Map.has_key?(o.source.changes, :is_correct) && o.source.data.is_correct) do %> 1 do %>
- <%= gettext("Delete") %> + {gettext("Delete")}
- + <%= gettext("Add answer") %> + + {gettext("Add answer")} <%= if Ecto.Changeset.get_field(@changeset, :quiz_questions) |> length() > 1 do %>
diff --git a/lib/claper_web/live/stat_live/index.html.heex b/lib/claper_web/live/stat_live/index.html.heex index 765cbfd..045ef74 100644 --- a/lib/claper_web/live/stat_live/index.html.heex +++ b/lib/claper_web/live/stat_live/index.html.heex @@ -2,7 +2,7 @@

- <%= @page_title %> + {@page_title}

- <%= gettext("Unique attendees") %> + {gettext("Unique attendees")}

- <%= @distinct_attendee_count %> + {@distinct_attendee_count} - <%= ngettext("attendee", "attendees", @distinct_attendee_count) %> + {ngettext("attendee", "attendees", @distinct_attendee_count)}

@@ -99,18 +99,18 @@

- <%= gettext("Messages") %> + {gettext("Messages")}

- <%= length(@posts) %> + {length(@posts)} - <%= ngettext( + {ngettext( "from %{count} people", "from %{count} peoples", @distinct_poster_count - ) %> + )}

@@ -136,11 +136,11 @@

- <%= gettext("Engagement rate") %> + {gettext("Engagement rate")}

-

<%= @engagement_rate %>%

+

{@engagement_rate}%

- <%= gettext("Interactions") %> + {gettext("Interactions")}

@@ -177,35 +177,35 @@ phx-value-tab="messages" class={"whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm #{if @current_tab == :messages, do: "border-primary-500 text-primary-600", else: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300"}"} > - <%= gettext("Messages") %> + {gettext("Messages")}
@@ -219,7 +219,7 @@ <% total = Enum.map(poll.poll_opts, fn e -> e.vote_count end) |> Enum.sum() %>
-

<%= poll.title %>

+

{poll.title}

<%= link to: ~p"/export/polls/#{poll.id}", class: "text-sm text-white bg-primary-500 hover:bg-primary-600 rounded-md px-3 py-1 flex items-center gap-1", method: :post, target: "_blank" do %> - <%= gettext("Export") %> (CSV) + {gettext("Export")} (CSV) <% end %>
@@ -252,14 +252,14 @@ >
- <%= opt.content %> + {opt.content}
- <%= percentage %>% (<%= opt.vote_count %>) + {percentage}% ({opt.vote_count})
<% end %> @@ -269,7 +269,7 @@
<% end %> <% else %> -

<%= gettext("No poll has been created") %>

+

{gettext("No poll has been created")}

<% end %>
<% :forms -> %> @@ -278,7 +278,7 @@ <%= for form <- @event.presentation_file.forms do %>
- <%= form.title %> + {form.title} <%= if length(form.form_submits) > 0 do %> @@ -295,14 +295,14 @@ > - <%= gettext("Export") %> (CSV) + {gettext("Export")} (CSV) <% end %> <% end %>
<%= if length(form.form_submits) == 0 do %>

- <%= gettext("No form submission has been sent") %> + {gettext("No form submission has been sent")}

<% end %> @@ -325,7 +325,7 @@
<%= for res <- fs.response do %> -

<%= elem(res, 0) %>: <%= elem(res, 1) %>

+

{elem(res, 0)}: {elem(res, 1)}

<% end %>
@@ -335,7 +335,7 @@
<% end %> <% else %> -

<%= gettext("No form has been created") %>

+

{gettext("No form has been created")}

<% end %> <% :web_content -> %> @@ -343,7 +343,7 @@ <%= if length(@event.presentation_file.embeds) > 0 do %> <%= for embed <- @event.presentation_file.embeds do %> - <%= embed.title %> + {embed.title}
<.live_component @@ -356,7 +356,7 @@ <% end %> <% else %>

- <%= gettext("No web content has been created") %> + {gettext("No web content has been created")}

<% end %>
@@ -377,13 +377,13 @@ > - <%= gettext("Export") %> (CSV) + {gettext("Export")} (CSV) <% end %> <% end %> <%= if length(@posts) == 0 do %> -

<%= gettext("No messages has been sent") %>

+

{gettext("No messages has been sent")}

<% end %>
@@ -405,7 +405,7 @@
-

<%= quiz.title %>

+

{quiz.title}

<%= link to: ~p"/export/quizzes/#{quiz.id}", class: "text-sm text-white bg-primary-500 hover:bg-primary-600 rounded-md px-3 py-1 flex items-center gap-1", method: :post, target: "_blank" do %> - <%= gettext("Export") %> (CSV) + {gettext("Export")} (CSV) <% end %>

- <%= gettext("Average score") %>: + {gettext("Average score")}: - <%= Claper.Quizzes.calculate_average_score(quiz.id) %>/<%= length( + {Claper.Quizzes.calculate_average_score(quiz.id)}/{length( quiz.quiz_questions - ) %> + )}

- <%= gettext("Total submissions") %>: + {gettext("Total submissions")}: - <%= Claper.Quizzes.get_submission_count(quiz.id) %> + {Claper.Quizzes.get_submission_count(quiz.id)}

@@ -443,7 +443,7 @@ <%= for {question, _idx} <- Enum.with_index(quiz.quiz_questions) do %>

- <%= question.content %> + {question.content}

<%= for opt <- question.quiz_question_opts do %> @@ -457,10 +457,10 @@
<% end %> - <%= opt.content %> + {opt.content}
- <%= opt.percentage %>% (<%= opt.response_count %>) + {opt.percentage}% ({opt.response_count})
@@ -473,7 +473,7 @@ <% end %>
<% else %> -

<%= gettext("No quiz has been created") %>

+

{gettext("No quiz has been created")}

<% end %> <% end %> diff --git a/lib/claper_web/live/user_settings_live/show.html.heex b/lib/claper_web/live/user_settings_live/show.html.heex index e9f59f9..3b21e30 100644 --- a/lib/claper_web/live/user_settings_live/show.html.heex +++ b/lib/claper_web/live/user_settings_live/show.html.heex @@ -2,7 +2,7 @@

- <%= gettext("My account") %> + {gettext("My account")}

@@ -26,7 +26,7 @@ id="update_email" class="mt-5 md:flex md:items-end" > - <%= hidden_input(f, :action, name: "action", value: "update_email") %> + {hidden_input(f, :action, name: "action", value: "update_email")} - <%= submit(gettext("Save"), + {submit(gettext("Save"), phx_disable_with: "Saving...", class: "mt-2 w-full h-14 inline-flex transition-all items-center justify-center px-4 py-2 shadow-sm font-medium rounded-md text-white bg-black hover:bg-primary-500 md:mt-0 md:ml-3 md:w-auto md:text-sm" - ) %> + )}
@@ -62,7 +62,7 @@ id="update_password" class="mt-5 md:flex md:items-end gap-x-2" > - <%= hidden_input(f, :action, name: "action", value: "update_password") %> + {hidden_input(f, :action, name: "action", value: "update_password")} - <%= submit(gettext("Save"), + {submit(gettext("Save"), phx_disable_with: "Saving...", class: "mt-2 w-full h-14 inline-flex transition-all items-center justify-center px-4 py-2 shadow-sm font-medium rounded-md text-white bg-black hover:bg-primary-500 md:mt-0 md:ml-3 md:w-auto md:text-sm" - ) %> + )} @@ -104,7 +104,7 @@ id="set_password" class="mt-5 md:flex md:items-end gap-x-2" > - <%= hidden_input(f, :action, name: "action", value: "set_password") %> + {hidden_input(f, :action, name: "action", value: "set_password")} - <%= submit(gettext("Save"), + {submit(gettext("Save"), phx_disable_with: "Saving...", class: "mt-2 w-full h-14 inline-flex transition-all items-center justify-center px-4 py-2 shadow-sm font-medium rounded-md text-white bg-black hover:bg-primary-500 md:mt-0 md:ml-3 md:w-auto md:text-sm" - ) %> + )} <% end %> -
+

- <%= gettext("Personal informations") %> + {gettext("Personal informations")}

- <%= gettext("Your personal informations to access your account") %> + {gettext("Your personal informations to access your account")}

- <%= gettext("Email address") %> + {gettext("Email address")}
- <%= @current_user.email %> - + {@current_user.email} + <.link patch={~p"/users/settings/edit/email"} class="rounded-md font-medium text-purple-600 hover:text-purple-500" > - <%= gettext("Change") %> + {gettext("Change")}
- <%= gettext("Password") %> + {gettext("Password")}
- ******** - + ******** + <.link patch={~p"/users/settings/edit/password"} class="rounded-md font-medium text-purple-600 hover:text-purple-500" > - <%= gettext("Change") %> + {gettext("Change")}
- <%= gettext("Accounts linked") %> + {gettext("Accounts linked")}
<%= for account <- @oidc_accounts do %>
- - <%= account.provider %> + + {account.provider}
- <%= account.organization %> + {account.organization}
@@ -208,7 +208,7 @@ data-confirm={gettext("Are you sure you want to unlink this account?")} class="font-medium text-red-600 hover:text-red-500" > - <%= gettext("Unlink") %> + {gettext("Unlink")}
@@ -216,17 +216,17 @@ <%= for account <- @lti_accounts do %>
- - LMS #<%= account.registration_id %> + + LMS #{account.registration_id} - +
@@ -238,29 +238,42 @@

- <%= gettext("Preferences") %> + {gettext("Preferences")}

- <%= gettext("Customize your account") %> + {gettext("Customize your account")}

<.form :let={f} for={@preferences_changeset} phx-change="save"> - <%= hidden_input(f, :action, name: "action", value: "update_preferences") %> + {hidden_input(f, :action, name: "action", value: "update_preferences")} Enum.filter(fn {_name, code} -> + code in Application.get_env(:claper, :languages, [ + "en", + "fr", + "es", + "it", + "de" + ]) + end) + } key={:locale} name={gettext("Language")} /> @@ -272,23 +285,23 @@

- <%= gettext("Danger zone") %> + {gettext("Danger zone")}

- <%= gettext("Be careful, these actions are irreversible") %> + {gettext("Be careful, these actions are irreversible")}

- <%= link(gettext("Delete account"), + {link(gettext("Delete account"), to: ~p"/users/register/delete", method: :delete, "data-confirm": gettext("All your events and files will be permanently deleted, are you sure?"), class: - "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-none focus:shadow-outline bg-gradient-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-200 bg-pos-0 hover:bg-pos-100 transition-all duration-500" - ) %> + "w-full lg:w-auto px-6 text-center text-white py-2 rounded-md tracking-wide font-bold focus:outline-hidden focus:shadow-outline bg-linear-to-tl from-supporting-red-600 to-supporting-red-400 bg-size-[200%_200%] bg-position-[0%_0%] hover:bg-position-[100%_100%] transition-all duration-500" + )}
diff --git a/lib/claper_web/notifiers/leader_notifier.ex b/lib/claper_web/notifiers/leader_notifier.ex index 50fc8aa..5c10b6b 100644 --- a/lib/claper_web/notifiers/leader_notifier.ex +++ b/lib/claper_web/notifiers/leader_notifier.ex @@ -1,6 +1,6 @@ defmodule ClaperWeb.Notifiers.LeaderNotifier do use Phoenix.Swoosh, view: ClaperWeb.LeaderNotifierView, layout: {ClaperWeb.LayoutView, :email} - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext def event_invitation(event_name, email, url) do new() diff --git a/lib/claper_web/notifiers/user_notifier.ex b/lib/claper_web/notifiers/user_notifier.ex index 1c549bb..c256887 100644 --- a/lib/claper_web/notifiers/user_notifier.ex +++ b/lib/claper_web/notifiers/user_notifier.ex @@ -1,6 +1,6 @@ defmodule ClaperWeb.Notifiers.UserNotifier do use Phoenix.Swoosh, view: ClaperWeb.UserNotifierView, layout: {ClaperWeb.LayoutView, :email} - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext def magic(email, url) do new() @@ -24,15 +24,37 @@ defmodule ClaperWeb.Notifiers.UserNotifier do |> render_body("welcome.html", %{email: email}) end - def update_email(user, url) do + def update_email(new_email, url) do + new() + |> to(new_email) + |> from( + {Application.get_env(:claper, :mail) |> Keyword.get(:from_name), + Application.get_env(:claper, :mail) |> Keyword.get(:from)} + ) + |> subject(gettext("Update email instructions")) + |> render_body("change.html", %{url: url}) + end + + def confirm(user, url) do new() |> to(user.email) |> from( {Application.get_env(:claper, :mail) |> Keyword.get(:from_name), Application.get_env(:claper, :mail) |> Keyword.get(:from)} ) - |> subject(gettext("Update email instructions")) - |> render_body("change.html", %{user: user, url: url}) + |> subject(gettext("Confirmation instructions")) + |> render_body("confirm.html", %{user: user, url: url}) + end + + def reset(user, url) do + new() + |> to(user.email) + |> from( + {Application.get_env(:claper, :mail) |> Keyword.get(:from_name), + Application.get_env(:claper, :mail) |> Keyword.get(:from)} + ) + |> subject(gettext("Reset password instructions")) + |> render_body("reset.html", %{user: user, url: url}) end def confirm(user, url) do diff --git a/lib/claper_web/plugs/admin_required_plug.ex b/lib/claper_web/plugs/admin_required_plug.ex new file mode 100644 index 0000000..c338bdb --- /dev/null +++ b/lib/claper_web/plugs/admin_required_plug.ex @@ -0,0 +1,33 @@ +defmodule ClaperWeb.Plugs.AdminRequiredPlug do + @moduledoc """ + Plug to ensure that the current user has admin role. + + This plug should be used after the authentication plug to ensure + that only admin users can access certain routes. + """ + + import Plug.Conn + import Phoenix.Controller + + use Phoenix.VerifiedRoutes, + endpoint: ClaperWeb.Endpoint, + router: ClaperWeb.Router, + statics: ClaperWeb.static_paths() + + alias Claper.Accounts + + def init(opts), do: opts + + def call(conn, _opts) do + user = conn.assigns[:current_user] + + if user && Accounts.user_has_role?(user, "admin") do + conn + else + conn + |> put_flash(:error, "You must be an admin to access this page.") + |> redirect(to: ~p"/events") + |> halt() + end + end +end diff --git a/lib/claper_web/router.ex b/lib/claper_web/router.ex index 7d06ba0..bd049f3 100644 --- a/lib/claper_web/router.ex +++ b/lib/claper_web/router.ex @@ -14,6 +14,10 @@ defmodule ClaperWeb.Router do plug(ClaperWeb.Plugs.Locale) end + pipeline :admin_required do + plug(ClaperWeb.Plugs.AdminRequiredPlug) + end + pipeline :lti do plug(:accepts, ["html", "json"]) plug(:put_root_layout, html: {ClaperWeb.LayoutView, :root}) @@ -165,4 +169,28 @@ defmodule ClaperWeb.Router do delete("/users/log_out", UserSessionController, :delete) end + + # Admin panel routes - LiveView implementation + live_session :admin, root_layout: {ClaperWeb.LayoutView, :admin} do + scope "/admin", ClaperWeb.AdminLive do + pipe_through [:browser, :require_authenticated_user, :admin_required] + + live "/", DashboardLive, :index + + live "/users", UserLive, :index + live "/users/new", UserLive, :new + live "/users/:id/edit", UserLive, :edit + live "/users/:id", UserLive, :show + + live "/events", EventLive, :index + live "/events/new", EventLive, :new + live "/events/:id/edit", EventLive, :edit + live "/events/:id", EventLive, :show + + live "/oidc_providers", OidcProviderLive, :index + live "/oidc_providers/new", OidcProviderLive, :new + live "/oidc_providers/:id/edit", OidcProviderLive, :edit + live "/oidc_providers/:id", OidcProviderLive, :show + end + end end diff --git a/lib/claper_web/templates/error/404.html.heex b/lib/claper_web/templates/error/404.html.heex index a6cfd75..c5e7b50 100644 --- a/lib/claper_web/templates/error/404.html.heex +++ b/lib/claper_web/templates/error/404.html.heex @@ -4,7 +4,7 @@ - <%= csrf_meta_tag() %> + {csrf_meta_tag()} Not found - Claper @@ -28,12 +28,12 @@

- <%= gettext("Oops, page doesn't exist.") %> + {gettext("Oops, page doesn't exist.")}

diff --git a/lib/claper_web/templates/error/500.html.heex b/lib/claper_web/templates/error/500.html.heex index 6162aa6..0315d1b 100644 --- a/lib/claper_web/templates/error/500.html.heex +++ b/lib/claper_web/templates/error/500.html.heex @@ -4,7 +4,7 @@ - <%= csrf_meta_tag() %> + {csrf_meta_tag()} Not found - Claper @@ -28,13 +28,13 @@

- <%= gettext("The site is under maintenance, we'll be back very soon!") %> + {gettext("The site is under maintenance, we'll be back very soon!")}

diff --git a/lib/claper_web/templates/error/csrf_error.html.heex b/lib/claper_web/templates/error/csrf_error.html.heex index bebb46a..7fb1f80 100644 --- a/lib/claper_web/templates/error/csrf_error.html.heex +++ b/lib/claper_web/templates/error/csrf_error.html.heex @@ -2,31 +2,31 @@

- <%= gettext("CSRF Verification Failed") %> + {gettext("CSRF Verification Failed")}

- <%= gettext("A required security token was not found or was invalid.") %> + {gettext("A required security token was not found or was invalid.")}

- <%= gettext("If you're continually seeing this issue, try the following:") %> + {gettext("If you're continually seeing this issue, try the following:")}

    -
  1. <%= gettext("Clear cookies (at least for Claper domain)") %>
  2. -
  3. <%= gettext("Reload the page you're trying to access (don't re-submit data)") %>
  4. -
  5. <%= gettext("Try logging in again") %>
  6. -
  7. <%= gettext("Ensure the URL does not contain an extra \"/\" anywhere") %>
  8. +
  9. {gettext("Clear cookies (at least for Claper domain)")}
  10. +
  11. {gettext("Reload the page you're trying to access (don't re-submit data)")}
  12. +
  13. {gettext("Try logging in again")}
  14. +
  15. {gettext("Ensure the URL does not contain an extra \"/\" anywhere")}

- <%= gettext("If the problem persists, please contact support.") %> + {gettext("If the problem persists, please contact support.")}

- <%= link(gettext("Back to Login"), + {link(gettext("Back to Login"), to: ~p"/users/log_in", class: "text-blue underline font-semibold transition duration-300 ease-in-out" - ) %> + )}
diff --git a/lib/claper_web/templates/layout/_avatar.html.heex b/lib/claper_web/templates/layout/_avatar.html.heex index 917ca9e..83f05de 100644 --- a/lib/claper_web/templates/layout/_avatar.html.heex +++ b/lib/claper_web/templates/layout/_avatar.html.heex @@ -4,9 +4,9 @@ <% else %>
<%= if @user.full_name do %> - <%= with [first | _] <- String.codepoints(@user.full_name), do: String.capitalize(first) %> + {with [first | _] <- String.codepoints(@user.full_name), do: String.capitalize(first)} <% else %> - <%= with [first | _] <- String.codepoints(@user.email), do: String.capitalize(first) %> + {with [first | _] <- String.codepoints(@user.email), do: String.capitalize(first)} <% end %>
<% end %> diff --git a/lib/claper_web/templates/layout/_profile_dropdown.html.heex b/lib/claper_web/templates/layout/_profile_dropdown.html.heex index c20e3c5..c2123f1 100644 --- a/lib/claper_web/templates/layout/_profile_dropdown.html.heex +++ b/lib/claper_web/templates/layout/_profile_dropdown.html.heex @@ -20,7 +20,7 @@ aria-haspopup="true" > Open user menu - +
diff --git a/lib/claper_web/templates/layout/_user_menu.html.heex b/lib/claper_web/templates/layout/_user_menu.html.heex index 925e439..70c9a71 100644 --- a/lib/claper_web/templates/layout/_user_menu.html.heex +++ b/lib/claper_web/templates/layout/_user_menu.html.heex @@ -3,24 +3,31 @@ href={~p"/users/settings"} class="text-gray-700 block px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900" > - <%= gettext("My account") %> + {gettext("My account")} + + + {gettext("Admin")} - <%= gettext("Documentation") %> + {gettext("Documentation")}
- <%= link(gettext("Logout"), + {link(gettext("Logout"), to: ~p"/users/log_out", method: :delete, class: "text-gray-700 block px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900" - ) %> + )}

- Version <%= Application.spec(:claper, :vsn) %> + Version {Application.spec(:claper, :vsn)}

diff --git a/lib/claper_web/templates/layout/admin.html.heex b/lib/claper_web/templates/layout/admin.html.heex new file mode 100644 index 0000000..5385685 --- /dev/null +++ b/lib/claper_web/templates/layout/admin.html.heex @@ -0,0 +1,316 @@ + + + + + + + {csrf_meta_tag()} + <.live_title suffix=" · Claper Admin"> + {assigns[:page_title] || "Admin Dashboard"} + + + + + + + +
+ + +
+ + + + +
+ +
+ <%= if Phoenix.Flash.get(@flash, :info) do %> +
+ + + + + {Phoenix.Flash.get(@flash, :info)} + +
+ <% end %> + + <%= if Phoenix.Flash.get(@flash, :success) do %> +
+ + + + {Phoenix.Flash.get(@flash, :success)} + +
+ <% end %> + + <%= if Phoenix.Flash.get(@flash, :warning) do %> +
+ + + + {Phoenix.Flash.get(@flash, :warning)} + +
+ <% end %> + + <%= if Phoenix.Flash.get(@flash, :error) do %> +
+ + + + {Phoenix.Flash.get(@flash, :error)} + +
+ <% end %> +
+
+ {@inner_content} +
+
+
+ + +
+ + +
+
+ + + + + diff --git a/lib/claper_web/templates/layout/app.html.heex b/lib/claper_web/templates/layout/app.html.heex index aa07106..5e15891 100644 --- a/lib/claper_web/templates/layout/app.html.heex +++ b/lib/claper_web/templates/layout/app.html.heex @@ -8,4 +8,4 @@ <% end %>
-<%= @inner_content %> +{@inner_content} diff --git a/lib/claper_web/templates/layout/email.html.heex b/lib/claper_web/templates/layout/email.html.heex index 7754e14..1746023 100644 --- a/lib/claper_web/templates/layout/email.html.heex +++ b/lib/claper_web/templates/layout/email.html.heex @@ -58,7 +58,7 @@   - <%= @inner_content %> + {@inner_content} diff --git a/lib/claper_web/templates/layout/live.html.heex b/lib/claper_web/templates/layout/live.html.heex index 3b69ea9..5e15891 100644 --- a/lib/claper_web/templates/layout/live.html.heex +++ b/lib/claper_web/templates/layout/live.html.heex @@ -1,11 +1,11 @@
- <%= if live_flash(@flash, :info) do %> - + <%= if Phoenix.Flash.get(@flash, :info) do %> + <% end %> - <%= if live_flash(@flash, :error) do %> - + <%= if Phoenix.Flash.get(@flash, :error) do %> + <% end %>
-<%= @inner_content %> +{@inner_content} diff --git a/lib/claper_web/templates/layout/root.html.heex b/lib/claper_web/templates/layout/root.html.heex index 9a903ea..71fb97d 100644 --- a/lib/claper_web/templates/layout/root.html.heex +++ b/lib/claper_web/templates/layout/root.html.heex @@ -4,11 +4,16 @@ - <%= csrf_meta_tag() %> - <.live_title suffix=" · Claper" )><%= assigns[:page_title] || "Claper" %> + {csrf_meta_tag()} + <.live_title suffix=" · Claper" )>{assigns[:page_title] || "Claper"} + @@ -17,7 +22,7 @@
- <%= @inner_content %> + {@inner_content}
diff --git a/lib/claper_web/templates/layout/user.html.heex b/lib/claper_web/templates/layout/user.html.heex index 37f0a0b..5106cfe 100644 --- a/lib/claper_web/templates/layout/user.html.heex +++ b/lib/claper_web/templates/layout/user.html.heex @@ -4,8 +4,8 @@ - <%= csrf_meta_tag() %> - <.live_title suffix=" · Claper" )><%= assigns[:page_title] || "Claper" %> + {csrf_meta_tag()} + <.live_title suffix=" · Claper" )>{assigns[:page_title] || "Claper"} @@ -16,9 +16,9 @@
- <%= render("_profile_dropdown.html", user: @current_user, conn: @conn) %> + {render("_profile_dropdown.html", user: @current_user, conn: @conn)}
- <%= @inner_content %> + {@inner_content}
diff --git a/lib/claper_web/templates/leader_notifier/invitation.html.heex b/lib/claper_web/templates/leader_notifier/invitation.html.heex index c6699f5..d821fd8 100644 --- a/lib/claper_web/templates/leader_notifier/invitation.html.heex +++ b/lib/claper_web/templates/leader_notifier/invitation.html.heex @@ -14,25 +14,25 @@

- <%= gettext("You have been invited") %> + {gettext("You have been invited")}

- <%= gettext("Someone invited you to manage the event: %{name}", name: @event_name) %> + {gettext("Someone invited you to manage the event: %{name}", name: @event_name)}

- <%= gettext( + {gettext( "To accept the invitation, please login or create an account with this email: %{email}", email: @leader_email - ) %> + )}

- <%= gettext("Login or create account") %> + {gettext("Login or create account")} @@ -42,11 +42,11 @@

- <%= gettext( + {gettext( "If you’re having trouble with the button above, copy and paste the URL below into your web browser" - ) %>. + )}.

-

<%= @url %>

+

{@url}

diff --git a/lib/claper_web/templates/lti/launch/error.html.heex b/lib/claper_web/templates/lti/launch/error.html.heex index 6732aee..5827f57 100644 --- a/lib/claper_web/templates/lti/launch/error.html.heex +++ b/lib/claper_web/templates/lti/launch/error.html.heex @@ -2,19 +2,19 @@

- <%= gettext("Oops") %> + {gettext("Oops")}

- <%= gettext("You cannot perform this action") %> + {gettext("You cannot perform this action")}

<%= @msg %>
diff --git a/lib/claper_web/templates/lti/registration/new.html.heex b/lib/claper_web/templates/lti/registration/new.html.heex index 4bed03f..11f5b33 100644 --- a/lib/claper_web/templates/lti/registration/new.html.heex +++ b/lib/claper_web/templates/lti/registration/new.html.heex @@ -21,10 +21,10 @@

- <%= gettext("Bring Claper to your LMS") %> + {gettext("Bring Claper to your LMS")}

- <%= gettext("Register your platform") %> + {gettext("Register your platform")}

@@ -35,12 +35,12 @@

- <%= gettext("You must login to continue") %> + {gettext("You must login to continue")}

diff --git a/lib/claper_web/templates/lti/registration/success.html.heex b/lib/claper_web/templates/lti/registration/success.html.heex index e753eca..8a5e65b 100644 --- a/lib/claper_web/templates/lti/registration/success.html.heex +++ b/lib/claper_web/templates/lti/registration/success.html.heex @@ -2,28 +2,28 @@

- <%= gettext("Registration completed") %> + {gettext("Registration completed")}

- <%= gettext("Your next steps") %>: + {gettext("Your next steps")}:

    -
  1. <%= gettext("Activate the tool in your LMS") %>
  2. -
  3. <%= gettext("Configure it to be opened in a new window") %>
  4. +
  5. {gettext("Activate the tool in your LMS")}
  6. +
  7. {gettext("Configure it to be opened in a new window")}
  8. - <%= gettext("Check the permissions to share name and email of users") %> + {gettext("Check the permissions to share name and email of users")}
diff --git a/lib/claper_web/templates/page/user_confirmation/edit.html.heex b/lib/claper_web/templates/page/user_confirmation/edit.html.heex index 16087e6..f776bab 100644 --- a/lib/claper_web/templates/page/user_confirmation/edit.html.heex +++ b/lib/claper_web/templates/page/user_confirmation/edit.html.heex @@ -2,12 +2,12 @@ <.form :let={_f} for={:user} action={~p"/users/confirm/#{@token}"}>
- <%= submit("Confirm my account") %> + {submit("Confirm my account")}

- <%= link("Register", to: ~p"/users/register") %> | <%= link("Log in", + {link("Register", to: ~p"/users/register")} | {link("Log in", to: ~p"/users/log_in" - ) %> + )}

diff --git a/lib/claper_web/templates/page/user_confirmation/new.html.heex b/lib/claper_web/templates/page/user_confirmation/new.html.heex index cf4fbb0..510ca1c 100644 --- a/lib/claper_web/templates/page/user_confirmation/new.html.heex +++ b/lib/claper_web/templates/page/user_confirmation/new.html.heex @@ -1,16 +1,16 @@

Resend confirmation instructions

<.form :let={f} for={:user} action={~p"/users/confirm"}> - <%= label(f, :email) %> - <%= email_input(f, :email, required: true) %> + {label(f, :email)} + {email_input(f, :email, required: true)}
- <%= submit("Resend confirmation instructions") %> + {submit("Resend confirmation instructions")}

- <%= link("Register", to: ~p"/users/register") %> | <%= link("Log in", + {link("Register", to: ~p"/users/register")} | {link("Log in", to: ~p"/users/log_in" - ) %> + )}

diff --git a/lib/claper_web/templates/user_confirmation/new.html.heex b/lib/claper_web/templates/user_confirmation/new.html.heex index 46f92e4..b69d53e 100644 --- a/lib/claper_web/templates/user_confirmation/new.html.heex +++ b/lib/claper_web/templates/user_confirmation/new.html.heex @@ -1,16 +1,16 @@

Resend confirmation instructions

<%= form_for :user, ~p"/users/confirm", fn f -> %> - <%= label(f, :email) %> - <%= email_input(f, :email, required: true) %> + {label(f, :email)} + {email_input(f, :email, required: true)}
- <%= submit("Resend confirmation instructions") %> + {submit("Resend confirmation instructions")}
<% end %>

- <%= link("Register", to: ~p"/users/register") %> | <%= link("Log in", + {link("Register", to: ~p"/users/register")} | {link("Log in", to: ~p"/users/log_in" - ) %> + )}

diff --git a/lib/claper_web/templates/user_notifier/change.html.heex b/lib/claper_web/templates/user_notifier/change.html.heex index 4e5b3f5..1d59672 100644 --- a/lib/claper_web/templates/user_notifier/change.html.heex +++ b/lib/claper_web/templates/user_notifier/change.html.heex @@ -14,22 +14,22 @@

- <%= gettext("Confirm email") %> + {gettext("Confirm email change")}

- <%= gettext("You can change your email by visiting the URL below") %> + {gettext("You can confirm your email change by visiting the URL below")}

- <%= gettext("CONFIRM EMAIL") %> + {gettext("CONFIRM EMAIL")}

- <%= gettext("If you didn't create an account with us, please ignore this.") %> + {gettext("If you didn't request an email change, please ignore this.")}

@@ -39,11 +39,11 @@

- <%= gettext( + {gettext( "If you’re having trouble with the button above, copy and paste the URL below into your web browser" - ) %>. + )}.

-

<%= @url %>

+

{@url}

diff --git a/lib/claper_web/templates/user_notifier/confirm.html.heex b/lib/claper_web/templates/user_notifier/confirm.html.heex index 749a792..49e31a4 100644 --- a/lib/claper_web/templates/user_notifier/confirm.html.heex +++ b/lib/claper_web/templates/user_notifier/confirm.html.heex @@ -14,22 +14,22 @@

- <%= gettext("Confirm account") %> + {gettext("Confirm account")}

- <%= gettext("You can confirm your account by visiting the URL below") %> + {gettext("You can confirm your account by visiting the URL below")}

- <%= gettext("CONFIRM ACCOUNT") %> + {gettext("CONFIRM ACCOUNT")}

- <%= gettext("If you didn't create an account with us, please ignore this.") %> + {gettext("If you didn't create an account with us, please ignore this.")}

@@ -39,11 +39,11 @@

- <%= gettext( + {gettext( "If you’re having trouble with the button above, copy and paste the URL below into your web browser" - ) %>. + )}.

-

<%= @url %>

+

{@url}

diff --git a/lib/claper_web/templates/user_notifier/magic.html.heex b/lib/claper_web/templates/user_notifier/magic.html.heex index 8ead688..7fc359f 100644 --- a/lib/claper_web/templates/user_notifier/magic.html.heex +++ b/lib/claper_web/templates/user_notifier/magic.html.heex @@ -14,22 +14,22 @@

- <%= gettext("Connect to Claper") %> + {gettext("Connect to Claper")}

- <%= gettext("You can log into your account by clicking here.") %> + {gettext("You can log into your account by clicking here.")}

- <%= gettext("ACCESS TO MY ACCOUNT") %> + {gettext("ACCESS TO MY ACCOUNT")}

- <%= gettext("If you didn't create an account with us, please ignore this.") %> + {gettext("If you didn't create an account with us, please ignore this.")}

@@ -39,11 +39,11 @@

- <%= gettext( + {gettext( "If you’re having trouble with the button above, copy and paste the URL below into your web browser" - ) %>. + )}.

-

<%= @url %>

+

{@url}

diff --git a/lib/claper_web/templates/user_notifier/reset.html.heex b/lib/claper_web/templates/user_notifier/reset.html.heex index 4123497..5bb968c 100644 --- a/lib/claper_web/templates/user_notifier/reset.html.heex +++ b/lib/claper_web/templates/user_notifier/reset.html.heex @@ -14,22 +14,22 @@

- <%= gettext("Reset password") %> + {gettext("Reset password")}

- <%= gettext("You can reset your password by visiting the URL below") %> + {gettext("You can reset your password by visiting the URL below")}

- <%= gettext("RESET PASSWORD") %> + {gettext("RESET PASSWORD")}

- <%= gettext("If you didn't create an account with us, please ignore this.") %> + {gettext("If you didn't create an account with us, please ignore this.")}

@@ -39,11 +39,11 @@

- <%= gettext( + {gettext( "If you’re having trouble with the button above, copy and paste the URL below into your web browser" - ) %>. + )}.

-

<%= @url %>

+

{@url}

diff --git a/lib/claper_web/templates/user_notifier/welcome.html.heex b/lib/claper_web/templates/user_notifier/welcome.html.heex index 9f04aaf..14f1906 100644 --- a/lib/claper_web/templates/user_notifier/welcome.html.heex +++ b/lib/claper_web/templates/user_notifier/welcome.html.heex @@ -14,59 +14,59 @@

- <%= gettext("Welcome !") %> + {gettext("Welcome !")}

- <%= gettext( + {gettext( "Congrats! You've taken the first step to improving your presentations. Here are the next steps to create step up your presentations with Claper:" - ) %> + )}

  1. - <%= raw( + {raw( gettext( "Export your current presentation to PDF from your favorite slide presentation software (PowerPoint, etc)" ) - ) %> + )}
  2. - <%= raw( + {raw( gettext( "Click on the create button on your dashboard" ) - ) %> + )}
  3. - <%= raw( + {raw( gettext( "Choose a name for your event, a code for your attendees to join and dates when your attendees could start interacting" ) - ) %> + )}
  4. - <%= raw( + {raw( gettext( "Wait few minutes for your file to be processed" ) - ) %> + )}
  5. - <%= raw( + {raw( gettext( "Click on Present/Customize to add interaction on your slides" ) - ) %> + )}
  6. - <%= raw( + {raw( gettext( "Click Start to open your presentation and move the window on the big screen" ) - ) %> + )}
  7. -
  8. <%= gettext("Enjoy ! ✨") %>
  9. +
  10. {gettext("Enjoy ! ✨")}
diff --git a/lib/claper_web/templates/user_registration/confirm.html.heex b/lib/claper_web/templates/user_registration/confirm.html.heex index eea8f68..9d04dba 100644 --- a/lib/claper_web/templates/user_registration/confirm.html.heex +++ b/lib/claper_web/templates/user_registration/confirm.html.heex @@ -10,23 +10,23 @@

<%= if @conn.query_params["retry"] do %> - <%= gettext("We already sent you an email to login, please retry in 5 minutes.") %> + {gettext("We already sent you an email to login, please retry in 5 minutes.")} <% else %> <%= if @conn.query_params["email"] do %> - <%= gettext("We sent you an email at") <> + {gettext("We sent you an email at") <> " #{@conn.query_params["email"]}" <> - gettext(", click on the provided link to connect (check your spam !)") %> + gettext(", click on the provided link to connect (check your spam !)")} <% else %> - <%= gettext( + {gettext( "We sent you an email, click on the provided link to connect (check your spam !)" - ) %> + )} <% end %> <% end %>

<.link href={~p"/"} class="text-sm text-white underline"> - <%= gettext("back to the home page") %> + {gettext("back to the home page")}
diff --git a/lib/claper_web/templates/user_registration/new.html.heex b/lib/claper_web/templates/user_registration/new.html.heex index 478c954..a913231 100644 --- a/lib/claper_web/templates/user_registration/new.html.heex +++ b/lib/claper_web/templates/user_registration/new.html.heex @@ -9,7 +9,7 @@

- <%= gettext("Join the Claper experience") %> + {gettext("Join the Claper experience")}

@@ -41,9 +41,9 @@
diff --git a/lib/claper_web/templates/user_reset_password/edit.html.heex b/lib/claper_web/templates/user_reset_password/edit.html.heex index 4c59a67..56c11dd 100644 --- a/lib/claper_web/templates/user_reset_password/edit.html.heex +++ b/lib/claper_web/templates/user_reset_password/edit.html.heex @@ -9,7 +9,7 @@

- <%= gettext("Reset your password") %> + {gettext("Reset your password")}

@@ -46,9 +46,9 @@
diff --git a/lib/claper_web/templates/user_reset_password/new.html.heex b/lib/claper_web/templates/user_reset_password/new.html.heex index 41e79db..6a94dad 100644 --- a/lib/claper_web/templates/user_reset_password/new.html.heex +++ b/lib/claper_web/templates/user_reset_password/new.html.heex @@ -9,7 +9,7 @@

- <%= gettext("Reset your password") %> + {gettext("Reset your password")}

@@ -31,9 +31,9 @@
diff --git a/lib/claper_web/templates/user_session/new.html.heex b/lib/claper_web/templates/user_session/new.html.heex index a4830dd..47520ac 100644 --- a/lib/claper_web/templates/user_session/new.html.heex +++ b/lib/claper_web/templates/user_session/new.html.heex @@ -19,10 +19,10 @@

- <%= gettext("It's time to empower your presentations.") %> + {gettext("It's time to empower your presentations.")}

- <%= gettext("Connect to your account") %> + {gettext("Connect to your account")}

@@ -57,9 +57,9 @@
@@ -68,23 +68,23 @@ <%= link( to: ~p"/users/oidc", class: - "w-full flex justify-center items-center gap-x-2 py-2 px-4 rounded-md shadow-sm text-sm font-medium text-white border-2 border-secondary-500 hover:bg-secondary-500 hover:bg-opacity-40" + "w-full flex justify-center items-center gap-x-2 py-2 px-4 rounded-md shadow-sm text-sm font-medium text-white border-2 border-secondary-500 hover:bg-secondary-500/40" ) do %> - <%= gettext("Login with %{provider}", provider: @oidc_provider_name) %> + {gettext("Login with %{provider}", provider: @oidc_provider_name)} <% end %>
- <%= link(gettext("Forgot your password?"), + {link(gettext("Forgot your password?"), to: ~p"/users/reset_password", class: "text-white text-sm text-center" - ) %> + )} <%= if Application.get_env(:claper, :enable_account_creation) do %> - <%= link(gettext("Create account"), + {link(gettext("Create account"), to: ~p"/users/register", class: "text-white text-sm text-center" - ) %> + )} <% end %>
diff --git a/lib/claper_web/validators/admin_form_validator.ex b/lib/claper_web/validators/admin_form_validator.ex new file mode 100644 index 0000000..d4f407c --- /dev/null +++ b/lib/claper_web/validators/admin_form_validator.ex @@ -0,0 +1,122 @@ +defmodule ClaperWeb.Validators.AdminFormValidator do + @moduledoc """ + Provides validation functions for admin panel forms. + + This module contains helper functions to validate input data + for admin forms before processing, providing consistent validation + across the admin panel. + """ + + @doc """ + Validates OIDC provider data. + + Returns {:ok, validated_params} or {:error, errors} + """ + def validate_oidc_provider(params) do + errors = [] + + errors = + if String.trim(params["name"]) == "" do + [{:name, "Name cannot be blank"} | errors] + else + errors + end + + errors = + if valid_url?(params["issuer"]) do + errors + else + [{:issuer, "Issuer must be a valid URL"} | errors] + end + + errors = + if String.trim(params["client_id"]) == "" do + [{:client_id, "Client ID cannot be blank"} | errors] + else + errors + end + + errors = + if String.trim(params["client_secret"]) == "" do + [{:client_secret, "Client Secret cannot be blank"} | errors] + else + errors + end + + if Enum.empty?(errors) do + {:ok, params} + else + {:error, errors} + end + end + + @doc """ + Validates event data. + + Returns {:ok, validated_params} or {:error, errors} + """ + def validate_event(params) do + errors = [] + + errors = + if String.trim(params["name"]) == "" do + [{:name, "Name cannot be blank"} | errors] + else + errors + end + + errors = + if String.trim(params["code"]) == "" do + [{:code, "Code cannot be blank"} | errors] + else + errors + end + + if Enum.empty?(errors) do + {:ok, params} + else + {:error, errors} + end + end + + @doc """ + Validates user data. + + Returns {:ok, validated_params} or {:error, errors} + """ + def validate_user(params) do + errors = [] + + errors = + if String.trim(params["email"]) == "" do + [{:email, "Email cannot be blank"} | errors] + else + if valid_email?(params["email"]) do + errors + else + [{:email, "Email is not valid"} | errors] + end + end + + if Enum.empty?(errors) do + {:ok, params} + else + {:error, errors} + end + end + + # Private helper functions + + defp valid_url?(nil), do: false + + defp valid_url?(url) do + uri = URI.parse(url) + uri.scheme != nil && uri.host != nil && uri.host =~ "." + end + + defp valid_email?(nil), do: false + + defp valid_email?(email) do + Regex.match?(~r/^[^\s]+@[^\s]+\.[^\s]+$/, email) + end +end diff --git a/lib/claper_web/views/admin/shared_view.ex b/lib/claper_web/views/admin/shared_view.ex new file mode 100644 index 0000000..d656617 --- /dev/null +++ b/lib/claper_web/views/admin/shared_view.ex @@ -0,0 +1,3 @@ +defmodule ClaperWeb.Admin.SharedView do + use ClaperWeb, :view +end diff --git a/lib/claper_web/views/components/alert_component.ex b/lib/claper_web/views/components/alert_component.ex index 7ec1115..e949847 100644 --- a/lib/claper_web/views/components/alert_component.ex +++ b/lib/claper_web/views/components/alert_component.ex @@ -15,7 +15,7 @@ defmodule ClaperWeb.Component.Alert do x-transition >
-
+

- <%= @message %> + {@message}

@@ -54,7 +54,7 @@ defmodule ClaperWeb.Component.Alert do x-transition >
-
+

- <%= @message %> + {@message}

diff --git a/lib/claper_web/views/components/input_component.ex b/lib/claper_web/views/components/input_component.ex index 9994328..6fdc869 100644 --- a/lib/claper_web/views/components/input_component.ex +++ b/lib/claper_web/views/components/input_component.ex @@ -3,6 +3,7 @@ defmodule ClaperWeb.Component.Input do Input component for forms """ use ClaperWeb, :view_component + use Gettext, backend: ClaperWeb.Gettext def text(assigns) do assigns = @@ -11,6 +12,10 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:autofocus, fn -> false end) |> assign_new(:placeholder, fn -> false end) |> assign_new(:readonly, fn -> false end) + |> assign_new(:label, fn + %{required: false, name: name} -> ~s/#{name} #{gettext("(optional)")}/ + %{name: name} -> name + end) |> assign_new(:labelClass, fn -> "text-gray-700" end) |> assign_new(:fieldClass, fn -> "bg-white" end) |> assign_new(:value, fn -> input_value(assigns.form, assigns.key) end) @@ -19,9 +24,9 @@ defmodule ClaperWeb.Component.Input do ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}") %> + {label(@form, @key, @label, class: "block text-sm font-medium #{@labelClass}")}
- <%= text_input(@form, @key, + {text_input(@form, @key, required: @required, readonly: @readonly, autofocus: @autofocus, @@ -31,11 +36,11 @@ defmodule ClaperWeb.Component.Input do minlength: @minlength, maxlength: @maxlength, class: - "#{@fieldClass} read-only:opacity-50 outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 focus:ring-2 block w-full text-lg border-gray-300 rounded-md py-2 px-3" - ) %> + "#{@fieldClass} read-only:opacity-50 outline-hidden shadow-base focus:ring-primary-500 focus:border-primary-500 focus:ring-2 block w-full text-lg border-gray-300 rounded-md py-2 px-3" + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" @@ -54,9 +59,9 @@ defmodule ClaperWeb.Component.Input do ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}") %> + {label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}")}
- <%= text_input(@form, @key, + {text_input(@form, @key, required: @required, readonly: @readonly, autofocus: @autofocus, @@ -64,11 +69,11 @@ defmodule ClaperWeb.Component.Input do autocomplete: @key, value: @value, class: - "#{@fieldClass} read-only:opacity-50 outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 focus:ring-2 block w-full text-lg border-gray-300 rounded-md py-2 px-3" - ) %> + "#{@fieldClass} read-only:opacity-50 outline-hidden shadow-base focus:ring-primary-500 focus:border-primary-500 focus:ring-2 block w-full text-lg border-gray-300 rounded-md py-2 px-3" + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" @@ -85,24 +90,41 @@ defmodule ClaperWeb.Component.Input do ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}") %> + {label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}")}
- <%= select(@form, @key, @array, + {select(@form, @key, @array, required: @required, autofocus: @autofocus, placeholder: @placeholder, autocomplete: @key, class: - "#{@fieldClass} outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 px-3" - ) %> + "#{@fieldClass} outline-hidden shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 px-3" + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" end + attr :form, Phoenix.HTML.Form, required: true + attr :key, :atom, required: true + attr :label, :string, default: nil + attr :labelClass, :string, default: nil + + def toggle(assigns) do + ~H""" +
+ {@label && + PhoenixHTMLHelpers.Form.label(@form, @key, @label, + class: ["block text-sm font-medium", @labelClass || "text-gray-700"] + )} + {PhoenixHTMLHelpers.Form.checkbox(@form, @key, class: "toggle")} +
+ """ + end + def check(assigns) do assigns = assigns @@ -115,7 +137,7 @@ defmodule ClaperWeb.Component.Input do disabled={@disabled} phx-value-key={@key} type="button" - class="group relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center rounded-full" + class="group relative inline-flex h-5 w-10 shrink-0 cursor-pointer items-center justify-center rounded-full" role="switch" aria-checked="false" phx-key={@shortcut} @@ -150,13 +172,13 @@ defmodule ClaperWeb.Component.Input do disabled={@disabled} phx-value-key={@key} type="button" - class={"py-2 px-2 rounded #{if @checked, do: "bg-primary-500 hover:bg-primary-600 text-white", else: "bg-gray-200 hover:bg-gray-300 text-gray-600"} flex justify-between items-center w-full gap-x-2 disabled:opacity-50 disabled:cursor-not-allowed transition ease-in-out duration-300"} + class={"py-2 px-2 rounded-sm #{if @checked, do: "bg-primary-500 hover:bg-primary-600 text-white", else: "bg-gray-200 hover:bg-gray-300 text-gray-600"} flex justify-between items-center w-full gap-x-2 disabled:opacity-50 disabled:cursor-not-allowed transition ease-in-out duration-300"} role="switch" aria-checked="false" phx-key={@shortcut} phx-window-keydown={if @shortcut && not @disabled, do: checked(@checked, @key)} > - <%= render_slot(@inner_block) %> + {render_slot(@inner_block)} """ end @@ -198,17 +220,19 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:autofocus, fn -> false end) |> assign_new(:placeholder, fn -> false end) |> assign_new(:readonly, fn -> false end) + |> assign_new(:labelClass, fn -> "text-gray-700" end) + |> assign_new(:fieldClass, fn -> "bg-white" end) ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium text-gray-700") %> + {label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}")}
code - <%= text_input(@form, @key, + {text_input(@form, @key, required: @required, readonly: @readonly, placeholder: @placeholder, @@ -217,11 +241,11 @@ defmodule ClaperWeb.Component.Input do minlength: 5, maxlength: 10, class: - "read-only:opacity-50 outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 pr-3 pl-9 uppercase" - ) %> + "#{@fieldClass} read-only:opacity-50 outline-hidden shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 pr-3 pl-9 uppercase" + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" @@ -234,24 +258,26 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:autofocus, fn -> false end) |> assign_new(:placeholder, fn -> false end) |> assign_new(:readonly, fn -> false end) + |> assign_new(:labelClass, fn -> "text-gray-700" end) + |> assign_new(:fieldClass, fn -> "bg-white" end) ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium text-gray-700") %> + {label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}")}
- <%= hidden_input(@form, @key) %> - <%= text_input(@form, :local_date, + {hidden_input(@form, @key)} + {text_input(@form, :local_date, autofocus: @autofocus, placeholder: @placeholder, autocomplete: false, class: - "outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 px-3 read-only:opacity-50" - ) %> + "#{@fieldClass} outline-hidden shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-2 px-3 read-only:opacity-50" + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
@@ -265,15 +291,19 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:autofocus, fn -> false end) |> assign_new(:readonly, fn -> false end) |> assign_new(:placeholder, fn -> false end) + |> assign_new(:label, fn + %{required: false, name: name} -> ~s/#{name} #{gettext("(optional)")}/ + %{name: name} -> name + end) |> assign_new(:labelClass, fn -> "text-gray-700" end) |> assign_new(:fieldClass, fn -> "bg-white" end) |> assign_new(:value, fn -> input_value(assigns.form, assigns.key) end) ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}") %> + {label(@form, @key, @label, class: "block text-sm font-medium #{@labelClass}")}
- <%= email_input(@form, @key, + {email_input(@form, @key, required: @required, autofocus: @autofocus, placeholder: @placeholder, @@ -281,13 +311,13 @@ defmodule ClaperWeb.Component.Input do autocomplete: @key, value: @value, class: - "#{@fieldClass} read-only:opacity-50 shadow-base block w-full text-lg focus:ring-primary-500 focus:ring-2 outline-none rounded-md py-2 px-3", + "#{@fieldClass} read-only:opacity-50 shadow-base block w-full text-lg focus:ring-primary-500 focus:ring-2 outline-hidden rounded-md py-2 px-3", "x-model": "input", "x-ref": "input" - ) %> + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" @@ -305,20 +335,20 @@ defmodule ClaperWeb.Component.Input do ~H"""
- <%= label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}") %> + {label(@form, @key, @name, class: "block text-sm font-medium #{@labelClass}")}
- <%= password_input(@form, @key, + {password_input(@form, @key, required: @required, autofocus: @autofocus, placeholder: @placeholder, class: - "#{@fieldClass} shadow-base block w-full text-lg focus:ring-primary-500 focus:ring-2 outline-none rounded-md py-2 px-3", + "#{@fieldClass} shadow-base block w-full text-lg focus:ring-primary-500 focus:ring-2 outline-hidden rounded-md py-2 px-3", "x-model": "input", "x-ref": "input" - ) %> + )}
<%= if Keyword.has_key?(@form.errors, @key) do %> -

<%= error_tag(@form, @key) %>

+

{error_tag(@form, @key)}

<% end %>
""" diff --git a/lib/claper_web/views/error_helpers.ex b/lib/claper_web/views/error_helpers.ex index c569245..f494420 100644 --- a/lib/claper_web/views/error_helpers.ex +++ b/lib/claper_web/views/error_helpers.ex @@ -3,18 +3,16 @@ defmodule ClaperWeb.ErrorHelpers do Conveniences for translating and building error messages. """ - import Phoenix.HTML.Form use PhoenixHTMLHelpers @doc """ Generates tag for inlined form input errors. """ def error_tag(form, field) do - Enum.map(Keyword.get_values(form.errors, field), fn error -> - content_tag(:span, translate_error(error), - class: "invalid-feedback", - phx_feedback_for: input_name(form, field) - ) + errors = if Phoenix.Component.used_input?(form[field]), do: form[field].errors, else: [] + + Enum.map(errors, fn error -> + content_tag(:span, translate_error(error), class: "invalid-feedback") end) end diff --git a/lib/claper_web/views/layout_view.ex b/lib/claper_web/views/layout_view.ex index 915811a..ef80821 100644 --- a/lib/claper_web/views/layout_view.ex +++ b/lib/claper_web/views/layout_view.ex @@ -24,6 +24,17 @@ defmodule ClaperWeb.LayoutView do end end + def get_section_path(conn) do + section = Enum.at(conn.path_info, 1) + + case section do + "users" -> ~p"/admin/users" + "events" -> ~p"/admin/events" + "oidc_providers" -> ~p"/admin/oidc_providers" + _ -> ~p"/admin" + end + end + def active_link(%Plug.Conn{} = conn, text, opts) do class = [opts[:class], active_class(conn, opts[:to])] diff --git a/lib/claper_web/views/leader_notifier_view.ex b/lib/claper_web/views/leader_notifier_view.ex index 3e97e5c..6c8a45f 100644 --- a/lib/claper_web/views/leader_notifier_view.ex +++ b/lib/claper_web/views/leader_notifier_view.ex @@ -1,5 +1,5 @@ defmodule ClaperWeb.LeaderNotifierView do use Phoenix.View, root: "lib/claper_web/templates" - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext use PhoenixHTMLHelpers end diff --git a/lib/claper_web/views/user_notifier_view.ex b/lib/claper_web/views/user_notifier_view.ex index 1a48574..539ab08 100644 --- a/lib/claper_web/views/user_notifier_view.ex +++ b/lib/claper_web/views/user_notifier_view.ex @@ -1,6 +1,6 @@ defmodule ClaperWeb.UserNotifierView do use Phoenix.View, root: "lib/claper_web/templates" - import ClaperWeb.Gettext + use Gettext, backend: ClaperWeb.Gettext import Phoenix.HTML use PhoenixHTMLHelpers end diff --git a/lib/utils/file_upload.ex b/lib/utils/file_upload.ex deleted file mode 100644 index fd8c4eb..0000000 --- a/lib/utils/file_upload.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule Utils.FileUpload do - import Mogrify - - def upload(type, path, old_path) when is_atom(type) do - remove_old_file(old_path) - - dest = - Path.join([ - :code.priv_dir(:claper), - "static", - "uploads", - Atom.to_string(type), - Path.basename(path) - ]) - - open(path) |> resize_to_fill("100x100") |> save(in_place: true) - File.cp!(path, dest) - "/uploads/#{Atom.to_string(type)}/#{Path.basename(dest)}" - end - - defp remove_old_file(old_path) do - if old_path do - old_file = Path.join([:code.priv_dir(:claper), "static", old_path]) - if File.exists?(old_file), do: File.rm(old_file) - end - end -end diff --git a/lib/utils/simple_s3_upload.ex b/lib/utils/simple_s3_upload.ex deleted file mode 100644 index b7d0af7..0000000 --- a/lib/utils/simple_s3_upload.ex +++ /dev/null @@ -1,127 +0,0 @@ -defmodule SimpleS3Upload do - @moduledoc """ - Dependency-free S3 Form Upload using HTTP POST sigv4 - - https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html - """ - - @doc """ - Signs a form upload. - - The configuration is a map which must contain the following keys: - - * `:region` - The AWS region, such as "us-east-1" - * `:access_key_id` - The AWS access key id - * `:secret_access_key` - The AWS secret access key - - - Returns a map of form fields to be used on the client via the JavaScript `FormData` API. - - ## Options - - * `:key` - The required key of the object to be uploaded. - * `:max_file_size` - The required maximum allowed file size in bytes. - * `:content_type` - The required MIME type of the file to be uploaded. - * `:expires_in` - The required expiration time in milliseconds from now - before the signed upload expires. - - ## Examples - - config = %{ - region: "us-east-1", - access_key_id: System.fetch_env!("AWS_ACCESS_KEY_ID"), - secret_access_key: System.fetch_env!("AWS_SECRET_ACCESS_KEY") - } - - {:ok, fields} = - SimpleS3Upload.sign_form_upload(config, "my-bucket", - key: "public/my-file-name", - content_type: "image/png", - max_file_size: 10_000, - expires_in: :timer.hours(1) - ) - - """ - def sign_form_upload(config, bucket, opts) do - key = Keyword.fetch!(opts, :key) - max_file_size = Keyword.fetch!(opts, :max_file_size) - content_type = Keyword.fetch!(opts, :content_type) - expires_in = Keyword.fetch!(opts, :expires_in) - - expires_at = DateTime.add(DateTime.utc_now(), expires_in, :millisecond) - amz_date = amz_date(expires_at) - credential = credential(config, expires_at) - - encoded_policy = - Base.encode64(""" - { - "expiration": "#{DateTime.to_iso8601(expires_at)}", - "conditions": [ - {"bucket": "#{bucket}"}, - ["eq", "$key", "#{key}"], - {"acl": "public-read"}, - ["eq", "$Content-Type", "#{content_type}"], - ["content-length-range", 0, #{max_file_size}], - {"x-amz-server-side-encryption": "AES256"}, - {"x-amz-credential": "#{credential}"}, - {"x-amz-algorithm": "AWS4-HMAC-SHA256"}, - {"x-amz-date": "#{amz_date}"} - ] - } - """) - - fields = %{ - "key" => key, - "acl" => "public-read", - "content-type" => content_type, - "x-amz-server-side-encryption" => "AES256", - "x-amz-credential" => credential, - "x-amz-algorithm" => "AWS4-HMAC-SHA256", - "x-amz-date" => amz_date, - "policy" => encoded_policy, - "x-amz-signature" => signature(config, expires_at, encoded_policy) - } - - {:ok, fields} - end - - defp amz_date(time) do - time - |> NaiveDateTime.to_iso8601() - |> String.split(".") - |> List.first() - |> String.replace("-", "") - |> String.replace(":", "") - |> Kernel.<>("Z") - end - - defp credential(%{} = config, %DateTime{} = expires_at) do - "#{config.access_key_id}/#{short_date(expires_at)}/#{config.region}/s3/aws4_request" - end - - defp signature(config, %DateTime{} = expires_at, encoded_policy) do - config - |> signing_key(expires_at, "s3") - |> sha256(encoded_policy) - |> Base.encode16(case: :lower) - end - - defp signing_key(%{} = config, %DateTime{} = expires_at, service) when service in ["s3"] do - amz_date = short_date(expires_at) - %{secret_access_key: secret, region: region} = config - - ("AWS4" <> secret) - |> sha256(amz_date) - |> sha256(region) - |> sha256(service) - |> sha256("aws4_request") - end - - defp short_date(%DateTime{} = expires_at) do - expires_at - |> amz_date() - |> String.slice(0..7) - end - - defp sha256(secret, msg), do: :crypto.mac(:hmac, :sha256, secret, msg) -end diff --git a/mix.exs b/mix.exs index 5752f09..dadf816 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Claper.MixProject do use Mix.Project - @version "2.3.2" + @version "2.4.0" def project do [ @@ -76,47 +76,47 @@ defmodule Claper.MixProject do # Type `mix help deps` for examples and options. defp deps do [ - {:ex_aws, "~> 2.2"}, - {:ex_aws_s3, "~> 2.3"}, - {:ex_doc, "~> 0.32", only: :dev, runtime: false}, - {:bcrypt_elixir, "~> 2.0"}, + {:ex_aws, "~> 2.5"}, + {:ex_aws_s3, "~> 2.5"}, + {:ex_doc, "~> 0.38", only: :dev, runtime: false}, + {:bcrypt_elixir, "~> 3.3"}, {:phoenix, "~> 1.7"}, - {:phoenix_ecto, "~> 4.5"}, - {:ecto_sql, "~> 3.11"}, - {:postgrex, ">= 0.0.0"}, - {:phoenix_html, "~> 4.1"}, + {:phoenix_ecto, "~> 4.6"}, + {:ecto_sql, "~> 3.13"}, + {:postgrex, "~> 0.20.0"}, + {:phoenix_html, "~> 4.2"}, {:phoenix_html_helpers, "~> 1.0"}, - {:phoenix_live_reload, "~> 1.5.2", only: :dev}, - {:phoenix_live_view, "~> 0.20.14"}, + {:phoenix_live_reload, "~> 1.6", only: :dev}, + {:phoenix_live_view, "~> 1.0"}, {:phoenix_swoosh, "~> 1.2.1"}, {:phoenix_view, "~> 2.0"}, {:floki, ">= 0.36.1", only: :test}, {:phoenix_live_dashboard, "~> 0.8"}, - {:esbuild, "~> 0.2", runtime: Mix.env() == :dev}, + {:esbuild, "~> 0.10", runtime: Mix.env() == :dev}, {:dart_sass, "~> 0.7", runtime: Mix.env() == :dev}, - {:swoosh, "~> 1.12"}, - {:finch, "~> 0.16"}, - {:telemetry_metrics, "~> 0.6"}, - {:telemetry_poller, "~> 1.0"}, - {:gettext, "~> 0.18"}, - {:jason, "~> 1.2"}, - {:sweet_xml, "~> 0.7.1"}, - {:plug_cowboy, "~> 2.5"}, - {:hashids, "~> 2.0"}, - {:mogrify, "~> 0.9.1"}, - {:libcluster, "~> 3.3"}, + {:swoosh, "~> 1.19"}, + {:finch, "~> 0.19"}, + {:telemetry_metrics, "~> 1.1"}, + {:telemetry_poller, "~> 1.2"}, + {:gettext, "~> 0.26"}, + {:jason, "~> 1.4"}, + {:sweet_xml, "~> 0.7"}, + {:plug_cowboy, "~> 2.7"}, + {:hashids, "~> 2.1"}, + {:libcluster, "~> 3.5"}, {:porcelain, "~> 2.0"}, - {:hackney, "~> 1.18"}, - {:csv, "~> 3.0"}, + {:hackney, "~> 1.24"}, + {:csv, "~> 3.2"}, {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, - {:joken, "~> 2.6.1"}, + {:joken, "~> 2.6"}, {:jose, "~> 1.11"}, - {:req, "~> 0.5.0"}, + {:req, "~> 0.5"}, {:uuid, "~> 1.1"}, - {:oidcc, "~> 3.2"}, - {:oban, "~> 2.17"}, - {:mua, "~> 0.2.4"}, - {:mail, "~> 0.4.3"} + {:oidcc, "~> 3.5"}, + {:oban, "~> 2.19"}, + {:mua, "~> 0.2"}, + {:mail, "~> 0.5"}, + {:tailwind, "~> 0.3", runtime: Mix.env() == :dev} ] end @@ -133,15 +133,12 @@ defmodule Claper.MixProject do "ecto.reset": ["ecto.drop", "ecto.setup"], test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"], "assets.deploy": [ - "cmd --cd assets npm install && npm run deploy", + "cmd --cd assets npm install", + "tailwind default --minify", + "tailwind admin --minify", "esbuild default --minify", "sass default --no-source-map --style=compressed", "phx.digest" - ], - "assets.deploy.nosass": [ - "cmd --cd assets npm install && npm run deploy", - "esbuild default --minify", - "phx.digest" ] ] end diff --git a/mix.lock b/mix.lock index eab21ec..595e357 100644 --- a/mix.lock +++ b/mix.lock @@ -1,94 +1,94 @@ %{ - "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.1", "5114d780459a04f2b4aeef52307de23de961b69e13a5cd98a911e39fda13f420", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "42182d5f46764def15bf9af83739e3bf4ad22661b1c34fc3e88558efced07279"}, + "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "castore": {:hex, :castore, "1.0.10", "43bbeeac820f16c89f79721af1b3e092399b3a1ecc8df1a472738fd853574911", [:mix], [], "hexpm", "1b0b7ea14d889d9ea21202c43a4fa015eb913021cb535e8ed91946f4b77a8848"}, - "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, + "castore": {:hex, :castore, "1.0.14", "4582dd7d630b48cf5e1ca8d3d42494db51e406b7ba704e81fbd401866366896a", [:mix], [], "hexpm", "7bc1b65249d31701393edaaac18ec8398d8974d52c647b7904d01b964137b9f4"}, + "certifi": {:hex, :certifi, "2.15.0", "0e6e882fcdaaa0a5a9f2b3db55b1394dba07e8d6d9bcad08318fb604c6839712", [:rebar3], [], "hexpm", "b147ed22ce71d72eafdad94f055165c1c182f61a2ff49df28bcc71d1d5b94a60"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, - "comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"}, + "comeonin": {:hex, :comeonin, "5.5.1", "5113e5f3800799787de08a6e0db307133850e635d34e9fab23c70b6501669510", [:mix], [], "hexpm", "65aac8f19938145377cee73973f192c5645873dcf550a8a6b18187d17c13ccdb"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, - "cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, + "cowboy": {:hex, :cowboy, "2.13.0", "09d770dd5f6a22cc60c071f432cd7cb87776164527f205c5a6b0f24ff6b38990", [:make, :rebar3], [{:cowlib, ">= 2.14.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e724d3a70995025d654c1992c7b11dbfea95205c047d86ff9bf1cda92ddc5614"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, - "cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, - "credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"}, - "csv": {:hex, :csv, "3.0.5", "3c1455127e92de8845806db89554ad7d45e0212974be41dd9c38a5c881861713", [:mix], [], "hexpm", "cbbe5455c93df5f3f2943e995e28b7a8808361ba34cf3e44267d77a01eaf1609"}, + "cowlib": {:hex, :cowlib, "2.15.0", "3c97a318a933962d1c12b96ab7c1d728267d2c523c25a5b57b0f93392b6e9e25", [:make, :rebar3], [], "hexpm", "4f00c879a64b4fe7c8fcb42a4281925e9ffdb928820b03c3ad325a617e857532"}, + "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, + "csv": {:hex, :csv, "3.2.2", "452f96414b39a176b7c390af6d8b78f15130dc6167fe3b836729131f515d843e", [:mix], [], "hexpm", "cbf256ff74a3fa01d9ec420d07b19c90d410ed9fe5b6d6e1bc7662edf35bc574"}, "dart_sass": {:hex, :dart_sass, "0.7.0", "7979e056cb74fd6843e1c72db763cffc7726a9192a657735b7d24c0d9c26a1ce", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "4a8e70bca41aa00846398abdf5ad8a64d7907a0f7bf40145cd2e40d5971629f2"}, - "db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"}, + "db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, - "ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"}, - "ecto_sql": {:hex, :ecto_sql, "3.11.1", "e9abf28ae27ef3916b43545f9578b4750956ccea444853606472089e7d169470", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ce14063ab3514424276e7e360108ad6c2308f6d88164a076aac8a387e1fea634"}, - "elixir_make": {:hex, :elixir_make, "0.7.6", "67716309dc5d43e16b5abbd00c01b8df6a0c2ab54a8f595468035a50189f9169", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5a0569756b0f7873a77687800c164cca6dfc03a09418e6fcf853d78991f49940"}, - "esbuild": {:hex, :esbuild, "0.7.0", "ce3afb13cd2c5fd63e13c0e2d0e0831487a97a7696cfa563707342bb825d122a", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "4ae9f4f237c5ebcb001390b8ada65a12fb2bb04f3fe3d1f1692b7a06fbfe8752"}, - "ex_aws": {:hex, :ex_aws, "2.5.8", "0393cfbc5e4a9e7017845451a015d836a670397100aa4c86901980e2a2c5f7d4", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8 or ~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:req, "~> 0.3", [hex: :req, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8f79777b7932168956c8cc3a6db41f5783aa816eb50de356aed3165a71e5f8c3"}, - "ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"}, - "ex_doc": {:hex, :ex_doc, "0.32.1", "21e40f939515373bcdc9cffe65f3b3543f05015ac6c3d01d991874129d173420", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5142c9db521f106d61ff33250f779807ed2a88620e472ac95dc7d59c380113da"}, - "expo": {:hex, :expo, "0.5.2", "beba786aab8e3c5431813d7a44b828e7b922bfa431d6bfbada0904535342efe2", [:mix], [], "hexpm", "8c9bfa06ca017c9cb4020fabe980bc7fdb1aaec059fd004c2ab3bff03b1c599c"}, - "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, + "ecto": {:hex, :ecto, "3.13.2", "7d0c0863f3fc8d71d17fc3ad3b9424beae13f02712ad84191a826c7169484f01", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "669d9291370513ff56e7b7e7081b7af3283d02e046cf3d403053c557894a0b3e"}, + "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, + "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, + "esbuild": {:hex, :esbuild, "0.10.0", "b0aa3388a1c23e727c5a3e7427c932d89ee791746b0081bbe56103e9ef3d291f", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "468489cda427b974a7cc9f03ace55368a83e1a7be12fba7e30969af78e5f8c70"}, + "ex_aws": {:hex, :ex_aws, "2.5.10", "d3f8ca8959dad6533a2a934dfdf380df1b1bef425feeb215a47a5176dee8736c", [:mix], [{:configparser_ex, "~> 5.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8 or ~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "88fcd9cc1b2e0fcea65106bdaa8340ac56c6e29bf72f46cf7ef174027532d3da"}, + "ex_aws_s3": {:hex, :ex_aws_s3, "2.5.7", "e571424d2f345299753382f3a01b005c422b1a460a8bc3ed47659b3d3ef91e9e", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "858e51241e50181e29aa2bc128fef548873a3a9cd580471f57eda5b64dec937f"}, + "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, + "expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"}, + "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, - "floki": {:hex, :floki, "0.36.1", "712b7f2ba19a4d5a47dfe3e74d81876c95bbcbee44fe551f0af3d2a388abb3da", [:mix], [], "hexpm", "21ba57abb8204bcc70c439b423fc0dd9f0286de67dc82773a14b0200ada0995f"}, + "floki": {:hex, :floki, "0.38.0", "62b642386fa3f2f90713f6e231da0fa3256e41ef1089f83b6ceac7a3fd3abf33", [:mix], [], "hexpm", "a5943ee91e93fb2d635b612caf5508e36d37548e84928463ef9dd986f0d1abd9"}, "gen_smtp": {:hex, :gen_smtp, "1.2.0", "9cfc75c72a8821588b9b9fe947ae5ab2aed95a052b81237e0928633a13276fd3", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "5ee0375680bca8f20c4d85f58c2894441443a743355430ff33a783fe03296779"}, - "gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"}, - "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~>2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, + "gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"}, + "hackney": {:hex, :hackney, "1.24.1", "f5205a125bba6ed4587f9db3cc7c729d11316fa8f215d3e57ed1c067a9703fa9", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "f4a7392a0b53d8bbc3eb855bdcc919cd677358e65b2afd3840b5b3690c4c8a39"}, "hashids": {:hex, :hashids, "2.1.0", "aabbcc4f9fa0b460cc6ef629f5bcbc35e7e87b382fee79f9c50be40b86574288", [:mix], [], "hexpm", "172163b1642d415881ef1c6e1f1be12d4e92b0711d5bbbd8854f82a1ce32d60b"}, "honeybadger": {:hex, :honeybadger, "0.18.1", "f61f71147d9e6ce8cdc6114e5df5eed4d2daa32dd15308267a1dacf5fa88b1e9", [:mix], [{:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:hackney, "~> 1.1", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.0.0 and < 2.0.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, ">= 1.0.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "693e14b1b7d254dd75f977240c208d6b69cc1cbdd515bdd5b8b1738a1baf5fd5"}, - "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, + "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, - "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, - "joken": {:hex, :joken, "2.6.1", "2ca3d8d7f83bf7196296a3d9b2ecda421a404634bfc618159981a960020480a1", [:mix], [{:jose, "~> 1.11.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "ab26122c400b3d254ce7d86ed066d6afad27e70416df947cdcb01e13a7382e68"}, + "joken": {:hex, :joken, "2.6.2", "5daaf82259ca603af4f0b065475099ada1b2b849ff140ccd37f4b6828ca6892a", [:mix], [{:jose, "~> 1.11.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "5134b5b0a6e37494e46dbf9e4dad53808e5e787904b7c73972651b51cce3d72b"}, "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, - "libcluster": {:hex, :libcluster, "3.3.2", "84c6ebfdc72a03805955abfb5ff573f71921a3e299279cc3445445d5af619ad1", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8b691ce8185670fc8f3fc0b7ed59eff66c6889df890d13411f8f1a0e6871d8a5"}, + "libcluster": {:hex, :libcluster, "3.5.0", "5ee4cfde4bdf32b2fef271e33ce3241e89509f4344f6c6a8d4069937484866ba", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebf6561fcedd765a4cd43b4b8c04b1c87f4177b5fb3cbdfe40a780499d72f743"}, "lti_1p3": {:hex, :lti_1p3, "0.6.0", "e896c56b0ae067b768fb5ce2c44db305b6d7bbc213fafd1bbb7da586629c6d9f", [:mix], [{:httpoison, "~> 2.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.2.0", [hex: :joken, repo: "hexpm", optional: false]}, {:timex, "~> 3.5", [hex: :timex, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm", "7c142ae8027913bbaa2267a28f448e734b1c5b2563e2aee2b1481632b84e35b3"}, "lti_1p3_ecto_provider": {:hex, :lti_1p3_ecto_provider, "0.6.0", "7d8f3293b2dd32c243a55b5020ff0e37c5372ba8669bf82944b173d65f22a8e3", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:httpoison, "~> 2.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:lti_1p3, "~> 0.6.0", [hex: :lti_1p3, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:timex, "~> 3.5", [hex: :timex, repo: "hexpm", optional: false]}, {:uuid, "~> 1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm", "b825e745ccd4dfb840bf1217056f535dd1c50ecbe673917c3b17efc4a64246d1"}, - "mail": {:hex, :mail, "0.4.3", "16df84500780980826d9b52059d24c08fdd75c98f178a7a7ea809ea83fb70542", [:mix], [], "hexpm", "164975550b977e47cab431c403b0e90c8ce542036d32c7189b83839d8d7d391b"}, - "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, + "mail": {:hex, :mail, "0.5.1", "6383a61620aea24675c96e34b9019dede1bfc9a37ee10ce5a5cafcc7c5e48743", [:mix], [], "hexpm", "595144340b74f23d651ea2b4a72a896819940478d7425dfa302ea3b5c9041ec9"}, + "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, + "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, - "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, - "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, - "mogrify": {:hex, :mogrify, "0.9.2", "b360984adea7dd6a55f18028e6327973c58de7f548fdb86c9859848aa904d5b0", [:mix], [], "hexpm", "c18d10fd70ca20e2585301616c89f6e4f7159d92efc9cc8ee579e00c886f699d"}, + "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, + "mimerl": {:hex, :mimerl, "1.4.0", "3882a5ca67fbbe7117ba8947f27643557adec38fa2307490c4c4207624cb213b", [:rebar3], [], "hexpm", "13af15f9f68c65884ecca3a3891d50a7b57d82152792f3e19d88650aa126b144"}, + "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "mua": {:hex, :mua, "0.2.4", "a9172ab0a1ac8732cf2699d739ceac3febcb9b4ffc540260ad2e32c0b6632af9", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "e7e4dacd5ad65f13e3542772e74a159c00bd2d5579e729e9bb72d2c73a266fb7"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, - "oban": {:hex, :oban, "2.18.3", "1608c04f8856c108555c379f2f56bc0759149d35fa9d3b825cb8a6769f8ae926", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "36ca6ca84ef6518f9c2c759ea88efd438a3c81d667ba23b02b062a0aa785475e"}, - "oidcc": {:hex, :oidcc, "3.2.0", "f80a4826a946ce07dc8cbd8212392b4ff436ae3c4b4cd6680fa0d84d0ff2fec1", [:mix, :rebar3], [{:jose, "~> 1.11", [hex: :jose, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.3.1", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "38fd9092ab5d5d10c71b8011b019316411afe466bef07ba57f57ec3f919278c3"}, + "oban": {:hex, :oban, "2.19.4", "045adb10db1161dceb75c254782f97cdc6596e7044af456a59decb6d06da73c1", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5fcc6219e6464525b808d97add17896e724131f498444a292071bf8991c99f97"}, + "oidcc": {:hex, :oidcc, "3.5.2", "91b0097a3fee86abb1aabfd80f2f910439688287408d916fed3535724b4fb897", [:mix, :rebar3], [{:igniter, "~> 0.5.50", [hex: :igniter, repo: "hexpm", optional: true]}, {:jose, "~> 1.11", [hex: :jose, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.3.1", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "474e7eddbf90ec4c8c50aeefe9a1ffb46ced72e6a11c2bb0c6eece9794821c2a"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, - "phoenix": {:hex, :phoenix, "1.7.11", "1d88fc6b05ab0c735b250932c4e6e33bfa1c186f76dcf623d8dd52f07d6379c7", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "b1ec57f2e40316b306708fe59b92a16b9f6f4bf50ccfa41aa8c7feb79e0ec02a"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.5.1", "6fdbc334ea53620e71655664df6f33f670747b3a7a6c4041cdda3e2c32df6257", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ebe43aa580db129e54408e719fb9659b7f9e0d52b965c5be26cdca416ecead28"}, - "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"}, + "phoenix": {:hex, :phoenix, "1.7.21", "14ca4f1071a5f65121217d6b57ac5712d1857e40a0833aff7a691b7870fc9a3b", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "336dce4f86cba56fed312a7d280bf2282c720abb6074bdb1b61ec8095bdd0bc9"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.5", "c4ef322acd15a574a8b1a08eff0ee0a85e73096b53ce1403b6563709f15e1cea", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "26ec3208eef407f31b748cadd044045c6fd485fbff168e35963d2f9dfff28d4b"}, + "phoenix_html": {:hex, :phoenix_html, "4.2.1", "35279e2a39140068fc03f8874408d58eef734e488fc142153f055c5454fd1c08", [:mix], [], "hexpm", "cff108100ae2715dd959ae8f2a8cef8e20b593f8dfd031c9cba92702cf23e053"}, "phoenix_html_helpers": {:hex, :phoenix_html_helpers, "1.0.1", "7eed85c52eff80a179391036931791ee5d2f713d76a81d0d2c6ebafe1e11e5ec", [:mix], [{:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "cffd2385d1fa4f78b04432df69ab8da63dc5cf63e07b713a4dcf36a3740e3090"}, - "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.3", "7ff51c9b6609470f681fbea20578dede0e548302b0c8bdf338b5a753a4f045bf", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "f9470a0a8bae4f56430a23d42f977b5a6205fdba6559d76f932b876bfaec652d"}, - "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.5.2", "354460993a480656b71c3887f5565f612b3bdbdd8688c83f9e6f512307067dd4", [:mix], [{:file_system, "~> 0.3 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "2bb3722f327e14a7aa47b1acf27ed633c8cd27b167e18b8237954b9b4804af39"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.14", "70fa101aa0539e81bed4238777498f6215e9dda3461bdaa067cad6908110c364", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "82f6d006c5264f979ed5eb75593d808bbe39020f20df2e78426f4f2d570e2402"}, + "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.0", "2791fac0e2776b640192308cc90c0dbcf67843ad51387ed4ecae2038263d708d", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "b3a1fa036d7eb2f956774eda7a7638cf5123f8f2175aca6d6420a7f95e598e1c"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "1.0.17", "beeb16d83a7d3760f7ad463df94e83b087577665d2acc0bf2987cd7d9778068f", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a4ca05c1eb6922c4d07a508a75bfa12c45e5f4d8f77ae83283465f02c53741e1"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, "phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, - "phoenix_view": {:hex, :phoenix_view, "2.0.3", "4d32c4817fce933693741deeb99ef1392619f942633dde834a5163124813aad3", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "cd34049af41be2c627df99cd4eaa71fc52a328c0c3d8e7d4aa28f880c30e7f64"}, - "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.7.2", "fdadb973799ae691bf9ecad99125b16625b1c6039999da5fe544d99218e662e4", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "245d8a11ee2306094840c000e8816f0cbed69a23fc0ac2bcf8d7835ae019bb2f"}, - "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, + "phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"}, + "plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.7.4", "729c752d17cf364e2b8da5bdb34fb5804f56251e88bb602aff48ae0bd8673d11", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9b85632bd7012615bae0a5d70084deb1b25d2bcbb32cab82d1e9a1e023168aa3"}, + "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, "porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"}, - "postgrex": {:hex, :postgrex, "0.17.5", "0483d054938a8dc069b21bdd636bf56c487404c241ce6c319c1f43588246b281", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "50b8b11afbb2c4095a3ba675b4f055c416d0f3d7de6633a595fc131a828a67eb"}, - "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, - "req": {:hex, :req, "0.5.8", "50d8d65279d6e343a5e46980ac2a70e97136182950833a1968b371e753f6a662", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d7fc5898a566477e174f26887821a3c5082b243885520ee4b45555f5d53f40ef"}, + "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, + "ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"}, + "req": {:hex, :req, "0.5.14", "521b449fa0bf275e6d034c05f29bec21789a0d6cd6f7a1c326c7bee642bf6e07", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b7b15692071d556c73432c7797aa7e96b51d1a2db76f746b976edef95c930021"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stripity_stripe": {:hex, :stripity_stripe, "2.13.0", "b9ea806fcf46e85232b75f2145c34770b17faa44c59cdd13ff493aaa6e84b4a9", [:mix], [{:hackney, "~> 1.15", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:uri_query, "~> 0.1.2", [hex: :uri_query, repo: "hexpm", optional: false]}], "hexpm", "d6931ed9816552320f95428fd997edf15e99a913ca78fc4342d5516b98f42476"}, - "sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"}, - "swoosh": {:hex, :swoosh, "1.17.5", "14910d267a2633d4335917b37846e376e2067815601592629366c39845dad145", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "629113d477bc82c4c3bffd15a25e8becc1c7ccc0f0e67743b017caddebb06f04"}, + "sweet_xml": {:hex, :sweet_xml, "0.7.5", "803a563113981aaac202a1dbd39771562d0ad31004ddbfc9b5090bdcd5605277", [:mix], [], "hexpm", "193b28a9b12891cae351d81a0cead165ffe67df1b73fe5866d10629f4faefb12"}, + "swoosh": {:hex, :swoosh, "1.19.3", "02ad4455939f502386e4e1443d4de94c514995fd0e51b3cafffd6bd270ffe81c", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "04a10f8496786b744b84130e3510eb53ca51e769c39511b65023bdf4136b732f"}, + "tailwind": {:hex, :tailwind, "0.3.1", "a89d2835c580748c7a975ad7dd3f2ea5e63216dc16d44f9df492fbd12c094bed", [:mix], [], "hexpm", "98a45febdf4a87bc26682e1171acdedd6317d0919953c353fcd1b4f9f4b676a2"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, - "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.2", "2caabe9344ec17eafe5403304771c3539f3b6e2f7fb6a6f602558c825d0d0bfb", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9b43db0dc33863930b9ef9d27137e78974756f5f198cae18409970ed6fa5b561"}, - "telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"}, + "telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"}, + "telemetry_poller": {:hex, :telemetry_poller, "1.2.0", "ba82e333215aed9dd2096f93bd1d13ae89d249f82760fcada0850ba33bac154b", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7216e21a6c326eb9aa44328028c34e9fd348fb53667ca837be59d0aa2a0156e8"}, "telemetry_registry": {:hex, :telemetry_registry, "0.3.2", "701576890320be6428189bff963e865e8f23e0ff3615eade8f78662be0fc003c", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7ed191eb1d115a3034af8e1e35e4e63d5348851d556646d46ca3d1b4e16bab9"}, "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, "tls_certificate_check": {:hex, :tls_certificate_check, "1.25.0", "702b1835fe718a52310509537392abd067dbe941ebc05fe72409d2b2f8061651", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "167343ccf50538cf2faf61a3f1460e749b3edf2ecef55516af2b5834362abcb1"}, "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"}, "uri_query": {:hex, :uri_query, "0.1.2", "ae35b83b472f3568c2c159eee3f3ccf585375d8a94fb5382db1ea3589e75c3b4", [:mix], [], "hexpm", "e3bc81816c98502c36498b9b2f239b89c71ce5eadfff7ceb2d6c0a2e6ae2ea0c"}, "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, - "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"}, + "websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"}, } diff --git a/phoenix_static_buildpack.config b/phoenix_static_buildpack.config deleted file mode 100644 index 0ce5c5f..0000000 --- a/phoenix_static_buildpack.config +++ /dev/null @@ -1 +0,0 @@ -node_version=14.19.0 diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po index a4c5286..98ae3a9 100644 --- a/priv/gettext/de/LC_MESSAGES/default.po +++ b/priv/gettext/de/LC_MESSAGES/default.po @@ -8,15 +8,18 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Einstellungen" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -43,7 +46,10 @@ msgstr "Überprüfen Sie, ob alle Felder korrekt ausgefüllt sind." msgid "Change" msgstr "Ändern" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "Code" @@ -54,7 +60,7 @@ msgstr "Code" msgid "Email address" msgstr "E-Mail Adresse" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Ausloggen" @@ -97,15 +103,18 @@ msgstr "Seien Sie der Erste, der reagiert!" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "Teilnehmen" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Dashboard" @@ -122,7 +131,7 @@ msgid "seconds" msgstr "Sekunden" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Beendet" @@ -175,47 +184,50 @@ msgstr "Zurück zur Startseite" msgid "Created successfully" msgstr "Erfolgreich erstellt" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Ändern" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "Erstellen" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Löschen" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -259,12 +271,6 @@ msgstr "Email-Einweisung ändern" msgid "CONFIRM EMAIL" msgstr "E-MAIL BESTÄTIGEN" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "E-Mail bestätigen" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -295,9 +301,9 @@ msgid "Presentation uploaded" msgstr "Präsentation hochgeladen" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Entfernen" @@ -332,17 +338,17 @@ msgstr "Ihre Datei ist zu groß" msgid "Change file" msgstr "Datei ändern" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Präsentation ersetzt" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Umfrage bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Neue Umfrage" @@ -357,18 +363,18 @@ msgstr "Titel Ihrer Umfrage" msgid "Upload failed" msgstr "Hochladen fehlgeschlagen" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "Fügen Sie eine Umfrage hinzu, um die Meinung Ihres Publikums zu erfahren." -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Umfrage" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -391,18 +397,18 @@ msgstr "Aktuelle Umfrage anzeigen" msgid "Vote" msgstr "Abstimmen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Benutzer Email-Adresse" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "Wenn Sie Ihre Datei ändern, werden alle damit verbundenen Interaktionselemente wie Umfragen entfernt." -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Nachrichten von Teilnehmern werden hier erscheinen." @@ -412,7 +418,7 @@ msgstr "Nachrichten von Teilnehmern werden hier erscheinen." msgid "Processing your file..." msgstr "Verarbeitung der Datei..." -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "Dadurch werden alle zugehörigen Antworten und die Umfrage selbst gelöscht, sind Sie sicher?" @@ -422,14 +428,14 @@ msgstr "Dadurch werden alle zugehörigen Antworten und die Umfrage selbst gelös msgid "Ask, comment..." msgstr "Fragen, kommentieren..." -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Nachrichten" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Moderator hinzufügen" @@ -444,7 +450,7 @@ msgstr "Hoppla, Seite existiert nicht." msgid "The site is under maintenance, we'll be back very soon!" msgstr "Die Seite wird gerade gewartet, wir sind bald wieder da!" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "Moderatoren können präsentieren und Interaktionen steuern" @@ -458,13 +464,8 @@ msgstr "Moderatoren können präsentieren und Interaktionen steuern" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "Wenn Sie Probleme mit der obigen Schaltfläche haben, kopieren Sie die folgende URL und fügen Sie sie in Ihren Webbrowser ein" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "Sie können Ihre E-Mail-Adresse ändern, indem Sie die folgende URL aufrufen" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "Interaktion hinzufügen" @@ -622,6 +623,7 @@ msgstr "Oder verwenden Sie den Code:" msgid "Create account" msgstr "Benutzerkonto erstellen" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -657,14 +659,14 @@ msgstr "Aktualisieren Sie Ihr Passwort" msgid "Your password has been updated." msgstr "Dein Passwort wurde aktualisiert." -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "Feld %{count}" msgstr[1] "Feld %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "Fügen Sie ein Formular hinzu, um Daten von Ihrem Publikum zu sammeln." @@ -674,34 +676,41 @@ msgstr "Fügen Sie ein Formular hinzu, um Daten von Ihrem Publikum zu sammeln." msgid "Current form" msgstr "Aktuelles Formular" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "Formular bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formular" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Abgeschickte Formulare" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "Formulareinsendungen der Teilnehmer werden hier angezeigt." -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "Name" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "Neues Formular" @@ -722,17 +731,17 @@ msgstr "Aktuelles Formular anzeigen" msgid "Submit" msgstr "Abschicken" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "Text" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Dies kann nicht rückgängig gemacht werden. Bestätigen?" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "Dadurch werden alle zugehörigen Antworten und das Formular selbst gelöscht. Sind Sie sicher?" @@ -742,7 +751,7 @@ msgstr "Dadurch werden alle zugehörigen Antworten und das Formular selbst gelö msgid "Title of your form" msgstr "Titel Ihres Formulars" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "Typ" @@ -757,7 +766,7 @@ msgstr "Wählen Sie eine Option aus" msgid "Select one or multiple options" msgstr "Wählen Sie eine oder mehrere Optionen aus" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "Mehrere Antworten" @@ -767,12 +776,12 @@ msgstr "Mehrere Antworten" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX bis zu %{size} MB" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Nachrichten aktivieren" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Nachrichten anzeigen" @@ -821,7 +830,7 @@ msgstr "deaktiviert" msgid "Account creation is disabled" msgstr "Kontoerstellung ist deaktiviert" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Fügen Sie ein YouTube-Video oder einen beliebigen Webinhalt hinzu." @@ -872,12 +881,12 @@ msgstr "Link zum Zurücksetzen des Passworts senden" msgid "Current web content" msgstr "Aktuelle Einbettung" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Webinhalt bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Neuer Webinhalt" @@ -887,7 +896,7 @@ msgstr "Neuer Webinhalt" msgid "See current web content" msgstr "Aktuelle Webinhalte anzeigen" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete the web content, are you sure?" msgstr "Dies wird den Webinhalt löschen, sind Sie sicher?" @@ -898,8 +907,8 @@ msgstr "Dies wird den Webinhalt löschen, sind Sie sicher?" msgid "Title" msgstr "Titel" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Webinhalt" @@ -916,17 +925,17 @@ msgstr "Anpinnen" msgid "Pinned" msgstr "Angepinnt" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format, fuzzy msgid "Pinned messages" msgstr "Angepinnte Nachrichten" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Angepinnte Beiträge werden hier angezeigt." -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Nur angepinnte Nachrichten anzeigen" @@ -967,7 +976,7 @@ msgstr "Sie wurden eingeladen, ein Ereignis zu verwalten" msgid "Saved" msgstr "Gespeichert" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "Alle Ihre Veranstaltungen und Dateien werden dauerhaft gelöscht, sind Sie sicher?" @@ -982,22 +991,22 @@ msgstr "Sind Sie sicher, dass Sie diese Veranstaltung beenden möchten? Diese Ak msgid "Attendees room" msgstr "Teilnehmerraum" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "Seien Sie vorsichtig, diese Aktionen sind unwiderruflich" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "Gefahrenzone" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format, fuzzy msgid "Delete account" msgstr "Konto löschen" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "Präsentation öffnen" @@ -1012,7 +1021,7 @@ msgstr "Bericht ansehen" msgid "Your account has been deleted." msgstr "Ihr Konto wurde gelöscht." -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format, fuzzy msgid "Access code" msgstr "Zugriff" @@ -1022,46 +1031,46 @@ msgstr "Zugriff" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "Animationen in PPT/PPTX-Dateien werden nicht unterstützt, weshalb wir empfehlen, Ihre Präsentation in PDF zu exportieren, um eine korrekte Anzeige zu gewährleisten." -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees interactions" msgstr "Interaktionen der Teilnehmer" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "Zurück" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators" msgstr "Moderatoren" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Finish" msgstr "Abschließen" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "Hier finden Sie alle Interaktionen Ihrer Teilnehmer. Sie können Nachrichten, angeheftete Nachrichten und eingereichte Formulare verwalten." -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "Identifizieren Sie Benutzer anhand ihrer einzigartigen Avatare." #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1074,57 +1083,57 @@ msgstr "Weiter" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "Wählen Sie Ihre Präsentationsdatei aus. Akzeptierte Formate sind PDF, PPT oder PPTX. Stellen Sie sicher, dass die Dateigröße das maximale Limit nicht überschreitet." -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format, fuzzy msgid "Time to launch your presentation!" msgstr "Zeit, Ihre Präsentation zu starten!" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "Verwenden Sie die zugehörigen Tastaturkürzel, um diese Einstellungen schnell umzuschalten." -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "Sie können jede Einstellung für die Präsentation (Anzeige auf dem Großbildschirm) und im Raum der Teilnehmer steuern." -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "Ihre ersten Schritte mit Claper" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "Teilnehmer, die versuchen, vor diesem Datum auf das Veranstaltung zuzugreifen, werden in einen Warteraum geleitet." -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format, fuzzy msgid "Create event" msgstr "Veranstaltung erstellen" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first event" msgstr "Erstellen Sie Ihr erstes Veranstaltung" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "Datum des Veranstaltungsbeginns" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "Wenn Sie keine Zeit haben und nur Interaktionen ohne eine Präsentationsdatei wünschen, können Sie hier eine neue Veranstaltung erstellen." -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "Wenn Sie Unterstützung bei der Verwaltung Ihrer Veranstaltung benötigen, können Sie anderen Personen Zugang gewähren. Geben Sie einfach deren E-Mail-Adressen ein. Sobald sie ein Konto mit diesen E-Mail-Adressen registrieren, können sie die Veranstaltung verwalten." -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "Eilig?" @@ -1134,18 +1143,18 @@ msgstr "Eilig?" msgid "Live" msgstr "Live" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "Meine Veranstaltungen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format, fuzzy msgid "Name of your event" msgstr "Name Ihrer Veranstaltung" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "Note: Facilitators do not have the ability to delete your event." msgstr "Hinweis: Moderatoren können Ihre Veranstaltung nicht löschen." @@ -1155,12 +1164,12 @@ msgstr "Hinweis: Moderatoren können Ihre Veranstaltung nicht löschen." msgid "Presentation file (optional)" msgstr "Präsentationsdatei (optional)" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "Schnellveranstaltung" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "Schnellveranstaltung erfolgreich erstellt" @@ -1170,7 +1179,7 @@ msgstr "Schnellveranstaltung erfolgreich erstellt" msgid "Return to your last event" msgstr "Zurück zu Ihrer letzten Veranstaltung" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Select the start date for your event. Future dates are permissible." msgstr "Wählen Sie das Startdatum für Ihre Veranstaltung. Zukünftige Daten sind zulässig." @@ -1180,22 +1189,22 @@ msgstr "Wählen Sie das Startdatum für Ihre Veranstaltung. Zukünftige Daten si msgid "Select your presentation (optional)" msgstr "Wählen Sie Ihre Präsentation aus (optional)" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format, fuzzy msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "Dieser Code wird von Ihren Teilnehmern verwendet, um auf die Veranstaltung zuzugreifen. Sie haben die Möglichkeit, einen benutzerdefinierten Code zu erstellen." -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "Diese Veranstaltung wurde beendet" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format, fuzzy msgid "Welcome to Claper! You can create a new event here." msgstr "Willkommen bei Claper! Hier können Sie eine neue Veranstaltung erstellen." -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format, fuzzy msgid "When your event will start?" msgstr "Wann beginnt Ihre Veranstaltung?" @@ -1205,8 +1214,8 @@ msgstr "Wann beginnt Ihre Veranstaltung?" msgid "Create your next presentation with" msgstr "Erstellen Sie Ihre nächste Präsentation mit" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1217,7 +1226,7 @@ msgstr "Veranstaltung existiert nicht" msgid "Customize your account" msgstr "Passen Sie Ihr Konto an" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "Sprache" @@ -1237,22 +1246,22 @@ msgstr "Ihre Einstellungen wurden aktualisiert." msgid "Question" msgstr "Frage" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "Fragen" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "Fragen werden hier erscheinen." -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "Nach Datum sortieren" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "Nach Beliebtheit sortieren" @@ -1262,7 +1271,8 @@ msgstr "Nach Beliebtheit sortieren" msgid "Event manager" msgstr "Veranstaltungsmanager" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "Dokumentation" @@ -1278,7 +1288,7 @@ msgstr "Mein Konto" msgid "Your personal informations to access your account" msgstr "Ihre persnlichen Informationen zum Zugreifen auf Ihr Konto" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format, fuzzy msgid "Enable reactions" msgstr "Reaktionen aktivieren" @@ -1334,43 +1344,43 @@ msgid "Add Claper" msgstr "Claper hinzufügen" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "Vorschau schließen" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first interaction." msgstr "Erstellen Sie Ihre erste Interaktion." -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format, fuzzy msgid "Disable" msgstr "Deaktivieren" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "Aktivieren" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format, fuzzy msgid "Enable messages to change this option" msgstr "Aktivieren Sie Nachrichten, um diese Option zu ändern" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "Vorschau öffnen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "Nachrichten anzeigen, um diese Option zu ändern" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "Diese Folie hat keine Interaktionen." @@ -1397,7 +1407,7 @@ msgstr "Anmelden mit %{provider}" msgid "The account has been unlinked." msgstr "Das Konto wurde getrennt." -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "Dieser Abschnitt enthält alle Ihre Interaktionen." @@ -1408,12 +1418,12 @@ msgstr "Dieser Abschnitt enthält alle Ihre Interaktionen." msgid "Unlink" msgstr "Trennen" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "Sie können Ihren Präsentationsfolien Interaktionen hinzufügen." -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "Ihre Interaktionen" @@ -1438,12 +1448,12 @@ msgstr "Legen Sie ein neues Passwort für Ihr Konto fest, bevor Sie es trennen." msgid "Your password has been set, you can now unlink your account." msgstr "Ihr Passwort wurde festgelegt. Sie können jetzt Ihr Konto trennen." -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "Iframe-Code" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "Link zum Inhalt" @@ -1469,24 +1479,24 @@ msgstr "Bitte geben Sie einen gültigen Link ein, der mit http:// oder https:// msgid "Please enter valid HTML content with an iframe tag" msgstr "Bitte geben Sie gültigen HTML-Inhalt mit einem iframe-Tag ein" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "Anbieter" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "Teilnehmer können die Ergebnisse auf ihrem Gerät sehen" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format msgid "Attendees can view the web content on their device" msgstr "Teilnehmer können die Webinhalte auf ihrem Gerät anzeigen" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "Optionen" @@ -1554,12 +1564,12 @@ msgstr "Beenden" msgid "More options" msgstr "Weitere Optionen" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "Nein" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "Ja" @@ -1609,32 +1619,32 @@ msgstr "Sie können Ihr Passwort zurücksetzen, indem Sie die folgende URL besuc msgid "back to the home page" msgstr "zurück zur Startseite" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format, fuzzy msgid "Add Question" msgstr "Frage hinzufügen" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "Fügen Sie ein Quiz hinzu, um Wissen zu testen." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "Antwort hinzufügen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous messages" msgstr "Anonyme Nachrichten erlauben" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "Antwort %{index}" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "Teilnehmer" @@ -1650,32 +1660,32 @@ msgstr "Durchschnittliche Punktzahl" msgid "Current quiz" msgstr "Aktuelles Quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format, fuzzy msgid "Deny anonymous messages" msgstr "Anonyme Nachrichten verweigern" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format, fuzzy msgid "Disable messages" msgstr "Nachrichten deaktivieren" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format, fuzzy msgid "Disable reactions" msgstr "Reaktionen deaktivieren" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format, fuzzy msgid "Edit quiz" msgstr "Quiz bearbeiten" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "Beitrittsanweisungen ausblenden" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format, fuzzy msgid "Hide messages" msgstr "Nachrichten ausblenden" @@ -1698,12 +1708,12 @@ msgstr "Wie funktioniert es?" msgid "Interaction" msgstr "Interaktion" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "Neues Quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "Präsentation" @@ -1713,13 +1723,13 @@ msgstr "Präsentation" msgid "Previous" msgstr "Vorherige" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "Quiz" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "Frage entfernen" @@ -1734,17 +1744,17 @@ msgstr "Überprüfen Sie die Fragen" msgid "See current quiz" msgstr "Aktuelles Quiz anzeigen" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format, fuzzy msgid "Select presentation" msgstr "Präsentation auswählen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format, fuzzy msgid "Show all messages" msgstr "Alle Nachrichten anzeigen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format, fuzzy msgid "Show instructions to join" msgstr "Beitrittsanweisungen anzeigen" @@ -1760,7 +1770,7 @@ msgstr "Ergebnisse anzeigen" msgid "Show results on presentation" msgstr "Ergebnisse in der Präsentation anzeigen" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "Dadurch werden alle zugehörigen Antworten und das Quiz selbst gelöscht. Sind Sie sicher?" @@ -1770,7 +1780,7 @@ msgstr "Dadurch werden alle zugehörigen Antworten und das Quiz selbst gelöscht msgid "Waiting for results..." msgstr "Warten auf Ergebnisse..." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "Ihre Frage" @@ -1788,7 +1798,7 @@ msgstr "Ihre Punktzahl" msgid "Export" msgstr "Exportieren" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "Als QTI (XML) exportieren" @@ -1848,17 +1858,21 @@ msgstr "Einzigartige Teilnehmer" msgid "Web Content" msgstr "Webinhalt" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "Aktiv" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "Mehr laden" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "Mit Ihnen geteilt" @@ -1868,17 +1882,17 @@ msgstr "Mit Ihnen geteilt" msgid "You must login to continue" msgstr "Sie müssen sich anmelden, um fortzufahren" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "muss mindestens eine richtige Antwort haben" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "Klicken Sie hier, um das Präsentationsfenster zu zeigen. Drucken Sie F im Präsentationsfenster, um den Vollbildmodus zu aktivieren." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous submissions" msgstr "Anonyme Einreichungen erlauben" @@ -1897,3 +1911,771 @@ msgstr "Anmelden" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "Gesamtanzahl der Einreichungen" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "Ein eindeutiger Code für Teilnehmer, um diesem Event beizutreten" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "Ein eindeutiger Name für dieses Event" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "Ein eindeutiger Name zur Identifikation dieses OIDC-Anbieters" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "Konto ist bestätigt und aktiv" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Optionen" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Aktiv" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "Sind Sie sicher, dass Sie dieses Event löschen möchten?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "Sind Sie sicher, dass Sie diesen Anbieter löschen möchten?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "Zugewiesener Benutzer" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Max. Zuschauer" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "Autorisierungscode" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "Abbrechen" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Datei ändern" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "Client-ID" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "Client-Secret" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "Abgeschlossen" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirmed" +msgstr "Bestätigt" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "Bestätigt am" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Veranstaltung erstellen" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "Anbieter erstellen" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Erstellen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Erstellen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Erstellen" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Aktuelles Quiz" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Löschen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "Anbieter löschen" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Löschen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "OIDC-Anbieter bearbeiten" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "Event bearbeiten" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "Anbieter bearbeiten" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Ändern" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "Diesen OIDC-Anbieter aktivieren" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "Client-ID eingeben" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "Client-Secret eingeben" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "Event-Code eingeben" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "Event-Name eingeben" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Aktuelles Passwort" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "Anbieter-Name eingeben" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "Benutzer-E-Mail eingeben" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "Event-Erstellung" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "Event erfolgreich erstellt" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "Event erfolgreich gelöscht" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "Event-Details" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "Event erfolgreich aktualisiert" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Veranstaltung" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "Events erfolgreich exportiert" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "Abgelaufen am" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "Datei ausgewählt" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Formulare" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "Fragment" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "Wie die Autorisierungsantwort zurückgegeben werden soll (Standard ist 'query')" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "Hybrid" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "Implizit" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Aktiv" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "Anfangspasswort für den Benutzer" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "Aussteller" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "Aussteller-URL" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "Letzte 30 Tage" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "Zuletzt aktualisiert" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "Neues Event" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "Keine Events gefunden" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "Keine Datei ausgewählt" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "Kein Besitzer" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "Keine Rolle" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "Keine Benutzer gefunden" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "Nicht abgelaufen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "Nicht gestartet" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "OAuth 2.0 Antworttyp (Standard ist 'code')" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "Anbieter" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "OIDC-Anbieter-Details" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "Anbieter" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "OIDC-Bereiche, die angefordert werden sollen (Standard ist 'openid email profile')" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "Besitzer" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "Anbieter erfolgreich erstellt" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "Anbieter erfolgreich aktualisiert" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "Query" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "Aktuelle Events" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "Umleitungs-URI" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "Antwortmodus" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "Antworttyp" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "Rolle" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "Speichern..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "Geplant" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "Bereich" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "Events suchen..." + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "Nach einem Benutzer suchen..." + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "Anbieter suchen..." + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "Benutzer suchen..." + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Wählen Sie eine Option aus" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "Auswählen..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "Startdatum" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "Gestartet am" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "Status" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "Die OIDC-Aussteller-URL (muss mit http:// oder https:// beginnen)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "Die Callback-URL für Ihre Anwendung (muss mit http:// oder https:// beginnen)" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "Der Benutzer, der dieses Event besitzt (erforderlich)" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "Events insgesamt" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "Benutzer insgesamt" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "Unbestätigt" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "Event aktualisieren" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "Anbieter aktualisieren" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "Benutzer aktualisieren" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "Benutzerkonto" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "Benutzerwachstum" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "Benutzer erfolgreich erstellt" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "Benutzer erfolgreich gelöscht" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "Benutzer-Details" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "Benutzer erfolgreich aktualisiert" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "Zugriffsebene des Benutzers" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "E-Mail-Adresse des Benutzers (muss eindeutig sein)" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "Benutzer" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "Benutzer erfolgreich exportiert" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "Event anzeigen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Bericht ansehen" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "Benutzer anzeigen" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "Wann dieses Event abläuft (optional)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "Ob dieser Anbieter derzeit aktiv und für die Authentifizierung verfügbar ist" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "Teilnehmer" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "https://example.com" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "https://yourapp.com/auth/callback" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "openid email profile" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "vs. letzter Monat" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to events" +msgstr "Zurück zu Events" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to providers" +msgstr "Zurück zu Anbietern" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to users" +msgstr "Zurück zu Benutzern" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "New provider" +msgstr "Neuer Anbieter" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format, fuzzy +msgid "New user" +msgstr "Neuer Benutzer" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format, fuzzy +msgid "No providers found" +msgstr "Keine Anbieter gefunden" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider deleted successfully" +msgstr "Anbieter erfolgreich gelöscht" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Anbieter" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "Admin" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "Zurück zur App" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "E-Mail bestätigen" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Wenn Sie kein Konto bei uns erstellt haben, ignorieren Sie dies bitte." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Sie können Ihre E-Mail-Adresse ändern, indem Sie die folgende URL aufrufen" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Teilnehmerzahl ausblenden" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Teilnehmerzahl anzeigen" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Erforderlich" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(optional)" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index d9f633e..08e38f4 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -10,15 +10,18 @@ msgid "" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -45,7 +48,10 @@ msgstr "" msgid "Change" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "" @@ -56,7 +62,7 @@ msgstr "" msgid "Email address" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "" @@ -99,15 +105,18 @@ msgstr "" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "" @@ -124,7 +133,7 @@ msgid "seconds" msgstr "" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "" @@ -177,47 +186,50 @@ msgstr "" msgid "Created successfully" msgstr "" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -261,12 +273,6 @@ msgstr "" msgid "CONFIRM EMAIL" msgstr "" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -297,9 +303,9 @@ msgid "Presentation uploaded" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "" @@ -334,17 +340,17 @@ msgstr "" msgid "Change file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "" @@ -359,18 +365,18 @@ msgstr "" msgid "Upload failed" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -393,18 +399,18 @@ msgstr "" msgid "Vote" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "" @@ -414,7 +420,7 @@ msgstr "" msgid "Processing your file..." msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "" @@ -424,14 +430,14 @@ msgstr "" msgid "Ask, comment..." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "" @@ -446,7 +452,7 @@ msgstr "" msgid "The site is under maintenance, we'll be back very soon!" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "" @@ -460,13 +466,8 @@ msgstr "" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "" @@ -624,6 +625,7 @@ msgstr "" msgid "Create account" msgstr "" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -659,14 +661,14 @@ msgstr "" msgid "Your password has been updated." msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "" msgstr[1] "" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "" @@ -676,34 +678,41 @@ msgstr "" msgid "Current form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "" @@ -724,17 +733,17 @@ msgstr "" msgid "Submit" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "" @@ -744,7 +753,7 @@ msgstr "" msgid "Title of your form" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "" @@ -759,7 +768,7 @@ msgstr "" msgid "Select one or multiple options" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "" @@ -769,12 +778,12 @@ msgstr "" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "" @@ -823,7 +832,7 @@ msgstr "" msgid "Account creation is disabled" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "" @@ -874,12 +883,12 @@ msgstr "" msgid "Current web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "" @@ -889,7 +898,7 @@ msgstr "" msgid "See current web content" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format msgid "This will delete the web content, are you sure?" msgstr "" @@ -900,8 +909,8 @@ msgstr "" msgid "Title" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "" @@ -918,17 +927,17 @@ msgstr "" msgid "Pinned" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "" @@ -969,7 +978,7 @@ msgstr "" msgid "Saved" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "" @@ -984,22 +993,22 @@ msgstr "" msgid "Attendees room" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format msgid "Delete account" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "" @@ -1014,7 +1023,7 @@ msgstr "" msgid "Your account has been deleted." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format msgid "Access code" msgstr "" @@ -1024,46 +1033,46 @@ msgstr "" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format msgid "Attendees interactions" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format msgid "Facilitators" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format msgid "Finish" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1076,57 +1085,57 @@ msgstr "" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format msgid "Time to launch your presentation!" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format msgid "Create event" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format msgid "Create your first event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "" @@ -1136,18 +1145,18 @@ msgstr "" msgid "Live" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format msgid "Name of your event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "Note: Facilitators do not have the ability to delete your event." msgstr "" @@ -1157,12 +1166,12 @@ msgstr "" msgid "Presentation file (optional)" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "" @@ -1172,7 +1181,7 @@ msgstr "" msgid "Return to your last event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Select the start date for your event. Future dates are permissible." msgstr "" @@ -1182,22 +1191,22 @@ msgstr "" msgid "Select your presentation (optional)" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "" -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format msgid "Welcome to Claper! You can create a new event here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format msgid "When your event will start?" msgstr "" @@ -1207,8 +1216,8 @@ msgstr "" msgid "Create your next presentation with" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1219,7 +1228,7 @@ msgstr "" msgid "Customize your account" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "" @@ -1239,22 +1248,22 @@ msgstr "" msgid "Question" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "" @@ -1264,7 +1273,8 @@ msgstr "" msgid "Event manager" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "" @@ -1280,7 +1290,7 @@ msgstr "" msgid "Your personal informations to access your account" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format msgid "Enable reactions" msgstr "" @@ -1336,43 +1346,43 @@ msgid "Add Claper" msgstr "" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format msgid "Create your first interaction." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format msgid "Disable" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format msgid "Enable messages to change this option" msgstr "" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "" @@ -1399,7 +1409,7 @@ msgstr "" msgid "The account has been unlinked." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "" @@ -1410,12 +1420,12 @@ msgstr "" msgid "Unlink" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "" @@ -1440,12 +1450,12 @@ msgstr "" msgid "Your password has been set, you can now unlink your account." msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "" @@ -1471,24 +1481,24 @@ msgstr "" msgid "Please enter valid HTML content with an iframe tag" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format msgid "Attendees can view the web content on their device" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "" @@ -1556,12 +1566,12 @@ msgstr "" msgid "More options" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "" @@ -1611,32 +1621,32 @@ msgstr "" msgid "back to the home page" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format msgid "Add Question" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format msgid "Allow anonymous messages" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format msgid "Attendees" msgstr "" @@ -1652,32 +1662,32 @@ msgstr "" msgid "Current quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format msgid "Deny anonymous messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format msgid "Disable messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format msgid "Disable reactions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format msgid "Edit quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format msgid "Hide messages" msgstr "" @@ -1700,12 +1710,12 @@ msgstr "" msgid "Interaction" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format msgid "Presentation" msgstr "" @@ -1715,13 +1725,13 @@ msgstr "" msgid "Previous" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "" @@ -1736,17 +1746,17 @@ msgstr "" msgid "See current quiz" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format msgid "Show all messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format msgid "Show instructions to join" msgstr "" @@ -1762,7 +1772,7 @@ msgstr "" msgid "Show results on presentation" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "" @@ -1772,7 +1782,7 @@ msgstr "" msgid "Waiting for results..." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "" @@ -1790,7 +1800,7 @@ msgstr "" msgid "Export" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "" @@ -1850,17 +1860,21 @@ msgstr "" msgid "Web Content" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "" @@ -1870,17 +1884,17 @@ msgstr "" msgid "You must login to continue" msgstr "" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format msgid "Allow anonymous submissions" msgstr "" @@ -1899,3 +1913,771 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Actions" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Active Events" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this event?" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this provider?" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this user?" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format +msgid "Audience Peak" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format +msgid "Choose file" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format +msgid "Confirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Create Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Create User" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format +msgid "Created" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format +msgid "Created At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format +msgid "Currently running" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format +msgid "Delete event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format +msgid "Delete user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter password" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format +msgid "Events" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format +msgid "Form Post" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format +msgid "Inactive" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format +msgid "OIDC Providers" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format +msgid "Provider updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format +msgid "Select an option" +msgstr "" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "User updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format +msgid "View provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format +msgid "attendees" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format +msgid "Back to events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "Back to providers" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format +msgid "Back to users" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format +msgid "New provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format +msgid "New user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format +msgid "No providers found" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format +msgid "Provider deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format +msgid "Provider details" +msgstr "" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Confirm email change" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format +msgid "If you didn't request an email change, please ignore this." +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can confirm your email change by visiting the URL below" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format +msgid "Show attendee count" +msgstr "" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index ec7431c..49ce3b1 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -8,15 +8,18 @@ msgstr "" "Language: en\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -43,7 +46,10 @@ msgstr "" msgid "Change" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "" @@ -54,7 +60,7 @@ msgstr "" msgid "Email address" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "" @@ -97,15 +103,18 @@ msgstr "" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "" @@ -122,7 +131,7 @@ msgid "seconds" msgstr "" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "" @@ -175,47 +184,50 @@ msgstr "" msgid "Created successfully" msgstr "" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -259,12 +271,6 @@ msgstr "" msgid "CONFIRM EMAIL" msgstr "" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -295,9 +301,9 @@ msgid "Presentation uploaded" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "" @@ -332,17 +338,17 @@ msgstr "" msgid "Change file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "" @@ -357,18 +363,18 @@ msgstr "" msgid "Upload failed" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -391,18 +397,18 @@ msgstr "" msgid "Vote" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "" @@ -412,7 +418,7 @@ msgstr "" msgid "Processing your file..." msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "" @@ -422,14 +428,14 @@ msgstr "" msgid "Ask, comment..." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "" @@ -444,7 +450,7 @@ msgstr "" msgid "The site is under maintenance, we'll be back very soon!" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "" @@ -458,13 +464,8 @@ msgstr "" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "" @@ -622,6 +623,7 @@ msgstr "" msgid "Create account" msgstr "" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -657,14 +659,14 @@ msgstr "" msgid "Your password has been updated." msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "" msgstr[1] "" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "" @@ -674,34 +676,41 @@ msgstr "" msgid "Current form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "" @@ -722,17 +731,17 @@ msgstr "" msgid "Submit" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "" @@ -742,7 +751,7 @@ msgstr "" msgid "Title of your form" msgstr "" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "" @@ -757,7 +766,7 @@ msgstr "" msgid "Select one or multiple options" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "" @@ -767,12 +776,12 @@ msgstr "" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "" @@ -821,7 +830,7 @@ msgstr "" msgid "Account creation is disabled" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "" @@ -872,12 +881,12 @@ msgstr "" msgid "Current web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "" @@ -887,7 +896,7 @@ msgstr "" msgid "See current web content" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format msgid "This will delete the web content, are you sure?" msgstr "" @@ -898,8 +907,8 @@ msgstr "" msgid "Title" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "" @@ -916,17 +925,17 @@ msgstr "" msgid "Pinned" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "" @@ -967,7 +976,7 @@ msgstr "" msgid "Saved" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "" @@ -982,22 +991,22 @@ msgstr "" msgid "Attendees room" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format, fuzzy msgid "Delete account" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "" @@ -1012,7 +1021,7 @@ msgstr "" msgid "Your account has been deleted." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format, fuzzy msgid "Access code" msgstr "" @@ -1022,46 +1031,46 @@ msgstr "" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees interactions" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators" msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Finish" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "" #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1074,57 +1083,57 @@ msgstr "" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format, fuzzy msgid "Time to launch your presentation!" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format, fuzzy msgid "Create event" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "" @@ -1134,18 +1143,18 @@ msgstr "" msgid "Live" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format, fuzzy msgid "Name of your event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "Note: Facilitators do not have the ability to delete your event." msgstr "" @@ -1155,12 +1164,12 @@ msgstr "" msgid "Presentation file (optional)" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "" @@ -1170,7 +1179,7 @@ msgstr "" msgid "Return to your last event" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Select the start date for your event. Future dates are permissible." msgstr "" @@ -1180,22 +1189,22 @@ msgstr "" msgid "Select your presentation (optional)" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format, fuzzy msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "" -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format, fuzzy msgid "Welcome to Claper! You can create a new event here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format, fuzzy msgid "When your event will start?" msgstr "" @@ -1205,8 +1214,8 @@ msgstr "" msgid "Create your next presentation with" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1217,7 +1226,7 @@ msgstr "" msgid "Customize your account" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "" @@ -1237,22 +1246,22 @@ msgstr "" msgid "Question" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "" @@ -1262,7 +1271,8 @@ msgstr "" msgid "Event manager" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "" @@ -1278,7 +1288,7 @@ msgstr "" msgid "Your personal informations to access your account" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format, fuzzy msgid "Enable reactions" msgstr "" @@ -1334,43 +1344,43 @@ msgid "Add Claper" msgstr "" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first interaction." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format, fuzzy msgid "Disable" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format, fuzzy msgid "Enable messages to change this option" msgstr "" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "" @@ -1397,7 +1407,7 @@ msgstr "" msgid "The account has been unlinked." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "" @@ -1408,12 +1418,12 @@ msgstr "" msgid "Unlink" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "" @@ -1438,12 +1448,12 @@ msgstr "" msgid "Your password has been set, you can now unlink your account." msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "" @@ -1469,24 +1479,24 @@ msgstr "" msgid "Please enter valid HTML content with an iframe tag" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees can view the web content on their device" msgstr "" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "" @@ -1554,12 +1564,12 @@ msgstr "" msgid "More options" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "" @@ -1609,32 +1619,32 @@ msgstr "" msgid "back to the home page" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format, fuzzy msgid "Add Question" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous messages" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "" @@ -1650,32 +1660,32 @@ msgstr "" msgid "Current quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format, fuzzy msgid "Deny anonymous messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format, fuzzy msgid "Disable messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format, fuzzy msgid "Disable reactions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format, fuzzy msgid "Edit quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format, fuzzy msgid "Hide messages" msgstr "" @@ -1698,12 +1708,12 @@ msgstr "" msgid "Interaction" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "" @@ -1713,13 +1723,13 @@ msgstr "" msgid "Previous" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "" @@ -1734,17 +1744,17 @@ msgstr "" msgid "See current quiz" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format, fuzzy msgid "Select presentation" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format, fuzzy msgid "Show all messages" msgstr "" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format, fuzzy msgid "Show instructions to join" msgstr "" @@ -1760,7 +1770,7 @@ msgstr "" msgid "Show results on presentation" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "" @@ -1770,7 +1780,7 @@ msgstr "" msgid "Waiting for results..." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "" @@ -1788,7 +1798,7 @@ msgstr "" msgid "Export" msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "" @@ -1848,17 +1858,21 @@ msgstr "" msgid "Web Content" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "" @@ -1868,17 +1882,17 @@ msgstr "" msgid "You must login to continue" msgstr "" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous submissions" msgstr "" @@ -1897,3 +1911,771 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to providers" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to users" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "New provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format, fuzzy +msgid "New user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format, fuzzy +msgid "No providers found" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "" diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po index 178d439..db4b4c7 100644 --- a/priv/gettext/es/LC_MESSAGES/default.po +++ b/priv/gettext/es/LC_MESSAGES/default.po @@ -8,15 +8,18 @@ msgstr "" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Configuración" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -43,7 +46,10 @@ msgstr "Uy, comprueba que todos los campos estén correctamente rellenados." msgid "Change" msgstr "Cambiar" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "Código" @@ -54,7 +60,7 @@ msgstr "Código" msgid "Email address" msgstr "Dirección email" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Salir" @@ -97,15 +103,18 @@ msgstr "¡Sé el primero en reaccionar!" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "Unirse" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Panel" @@ -122,7 +131,7 @@ msgid "seconds" msgstr "segundos" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Finalizado" @@ -175,47 +184,50 @@ msgstr "Volver a principal" msgid "Created successfully" msgstr "Creado exitosamente" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Editar" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "Crear" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Borrar" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -259,12 +271,6 @@ msgstr "Instrucciones de actualización de correo" msgid "CONFIRM EMAIL" msgstr "CONFIRMAR EMAIL" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "Confirmar email" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -295,9 +301,9 @@ msgid "Presentation uploaded" msgstr "Presentación subida" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Borrar" @@ -332,17 +338,17 @@ msgstr "Tu fichero es demasiado grande" msgid "Change file" msgstr "Cambiar fichero" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Presentación sustituida" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Editar votación" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Nueva votación" @@ -357,18 +363,18 @@ msgstr "Título de tu votación" msgid "Upload failed" msgstr "Subida fallida" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "Añadir una votación para conocer la opinión del público." -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Votación" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -391,18 +397,18 @@ msgstr "Ver la votación actual" msgid "Vote" msgstr "Votar" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Dirección email del usuario" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "Hacer cambios en tu fichero borrará todos los elementos de interacción asociados, incluyendo votaciones" -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Los mensajes de los asistentes aparecerán aquí." @@ -412,7 +418,7 @@ msgstr "Los mensajes de los asistentes aparecerán aquí." msgid "Processing your file..." msgstr "Procesando tu fichero..." -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "Esto borrará todas las respuestas asociadas y la propia votación, ¿estás seguro/a?" @@ -422,14 +428,14 @@ msgstr "Esto borrará todas las respuestas asociadas y la propia votación, ¿es msgid "Ask, comment..." msgstr "Pregunta, deja comentarios..." -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Mensajes" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Añadir colaborador" @@ -444,7 +450,7 @@ msgstr "Uy, la página no existe." msgid "The site is under maintenance, we'll be back very soon!" msgstr "El sitio está en mantenimiento, ¡volveremos muy pronto!" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "Los colaboradores pueden presentar y gestionar las interacciones" @@ -458,13 +464,8 @@ msgstr "Los colaboradores pueden presentar y gestionar las interacciones" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "Si tienes problemas con el botón superior, copia y pega la URL de debajo en tu navegador" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "Puedes cambiar tu correo visitando la URL de debajo" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "Añadir interacción" @@ -496,7 +497,7 @@ msgstr ", pulsa en el enlace proporcionado para conectar (¡comprueba tu bandeja #: lib/claper_web/templates/user_notifier/welcome.html.heex:29 #, elixir-autogen, elixir-format msgid "Export your current presentation to PDF from your favorite slide presentation software (PowerPoint, etc)" -msgstr "" +msgstr "Exporta tu presentación actual a PDF desde tu software de presentación favorito (PowerPoint, etc)" #: lib/claper_web/templates/user_notifier/welcome.html.heex:50 #, elixir-autogen, elixir-format @@ -591,7 +592,7 @@ msgstr "Nivel de participación" #: lib/claper_web/live/event_live/event_card_component.ex:282 #, elixir-autogen, elixir-format msgid "Error when processing the file" -msgstr "" +msgstr "Error al procesar el archivo" #: lib/claper_web/live/event_live/join.html.heex:24 #: lib/claper_web/live/event_live/join.html.heex:47 @@ -622,6 +623,7 @@ msgstr "O usa el código:" msgid "Create account" msgstr "Crear cuenta" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -657,14 +659,14 @@ msgstr "Actualizar tu contraseña" msgid "Your password has been updated." msgstr "Tu contraseña ha sido actualizada." -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "Campo %{count}" msgstr[1] "Campos %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "Añadir formulario para recopilar datos del público." @@ -674,34 +676,41 @@ msgstr "Añadir formulario para recopilar datos del público." msgid "Current form" msgstr "Formulario actual" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "Editar formulario" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formulario" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Envíos de formulario" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "Los envíos de formulario de los asistentes aparecerán aquí." -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "Nombre" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "Nuevo formulario" @@ -722,17 +731,17 @@ msgstr "Ver formulario actual" msgid "Submit" msgstr "Enviar" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "Texto" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Esto no se puede deshacer, ¿estás seguro/a?" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "Esto borrará todas las respuestas asociadas al formulario, ¿estás seguro/a?" @@ -742,7 +751,7 @@ msgstr "Esto borrará todas las respuestas asociadas al formulario, ¿estás seg msgid "Title of your form" msgstr "Título de tu formulario" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "Tipo" @@ -757,7 +766,7 @@ msgstr "Seleccione una opción" msgid "Select one or multiple options" msgstr "Seleccione una o varias opciones" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "Respuestas múltiples" @@ -767,12 +776,12 @@ msgstr "Respuestas múltiples" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX de hasta %{size} MB" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Activar mensajes" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Mostrar mensajes" @@ -821,7 +830,7 @@ msgstr "desactivada" msgid "Account creation is disabled" msgstr "La creación de cuentas está desactivada" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Agregar vídeo de Youtube o cualquier contenido web." @@ -872,12 +881,12 @@ msgstr "Enviar enlace para restablecer contraseña" msgid "Current web content" msgstr "Contenido actual" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Editar contenido web" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Nuevo contenido web" @@ -887,7 +896,7 @@ msgstr "Nuevo contenido web" msgid "See current web content" msgstr "Ver contenido web actual" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format msgid "This will delete the web content, are you sure?" msgstr "Esto borrará el contenido web, ¿estás seguro/a?" @@ -898,8 +907,8 @@ msgstr "Esto borrará el contenido web, ¿estás seguro/a?" msgid "Title" msgstr "Título" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Contenido" @@ -916,17 +925,17 @@ msgstr "Anclar" msgid "Pinned" msgstr "Anclado" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "Mensajes anclados" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Los mensajes anclados aparecerán aquí." -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Mostrar sólo mensajes anclados" @@ -967,7 +976,7 @@ msgstr "Has sido invitado/a a gestionar un evento" msgid "Saved" msgstr "Guardado" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "Todos tus eventos y ficheros serán borrados para siempre, ¿estás seguro/a?" @@ -982,22 +991,22 @@ msgstr "¿Estás seguro de que quieres finalizar este evento? Esta acción no pu msgid "Attendees room" msgstr "Sala de asistentes" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "Ten cuidado, estas acciones son irreversibles" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "Zona de peligro" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format, fuzzy msgid "Delete account" msgstr "Borrar cuenta" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "Abrir presentación" @@ -1012,7 +1021,7 @@ msgstr "Informe de visualización" msgid "Your account has been deleted." msgstr "Tu cuenta ha sido borrada" -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format, fuzzy msgid "Access code" msgstr "Código de acceso" @@ -1022,46 +1031,46 @@ msgstr "Código de acceso" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "No se soportan las animaciones de los ficheros PPT/PPTX, por lo que te recomendamos exportar tus presentaciones a formato PDF para tener la seguridad de que se mostrarán correctamente." -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees interactions" msgstr "Interacciones de asistentes" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "Atrás" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators" msgstr "Colaboradores" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Finish" msgstr "Finalizar" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "Aquí encontrarás todas las interacciones de tus asistentes. Puedes gestionar mensajes, mensajes anclados y formularios enviados." -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "Identificar usuarios por sus avatares únicos." #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1074,57 +1083,57 @@ msgstr "Siguiente" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "Selecciona tu fichero de presentación. Los formatos aceptados son PDF, PPT, o PPTX. Asegúrate de que el tamaño del fichero no excede el límite máximo." -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format, fuzzy msgid "Time to launch your presentation!" msgstr "¡Es el momento de lanzar tu presentación!" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "Usa los atajos de teclado asociados para conmutar estos ajustes." -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "Puedes controlar cada ajuste para la presentación (lo que se muestra en la pantalla grande) y en la sala de asistentes." -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "Tus primeros pasos con Claper" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "Los asistentes que intenten acceder al evento antes de esta fecha serán dirigidos a una sala de espera." -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format, fuzzy msgid "Create event" msgstr "Crear evento" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first event" msgstr "Crear tu primer evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "Fecha de inicio del evento" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "Si no tienes tiempo y sólo quieres interactuar sin ningún fichero de presentación, puedes crear un evento nuevo aquí." -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "Si necesitas ayuda para gestionar tu evento, puedes conceder acceso a otros. Simplemente, introduce su dirección de correo; una vez que registren una cuenta con esos correos, serán capaces de gestionar el evento." -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "¿ Tienes prisa ?" @@ -1134,18 +1143,18 @@ msgstr "¿ Tienes prisa ?" msgid "Live" msgstr "En vivo" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "Mis eventos" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format, fuzzy msgid "Name of your event" msgstr "Nombre de tu evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "Note: Facilitators do not have the ability to delete your event." msgstr "Nota: Los colaboradores no tienen capacidad para borrar tu evento." @@ -1155,12 +1164,12 @@ msgstr "Nota: Los colaboradores no tienen capacidad para borrar tu evento." msgid "Presentation file (optional)" msgstr "Fichero de presentación (opcional)" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "Evento rápido" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "Evento rápido creado con éxito" @@ -1170,7 +1179,7 @@ msgstr "Evento rápido creado con éxito" msgid "Return to your last event" msgstr "Volver a tu último evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Select the start date for your event. Future dates are permissible." msgstr "Selecciona la fecha de inicio de tu evento. Se permiten fechas futuras." @@ -1180,22 +1189,22 @@ msgstr "Selecciona la fecha de inicio de tu evento. Se permiten fechas futuras." msgid "Select your presentation (optional)" msgstr "Selecciona tu presentación (opcional)" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format, fuzzy msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "Este código será usado por tus asistentes para acceder al evento. Tienes la opción de crear un código personalizado." -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "Este evento ha sido terminado" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format, fuzzy msgid "Welcome to Claper! You can create a new event here." msgstr "¡Bienvenido/a a Claper! Aquí puedes crear un nuevo evento." -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format, fuzzy msgid "When your event will start?" msgstr "¿Cuándo empezará tu evento?" @@ -1205,8 +1214,8 @@ msgstr "¿Cuándo empezará tu evento?" msgid "Create your next presentation with" msgstr "Crea tu siguiente presentación con" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1217,7 +1226,7 @@ msgstr "El evento no existe" msgid "Customize your account" msgstr "Personaliza tu cuenta" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "Idioma" @@ -1237,22 +1246,22 @@ msgstr "Tus preferencias han sido actualizadas." msgid "Question" msgstr "Pregunta" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "Preguntas" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "Las preguntas aparecerán aquí." -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "Ordenar por fecha" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "Ordenar por popularidad" @@ -1262,7 +1271,8 @@ msgstr "Ordenar por popularidad" msgid "Event manager" msgstr "Gestor de evento" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "Documentación" @@ -1278,7 +1288,7 @@ msgstr "Mi cuenta" msgid "Your personal informations to access your account" msgstr "Tus información personal para acceder a tu cuenta" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format, fuzzy msgid "Enable reactions" msgstr "Activar reacciones" @@ -1334,43 +1344,43 @@ msgid "Add Claper" msgstr "Agregar Claper" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "Cerrar vista previa" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first interaction." msgstr "Crea tu primera interacción." -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format, fuzzy msgid "Disable" msgstr "Desactivar" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "Activar" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format, fuzzy msgid "Enable messages to change this option" msgstr "Activar mensajes para cambiar esta opción" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "Abrir vista previa" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "Mostrar mensajes para cambiar esta opción" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "Esta diapositiva no tiene interacciones." @@ -1397,7 +1407,7 @@ msgstr "Iniciar sesión con %{provider}" msgid "The account has been unlinked." msgstr "La cuenta ha sido desvinculada." -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "Esta sección contiene todas tus interacciones." @@ -1408,12 +1418,12 @@ msgstr "Esta sección contiene todas tus interacciones." msgid "Unlink" msgstr "Desvincular" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "Puedes añadir interacciones a tus diapositivas de presentación." -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "Tus interacciones" @@ -1438,12 +1448,12 @@ msgstr "Establece una nueva contraseña para tu cuenta antes de desvincularla." msgid "Your password has been set, you can now unlink your account." msgstr "Tu contraseña ha sido establecida, ahora puedes desvincular tu cuenta." -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "Código Iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "Enlace al contenido" @@ -1469,24 +1479,24 @@ msgstr "Por favor, introduce un enlace válido que comience con http:// o https: msgid "Please enter valid HTML content with an iframe tag" msgstr "Por favor, introduce contenido HTML válido con una etiqueta iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "Proveedor" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "Los asistentes pueden ver los resultados en su dispositivo" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees can view the web content on their device" msgstr "Los asistentes pueden ver el contenido web en su dispositivo" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "Opciones" @@ -1554,12 +1564,12 @@ msgstr "Finalizar" msgid "More options" msgstr "Más opciones" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "No" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "Sí" @@ -1609,32 +1619,32 @@ msgstr "Puedes restablecer tu contraseña visitando la URL de abajo" msgid "back to the home page" msgstr "volver a la página de inicio" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format, fuzzy msgid "Add Question" msgstr "Añadir Pregunta" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "Añadir un cuestionario para evaluar conocimientos." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "Añadir respuesta" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous messages" msgstr "Permitir mensajes anónimos" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "Respuesta %{index}" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "Asistentes" @@ -1650,32 +1660,32 @@ msgstr "Puntuación media" msgid "Current quiz" msgstr "Cuestionario actual" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format, fuzzy msgid "Deny anonymous messages" msgstr "Denegar mensajes anónimos" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format, fuzzy msgid "Disable messages" msgstr "Desactivar mensajes" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format, fuzzy msgid "Disable reactions" msgstr "Desactivar reacciones" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format, fuzzy msgid "Edit quiz" msgstr "Editar cuestionario" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "Ocultar instrucciones para unirse" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format, fuzzy msgid "Hide messages" msgstr "Ocultar mensajes" @@ -1698,12 +1708,12 @@ msgstr "¿Cómo funciona?" msgid "Interaction" msgstr "Interacción" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "Nuevo cuestionario" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "Presentación" @@ -1713,13 +1723,13 @@ msgstr "Presentación" msgid "Previous" msgstr "Anterior" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "Cuestionario" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "Eliminar pregunta" @@ -1734,17 +1744,17 @@ msgstr "Revise las preguntas" msgid "See current quiz" msgstr "Ver cuestionario actual" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format, fuzzy msgid "Select presentation" msgstr "Seleccionar presentación" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format, fuzzy msgid "Show all messages" msgstr "Mostrar todos los mensajes" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format, fuzzy msgid "Show instructions to join" msgstr "Mostrar instrucciones para unirse" @@ -1760,7 +1770,7 @@ msgstr "Mostrar resultados" msgid "Show results on presentation" msgstr "Mostrar resultados en la presentación" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "Esto eliminará todas las respuestas asociadas y el cuestionario en sí, ¿estás seguro?" @@ -1770,7 +1780,7 @@ msgstr "Esto eliminará todas las respuestas asociadas y el cuestionario en sí, msgid "Waiting for results..." msgstr "Esperando resultados..." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "Tu pregunta" @@ -1788,7 +1798,7 @@ msgstr "Tu puntuación" msgid "Export" msgstr "Exportar" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "Exportar a QTI (XML)" @@ -1848,17 +1858,21 @@ msgstr "Asistentes únicos" msgid "Web Content" msgstr "Contenido web" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "Activo" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "Cargar más" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "Compartido contigo" @@ -1868,17 +1882,17 @@ msgstr "Compartido contigo" msgid "You must login to continue" msgstr "Debes iniciar sesión para continuar" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "debe tener al menos una respuesta correcta" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "Pulsa aqui para abrir la ventana de presentación. Pulsa F en la ventana de presentación para activar el modo pantalla completa." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous submissions" msgstr "Permitir envíos anónimos" @@ -1897,3 +1911,771 @@ msgstr "Iniciar sesión" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "Total de envíos" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "Un código único para que los participantes se unan a este evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "Un nombre único para este evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "Un nombre único para identificar este proveedor OIDC" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "La cuenta está confirmada y activa" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Opciones" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Activo" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "¿Estás seguro de que quieres desvincular esta cuenta?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "¿Estás seguro de que quieres desvincular esta cuenta?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "¿Estás seguro de que quieres desvincular esta cuenta?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "Usuario Asignado" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Pico de audiencia" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "Código de Autorización" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "Cancelar" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Cambiar fichero" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "ID de Cliente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "Secreto de Cliente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "Completado" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirmed" +msgstr "Confirmar email" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "Confirmado el" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Crear evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "Crear Proveedor" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Crear" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Crear" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Crear" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Cuestionario actual" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Borrar" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "Eliminar proveedor" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Borrar" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "Editar Proveedor OIDC" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "Editar evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "Editar proveedor" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Editar" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "Activar este proveedor OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "Ingresa el ID de cliente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "Ingresa el secreto de cliente" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "Ingresa el código del evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "Ingresa el nombre del evento" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Contraseña actual" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "Ingresa el nombre del proveedor" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "Ingresa el email del usuario" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "Creación de Eventos" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "Evento creado exitosamente" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "Evento eliminado exitosamente" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "Detalles del evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "Evento actualizado exitosamente" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Evento" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "Eventos exportados exitosamente" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "Expira el" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "Archivo seleccionado" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Formularios" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "Fragmento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "Cómo debe devolverse la respuesta de autorización (por defecto 'query')" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "Híbrido" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "Implícito" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Activo" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "Contraseña inicial para el usuario" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "Emisor" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "URL del Emisor" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "Últimos 30 días" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "Última Actualización" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "Nuevo evento" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "No se encontraron eventos" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "Ningún archivo seleccionado" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "Sin propietario" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "Sin rol" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "No se encontraron usuarios" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "No expirado" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "No iniciado" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "Tipo de respuesta OAuth 2.0 (por defecto 'code')" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "Proveedor" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "Detalles del Proveedor OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "Proveedor" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "Alcances OIDC a solicitar (por defecto 'openid email profile')" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "Propietario" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "Proveedor creado exitosamente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "Contraseña actualizada con éxito." + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "Consulta" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "Eventos Recientes" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "URI de Redirección" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "Modo de Respuesta" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "Tipo de Respuesta" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "Rol" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "Guardando..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "Programado" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "Alcance" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "Buscar eventos..." + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "Buscar un usuario..." + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "Buscar proveedores..." + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "Buscar usuarios..." + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Seleccione una opción" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "Seleccionar..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "Fecha de Inicio" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "Iniciado el" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "Estado" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "La URL del emisor OIDC (debe comenzar con http:// o https://)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "La URL de callback para tu aplicación (debe comenzar con http:// o https://)" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "El usuario propietario de este evento (requerido)" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "Total de Eventos" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "Total de Usuarios" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "Sin confirmar" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "Actualizar Evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "Actualizar Proveedor" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "Actualizar Usuario" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "Cuenta de Usuario" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "Crecimiento de Usuarios" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "Usuario creado exitosamente" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "Usuario eliminado exitosamente" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "Detalles del usuario" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "Contraseña actualizada con éxito." + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "Nivel de acceso del usuario" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "Dirección de email del usuario (debe ser única)" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "Usuarios" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "Usuarios exportados exitosamente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "Ver evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Informe de visualización" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "Ver usuario" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "Cuándo expira este evento (opcional)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "Si este proveedor está activo y disponible para autenticación" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "asistente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "https://example.com" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "https://yourapp.com/auth/callback" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "openid email profile" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "vs mes anterior" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to events" +msgstr "Volver a eventos" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to providers" +msgstr "Volver a proveedores" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to users" +msgstr "Volver a usuarios" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "New provider" +msgstr "Nuevo proveedor" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format, fuzzy +msgid "New user" +msgstr "Nuevo usuario" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format, fuzzy +msgid "No providers found" +msgstr "No se encontraron proveedores" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider deleted successfully" +msgstr "Proveedor eliminado exitosamente" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Proveedor" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "Admin" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "Volver a la aplicación" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "Confirmar email" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Si no has creado una cuenta con nosotros, por favor ignora ésto." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Puedes cambiar tu correo visitando la URL de debajo" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Ocultar número de asistentes" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Mostrar número de asistentes" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Obligatorio" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(opcional)" diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po index ebedd40..da8c14f 100644 --- a/priv/gettext/fr/LC_MESSAGES/default.po +++ b/priv/gettext/fr/LC_MESSAGES/default.po @@ -8,15 +8,18 @@ msgstr "" "Language: fr\n" "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Paramètres" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -43,7 +46,10 @@ msgstr "Oups, vérifiez que tous les champs sont remplis correctement." msgid "Change" msgstr "Changer" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "Code" @@ -54,7 +60,7 @@ msgstr "Code" msgid "Email address" msgstr "Adresse email" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Déconnexion" @@ -97,15 +103,18 @@ msgstr "Soyez le premier à réagir !" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "Rejoindre" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Tableau de bord" @@ -122,7 +131,7 @@ msgid "seconds" msgstr "secondes" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Terminé" @@ -173,49 +182,52 @@ msgstr "Retourner à l'accueil" #: lib/claper_web/live/event_live/event_form_component.ex:248 #, elixir-autogen, elixir-format msgid "Created successfully" -msgstr "Mis à jour avec succès" +msgstr "Créé avec succès" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Modifier" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "Créer" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Supprimer" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -259,12 +271,6 @@ msgstr "Instructions de modification d'email" msgid "CONFIRM EMAIL" msgstr "CONFIRMER L'EMAIL" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "Confirmer l'email" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -295,9 +301,9 @@ msgid "Presentation uploaded" msgstr "Présentation chargée" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Supprimer" @@ -332,17 +338,17 @@ msgstr "Votre fichier est trop volumineux" msgid "Change file" msgstr "Changer le fichier" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Présentation remplacée" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Modifier le sondage" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Nouveau sondage" @@ -357,18 +363,18 @@ msgstr "Titre de votre sondage" msgid "Upload failed" msgstr "Échec du chargement" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "Ajoutez un sondage pour connaître l'opinion de votre public." -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Sondage" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -392,18 +398,18 @@ msgstr "Voir le sondage actuel" msgid "Vote" msgstr "Voter" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Adresse email" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "La modification de votre fichier supprimera tous les éléments d'interaction comme les sondages associés." -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Les messages des participants apparaîtront ici." @@ -413,7 +419,7 @@ msgstr "Les messages des participants apparaîtront ici." msgid "Processing your file..." msgstr "Traitement de votre fichier..." -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "Cela supprimera toutes les réponses associées et le sondage lui-même, êtes-vous sûr ?" @@ -423,14 +429,14 @@ msgstr "Cela supprimera toutes les réponses associées et le sondage lui-même, msgid "Ask, comment..." msgstr "Questionnez, commentez..." -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Messages" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Ajouter un animateur" @@ -445,7 +451,7 @@ msgstr "Oups, la page n'existe pas." msgid "The site is under maintenance, we'll be back very soon!" msgstr "Le site est en cours de maintenance, nous serons de retour très bientôt !" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators can present and manage interactions" msgstr "Les animateurs peuvent présenter et gérer les interactions" @@ -459,13 +465,8 @@ msgstr "Les animateurs peuvent présenter et gérer les interactions" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "Si vous rencontrez des difficultés avec le bouton ci-dessus, copiez et collez l'URL ci-dessous dans votre navigateur web" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format, fuzzy -msgid "You can change your email by visiting the URL below" -msgstr "Vous pouvez modifier votre email en visitant l'URL ci-dessous" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format, fuzzy msgid "Add interaction" msgstr "Ajouter une interaction" @@ -625,6 +626,7 @@ msgstr "Ou utilisez le code:" msgid "Create account" msgstr "Créer un compte" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -660,7 +662,7 @@ msgstr "Changer votre email" msgid "Your password has been updated." msgstr "Votre mot de passe a été mis à jour." -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Field %{count}" msgid_plural "Field %{count}" @@ -668,7 +670,7 @@ msgstr[0] "Champ %{count}" msgstr[1] "Champ %{count}" msgstr[2] "Champ %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "Ajoutez un formulaire pour recueillir les données de votre public." @@ -678,34 +680,41 @@ msgstr "Ajoutez un formulaire pour recueillir les données de votre public." msgid "Current form" msgstr "Formulaire actuel" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format, fuzzy msgid "Edit form" msgstr "Modifier" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formulaire" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Soumissions de formulaire" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "Les formulaires soumis par les participants apparaîtront ici." -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "Nom" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "Nouveau formulaire" @@ -726,17 +735,17 @@ msgstr "Voir le formulaire actuel" msgid "Submit" msgstr "Soumettre" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "Texte" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Cela ne peut pas être annulé, confirmez-vous ?" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "Cela supprimera toutes les réponses associées et le sondage lui-même, êtes-vous sûr ?" @@ -746,7 +755,7 @@ msgstr "Cela supprimera toutes les réponses associées et le sondage lui-même, msgid "Title of your form" msgstr "Titre de votre formulaire" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "Type" @@ -761,7 +770,7 @@ msgstr "Sélectionnez une option" msgid "Select one or multiple options" msgstr "Sélectionner une ou plusieurs options" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "Réponses multiples" @@ -771,12 +780,12 @@ msgstr "Réponses multiples" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX jusqu'à %{size} MB" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Activer messages" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Afficher messages" @@ -825,7 +834,7 @@ msgstr "désactivé" msgid "Account creation is disabled" msgstr "La création de compte est désactivée" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Ajoutez une vidéo Youtube ou tout autre contenu web." @@ -876,12 +885,12 @@ msgstr "Envoyer le lien pour réinitialiser le mot de passe" msgid "Current web content" msgstr "Contenu web actuel" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Modifier le contenu web" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Nouveau contenu web" @@ -891,7 +900,7 @@ msgstr "Nouveau contenu web" msgid "See current web content" msgstr "Voir le contenu web actuel" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete the web content, are you sure?" msgstr "Cela supprimera le contenu web, êtes-vous sûr?" @@ -902,8 +911,8 @@ msgstr "Cela supprimera le contenu web, êtes-vous sûr?" msgid "Title" msgstr "Titre" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Contenu web" @@ -920,17 +929,17 @@ msgstr "Épingler" msgid "Pinned" msgstr "Épinglé" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format, fuzzy msgid "Pinned messages" msgstr "Messages épinglés" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Les messages épinglés apparaîtront ici." -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Afficher uniquement les messages épinglés" @@ -971,7 +980,7 @@ msgstr "Vous avez été invité à gérer un événement" msgid "Saved" msgstr "Enregistré" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "Tous vos événements et fichiers seront définitivement supprimés, êtes-vous sûr ?" @@ -986,22 +995,22 @@ msgstr "Êtes-vous sûr de vouloir terminer cet événement ? Cette action est i msgid "Attendees room" msgstr "Salle des participants" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "Soyez prudent, ces actions sont irréversibles" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "Zone de danger" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format, fuzzy msgid "Delete account" msgstr "Supprimer le compte" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "Ouvrir la présentation" @@ -1016,7 +1025,7 @@ msgstr "Voir le rapport" msgid "Your account has been deleted." msgstr "Votre compte a été supprimé." -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format, fuzzy msgid "Access code" msgstr "Code d'accès" @@ -1026,46 +1035,46 @@ msgstr "Code d'accès" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "Les animations dans les fichiers PPT/PPTX ne sont pas prises en charge, c'est pourquoi nous recommandons d'exporter votre présentation en PDF pour garantir un affichage correct." -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees interactions" msgstr "Interactions des participants" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "Retour" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators" msgstr "Animateurs" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Finish" msgstr "Terminer" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "Ici, vous trouverez toutes les interactions de vos participants. Vous pouvez gérer les messages, les messages épinglés et les formulaires soumis." -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "Identifiez les utilisateurs par leurs avatars uniques." #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1078,57 +1087,57 @@ msgstr "Suivant" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "Sélectionnez votre fichier de présentation. Les formats acceptés sont PDF, PPT ou PPTX. Assurez-vous que la taille du fichier ne dépasse pas la limite maximale." -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format msgid "Time to launch your presentation!" msgstr "Il est temps de lancer votre présentation !" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "Utilisez les raccourcis clavier associés pour basculer rapidement entre ces paramètres." -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "Vous pouvez contrôler chaque paramètre pour la présentation (affichage sur le grand écran) et dans la salle des participants." -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "Vos premiers pas avec Claper" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "Les participants qui tentent d'accéder à l'événement avant cette date seront dirigés vers une salle d'attente." -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format msgid "Create event" msgstr "Créer un événement" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format msgid "Create your first event" msgstr "Créez votre premier événement" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "Date de début de l'événement" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "Si vous n'avez pas le temps et que vous voulez simplement des interactions sans fichier de présentation, vous pouvez créer un nouvel événement ici." -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "Si vous avez besoin d'aide pour gérer votre événement, vous pouvez accorder l'accès à d'autres personnes. Entrez simplement leurs adresses e-mail ; une fois qu'ils auront créé un compte avec ces e-mails, ils pourront gérer l'événement." -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "Pressé ?" @@ -1138,18 +1147,18 @@ msgstr "Pressé ?" msgid "Live" msgstr "En direct" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "Mes événements" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format msgid "Name of your event" msgstr "Nom de votre événement" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "Note: Facilitators do not have the ability to delete your event." msgstr "Remarque : Les animateurs n'ont pas la possibilité de supprimer votre événement." @@ -1159,12 +1168,12 @@ msgstr "Remarque : Les animateurs n'ont pas la possibilité de supprimer votre msgid "Presentation file (optional)" msgstr "Fichier de présentation (facultatif)" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "Événement rapide" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "Événement rapide créé avec succès" @@ -1174,7 +1183,7 @@ msgstr "Événement rapide créé avec succès" msgid "Return to your last event" msgstr "Retourner à votre dernier événement" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Select the start date for your event. Future dates are permissible." msgstr "Sélectionnez la date de début de votre événement. Les dates futures sont autorisées." @@ -1184,22 +1193,22 @@ msgstr "Sélectionnez la date de début de votre événement. Les dates futures msgid "Select your presentation (optional)" msgstr "Sélectionnez votre présentation (facultatif)" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "Ce code sera utilisé par vos participants pour accéder à l'événement. Vous avez la possibilité de créer un code personnalisé." -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "Cet événement viens d'être terminé" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format msgid "Welcome to Claper! You can create a new event here." msgstr "Bienvenue sur Claper ! Vous pouvez créer un nouvel événement ici." -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format msgid "When your event will start?" msgstr "Quand votre événement commencera-t-il ?" @@ -1209,8 +1218,8 @@ msgstr "Quand votre événement commencera-t-il ?" msgid "Create your next presentation with" msgstr "Créez votre prochaine présentation avec" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1221,7 +1230,7 @@ msgstr "L'événement n'existe pas" msgid "Customize your account" msgstr "Personnalisez votre compte" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "Langue" @@ -1241,22 +1250,22 @@ msgstr "Vos préférences ont été mises à jour." msgid "Question" msgstr "Question" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "Questions" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "Les questions apparaîtront ici." -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "Trier par date" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "Trier par popularité" @@ -1266,7 +1275,8 @@ msgstr "Trier par popularité" msgid "Event manager" msgstr "Gestionnaire d'événement" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "Documentation" @@ -1282,7 +1292,7 @@ msgstr "Mon compte" msgid "Your personal informations to access your account" msgstr "Vos informations personnelles pour accéder à votre compte" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format, fuzzy msgid "Enable reactions" msgstr "Activer les réactions" @@ -1338,43 +1348,43 @@ msgid "Add Claper" msgstr "Ajouter Claper" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "Fermer l'aperçu" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first interaction." msgstr "Créez votre première interaction." -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format, fuzzy msgid "Disable" msgstr "Désactiver" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "Activer" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format, fuzzy msgid "Enable messages to change this option" msgstr "Activer les messages pour modifier cette option" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "Ouvrir l'aperçu" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "Afficher les messages pour modifier cette option" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "Cette diapositive n'a pas d'interactions." @@ -1401,7 +1411,7 @@ msgstr "Se connecter avec %{provider}" msgid "The account has been unlinked." msgstr "Le compte a été délié." -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "Cette section contient toutes vos interactions." @@ -1412,12 +1422,12 @@ msgstr "Cette section contient toutes vos interactions." msgid "Unlink" msgstr "Délier" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "Vous pouvez ajouter des interactions à vos diapositives de présentation." -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "Vos interactions" @@ -1442,12 +1452,12 @@ msgstr "Définissez un nouveau mot de passe pour votre compte avant de le délie msgid "Your password has been set, you can now unlink your account." msgstr "Votre mot de passe a été défini, vous pouvez maintenant délier votre compte." -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "Code Iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "Lien vers le contenu" @@ -1473,24 +1483,24 @@ msgstr "Veuillez entrer un lien valide commençant par http:// ou https://" msgid "Please enter valid HTML content with an iframe tag" msgstr "Veuillez entrer un contenu HTML valide avec une balise iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "Fournisseur" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "Les participants peuvent voir les résultats sur leur appareil" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees can view the web content on their device" msgstr "Les participants peuvent voir le contenu web sur leur appareil" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "Options" @@ -1558,12 +1568,12 @@ msgstr "Terminer" msgid "More options" msgstr "Plus d'options" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "Non" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "Oui" @@ -1613,32 +1623,32 @@ msgstr "Vous pouvez réinitialiser votre mot de passe en visitant l'URL ci-desso msgid "back to the home page" msgstr "retour à la page d'accueil" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format, fuzzy msgid "Add Question" msgstr "Ajouter une question" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "Ajouter un quiz pour tester les connaissances." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "Ajouter une réponse" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous messages" msgstr "Autoriser les messages anonymes" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "Réponse %{index}" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "Participants" @@ -1654,32 +1664,32 @@ msgstr "Score moyen" msgid "Current quiz" msgstr "Quiz actuel" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format, fuzzy msgid "Deny anonymous messages" msgstr "Refuser les messages anonymes" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format, fuzzy msgid "Disable messages" msgstr "Désactiver les messages" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format, fuzzy msgid "Disable reactions" msgstr "Désactiver les réactions" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format, fuzzy msgid "Edit quiz" msgstr "Modifier le quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "Masquer les instructions pour rejoindre" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format, fuzzy msgid "Hide messages" msgstr "Masquer les messages" @@ -1702,12 +1712,12 @@ msgstr "Comment ça marche ?" msgid "Interaction" msgstr "Interaction" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "Nouveau quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "Présentation" @@ -1717,13 +1727,13 @@ msgstr "Présentation" msgid "Previous" msgstr "Précédent" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "Quiz" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "Supprimer la question" @@ -1738,17 +1748,17 @@ msgstr "Passez en revue les questions" msgid "See current quiz" msgstr "Voir le quiz actuel" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format, fuzzy msgid "Select presentation" msgstr "Sélectionner la présentation" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format, fuzzy msgid "Show all messages" msgstr "Afficher tous les messages" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format, fuzzy msgid "Show instructions to join" msgstr "Afficher les instructions pour rejoindre" @@ -1764,7 +1774,7 @@ msgstr "Afficher les résultats" msgid "Show results on presentation" msgstr "Afficher les résultats sur la présentation" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "Cela supprimera toutes les réponses associées et le quiz lui-même, êtes-vous sûr ?" @@ -1774,7 +1784,7 @@ msgstr "Cela supprimera toutes les réponses associées et le quiz lui-même, ê msgid "Waiting for results..." msgstr "En attente des résultats..." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "Votre question" @@ -1792,7 +1802,7 @@ msgstr "Votre score" msgid "Export" msgstr "Exporter" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "Exporter en QTI (XML)" @@ -1852,17 +1862,21 @@ msgstr "Participants uniques" msgid "Web Content" msgstr "Contenu web" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "Actif" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "Charger plus" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "Partagé avec vous" @@ -1872,17 +1886,17 @@ msgstr "Partagé avec vous" msgid "You must login to continue" msgstr "Vous devez vous connecter pour continuer" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "doit avoir au moins une bonne réponse" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "Cliquez ici pour ouvrir la fenêtre de présentation. Appuyez sur F dans la fenêtre de présentation pour activer le plein ecran." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous submissions" msgstr "Autoriser les soumissions anonymes" @@ -1901,3 +1915,771 @@ msgstr "Se connecter" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "Total des soumissions" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "Un code unique pour que les participants rejoignent cet événement" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "Un nom unique pour cet événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "Un nom unique pour identifier ce fournisseur OIDC" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "Le compte est confirmé et actif" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Actions" +msgstr "Actions" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Active Events" +msgstr "Événements actifs" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this event?" +msgstr "Êtes-vous sûr de vouloir supprimer cet événement ?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this provider?" +msgstr "Êtes-vous sûr de vouloir supprimer ce fournisseur ?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete this user?" +msgstr "Êtes-vous sûr de vouloir supprimer cet utilisateur ?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "Utilisateur assigné" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format +msgid "Audience Peak" +msgstr "Pic d'audience" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "Code d'autorisation" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "Annuler" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format +msgid "Choose file" +msgstr "Choisir un fichier" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "ID Client" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "Secret Client" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "Terminé" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format +msgid "Confirmed" +msgstr "Confirmé" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "Confirmé le" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Create Event" +msgstr "Créer un événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "Créer un fournisseur" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Create User" +msgstr "Créer un utilisateur" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format +msgid "Created" +msgstr "Créé" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format +msgid "Created At" +msgstr "Créé le" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format +msgid "Currently running" +msgstr "Actuellement en cours" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format +msgid "Delete event" +msgstr "Supprimer l'événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "Supprimer le fournisseur" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format +msgid "Delete user" +msgstr "Supprimer l'utilisateur" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "Modifier le fournisseur OIDC" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "Modifier l'événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "Modifier le fournisseur" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit user" +msgstr "Modifier l'utilisateur" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "Activer ce fournisseur OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "Saisir l'ID client" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "Saisir le secret client" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "Saisir le code de l'événement" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "Saisir le nom de l'événement" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter password" +msgstr "Saisir le mot de passe" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "Saisir le nom du fournisseur" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "Saisir l'email de l'utilisateur" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "Création d'événement" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "Événement créé avec succès" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "Événement supprimé avec succès" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "Détails de l'événement" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "Événement mis à jour avec succès" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format +msgid "Events" +msgstr "Événements" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "Événements exportés avec succès" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "Expiré le" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "Fichier sélectionné" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format +msgid "Form Post" +msgstr "Form Post" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "Fragment" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "Comment la réponse d'autorisation doit être retournée (par défaut 'query')" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "Hybride" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "Implicite" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format +msgid "Inactive" +msgstr "Inactif" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "Mot de passe initial pour l'utilisateur" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "Émetteur" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "URL de l'émetteur" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "30 derniers jours" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "Dernière mise à jour" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "Nouvel événement" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "Aucun événement trouvé" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "Aucun fichier choisi" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "Aucun propriétaire" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "Aucun rôle" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "Aucun utilisateur trouvé" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "Non expiré" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "Non démarré" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "Type de réponse OAuth 2.0 (par défaut 'code')" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "OIDC Provider" +msgstr "Fournisseur OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "Détails du fournisseur OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format +msgid "OIDC Providers" +msgstr "Fournisseurs OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "Portées OIDC à demander (par défaut 'openid email profile')" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "Propriétaire" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "Fournisseur créé avec succès" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format +msgid "Provider updated successfully" +msgstr "Fournisseur mis à jour avec succès" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "Query" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "Événements récents" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "URI de redirection" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "Mode de réponse" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "Type de réponse" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "Rôle" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "Enregistrement..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "Planifié" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "Portée" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "Rechercher des événements..." + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "Rechercher un utilisateur..." + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "Rechercher des fournisseurs..." + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "Rechercher des utilisateurs..." + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format +msgid "Select an option" +msgstr "Sélectionner une option" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "Sélectionner..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "Date de début" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "Démarré le" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "Statut" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "L'URL de l'émetteur OIDC (doit commencer par http:// ou https://)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "L'URL de rappel pour votre application (doit commencer par http:// ou https://)" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "L'utilisateur qui possède cet événement (requis)" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "Total des événements" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "Total des utilisateurs" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "Non confirmé" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "Mettre à jour l'événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "Mettre à jour le fournisseur" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "Mettre à jour l'utilisateur" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "Compte utilisateur" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "Croissance des utilisateurs" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "Utilisateur créé avec succès" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "Utilisateur supprimé avec succès" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "Détails de l'utilisateur" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "User updated successfully" +msgstr "Utilisateur mis à jour avec succès" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "Niveau d'accès de l'utilisateur" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "Adresse email de l'utilisateur (doit être unique)" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "Utilisateurs" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "Utilisateurs exportés avec succès" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "Voir l'événement" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format +msgid "View provider" +msgstr "Voir le fournisseur" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "Voir l'utilisateur" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "Quand cet événement expire (optionnel)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "Si ce fournisseur est actuellement actif et disponible pour l'authentification" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format +msgid "attendees" +msgstr "participants" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "https://exemple.com" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "https://votreapp.com/auth/callback" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "openid email profile" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "vs mois dernier" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format +msgid "Back to events" +msgstr "Retour aux événements" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "Back to providers" +msgstr "Retour aux fournisseurs" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format +msgid "Back to users" +msgstr "Retour aux utilisateurs" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format +msgid "New provider" +msgstr "Nouveau fournisseur" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format +msgid "New user" +msgstr "Nouvel utilisateur" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format +msgid "No providers found" +msgstr "Aucun fournisseur trouvé" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format +msgid "Provider deleted successfully" +msgstr "Fournisseur supprimé avec succès" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format +msgid "Provider details" +msgstr "Détails du fournisseur" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "Admin" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "Retour à l'app" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "Confirmer l'email" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Si vous n'avez pas créé de compte chez nous, veuillez ignorer ceci." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Vous pouvez modifier votre email en visitant l'URL ci-dessous" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Masquer nombre de participants" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Afficher le nombre de participants" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Obligatoire" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(facultatif)" diff --git a/priv/gettext/hu/LC_MESSAGES/default.po b/priv/gettext/hu/LC_MESSAGES/default.po new file mode 100644 index 0000000..4eb1a2f --- /dev/null +++ b/priv/gettext/hu/LC_MESSAGES/default.po @@ -0,0 +1,2681 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: Claper\n" +"Language: hu\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 +#: lib/claper_web/live/user_settings_live/show.ex:77 +#, elixir-autogen, elixir-format +msgid "Settings" +msgstr "Beállítások" + +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 +#: lib/claper_web/live/user_settings_live/show.html.heex:34 +#: lib/claper_web/templates/user_registration/new.html.heex:29 +#: lib/claper_web/templates/user_reset_password/new.html.heex:28 +#: lib/claper_web/templates/user_session/new.html.heex:42 +#, elixir-autogen, elixir-format +msgid "Email" +msgstr "E-mail" + +#: lib/claper_web/templates/user_registration/new.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Join the Claper experience" +msgstr "Csatlakozzon a Claper-élményhez" + +#: lib/claper_web/templates/user_registration/new.html.heex:19 +#: lib/claper_web/templates/user_reset_password/edit.html.heex:25 +#: lib/claper_web/templates/user_reset_password/new.html.heex:19 +#, elixir-autogen, elixir-format +msgid "Oops, check that all fields are filled in correctly." +msgstr "Ellenőrizze, hogy minden mező helyesen lett-e kitöltve." + +#: lib/claper_web/live/user_settings_live/show.html.heex:155 +#: lib/claper_web/live/user_settings_live/show.html.heex:170 +#, elixir-autogen, elixir-format +msgid "Change" +msgstr "Módosítás" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 +#, elixir-autogen, elixir-format +msgid "Code" +msgstr "Kód" + +#: lib/claper_web/live/user_settings_live/show.html.heex:146 +#: lib/claper_web/templates/user_session/new.html.heex:40 +#, elixir-autogen, elixir-format +msgid "Email address" +msgstr "E-mail cím" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 +#, elixir-autogen, elixir-format +msgid "Logout" +msgstr "Kijelentkezés" + +#: lib/claper_web/live/user_settings_live/show.html.heex:136 +#, elixir-autogen, elixir-format +msgid "Personal informations" +msgstr "Személyes adatok" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:13 +#, elixir-autogen, elixir-format +msgid "We already sent you an email to login, please retry in 5 minutes." +msgstr "Már küldtünk egy e-mailt a bejelentkezéshez, próbálja újra 5 perc múlva." + +#: lib/claper_web/templates/user_registration/confirm.html.heex:16 +#, elixir-autogen, elixir-format +msgid "We sent you an email at" +msgstr "Küldtünk egy e-mailt erre a címre:" + +#: lib/claper_web/live/event_live/show.html.heex:437 +#, elixir-autogen, elixir-format +msgid "days" +msgstr "nap" + +#: lib/claper_web/live/event_live/show.html.heex:443 +#, elixir-autogen, elixir-format +msgid "hours" +msgstr "óra" + +#: lib/claper_web/live/event_live/show.html.heex:449 +#, elixir-autogen, elixir-format +msgid "minutes" +msgstr "perc" + +#: lib/claper_web/live/event_live/show.html.heex:165 +#, elixir-autogen, elixir-format +msgid "Be the first to react !" +msgstr "Reagáljon elsőként!" + +#: lib/claper_web/live/event_live/event_card_component.ex:111 +#: lib/claper_web/live/event_live/join.ex:41 +#: lib/claper_web/live/event_live/join.html.heex:94 +#: lib/claper_web/live/event_live/manage.html.heex:492 +#: lib/claper_web/live/event_live/show.html.heex:286 +#, elixir-autogen, elixir-format +msgid "Join" +msgstr "Csatlakozás" + +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 +#, elixir-autogen, elixir-format +msgid "Dashboard" +msgstr "Kezdőlap" + +#: lib/claper_web/live/event_live/post_component.ex:33 +#: lib/claper_web/live/event_live/post_component.ex:112 +#, elixir-autogen, elixir-format +msgid "Host" +msgstr "Host" + +#: lib/claper_web/live/event_live/show.html.heex:455 +#, elixir-autogen, elixir-format +msgid "seconds" +msgstr "másodperc" + +#: lib/claper_web/live/event_live/event_card_component.ex:60 +#: lib/claper_web/live/event_live/index.html.heex:187 +#, elixir-autogen, elixir-format +msgid "Finished" +msgstr "Befejezve" + +#: lib/claper_web/live/event_live/event_card_component.ex:90 +#, elixir-autogen, elixir-format +msgid "Finished on" +msgstr "Vége ekkor: " + +#: lib/claper_web/live/event_live/event_card_component.ex:55 +#, elixir-autogen, elixir-format +msgid "Incoming" +msgstr "Bejövő" + +#: lib/claper_web/live/event_live/show.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Leave" +msgstr "Kilépés" + +#: lib/claper_web/live/event_live/presenter.html.heex:26 +#: lib/claper_web/live/event_live/show.html.heex:464 +#, elixir-autogen, elixir-format +msgid "Scan to interact in real-time" +msgstr "Szkennelje be, hogy valós időben csatlakozhasson." + +#: lib/claper_web/live/event_live/event_card_component.ex:86 +#, elixir-autogen, elixir-format +msgid "Starting on" +msgstr "Kezdés: " + +#: lib/claper_web/live/event_live/event_form_component.ex:268 +#, elixir-autogen, elixir-format +msgid "Updated successfully" +msgstr "Sikeresen frissítve" + +#: lib/claper_web/templates/user_session/new.html.heex:22 +#, elixir-autogen, elixir-format +msgid "It's time to empower your presentations." +msgstr "Itt az idő, hogy új szintre emelje prezentációit." + +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Return to home" +msgstr "Vissza a kezdőlapra" + +#: lib/claper_web/live/event_live/event_form_component.ex:212 +#: lib/claper_web/live/event_live/event_form_component.ex:248 +#, elixir-autogen, elixir-format +msgid "Created successfully" +msgstr "Sikeresen létrehozva" + +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 +#: lib/claper_web/live/event_live/event_card_component.ex:250 +#: lib/claper_web/live/event_live/event_card_component.ex:330 +#: lib/claper_web/live/event_live/form_component.ex:97 +#: lib/claper_web/live/event_live/index.ex:204 +#, elixir-autogen, elixir-format +msgid "Edit" +msgstr "Szerkesztés" + +#: lib/claper_web/live/embed_live/form_component.html.heex:63 +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#: lib/claper_web/live/event_live/event_form_component.html.heex:62 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 +#, elixir-autogen, elixir-format +msgid "Create" +msgstr "Létrehozás" + +#: lib/claper_web/live/embed_live/form_component.html.heex:68 +#: lib/claper_web/live/event_live/event_card_component.ex:444 +#: lib/claper_web/live/event_live/event_form_component.html.heex:67 +#: lib/claper_web/live/event_live/manage.html.heex:1397 +#: lib/claper_web/live/event_live/manageable_post_component.ex:92 +#: lib/claper_web/live/event_live/post_component.ex:70 +#: lib/claper_web/live/event_live/post_component.ex:142 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#, elixir-autogen, elixir-format +msgid "Delete" +msgstr "Törlés" + +#: lib/claper_web/live/embed_live/form_component.html.heex:64 +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#: lib/claper_web/live/event_live/event_form_component.html.heex:61 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 +#: lib/claper_web/live/user_settings_live/show.html.heex:38 +#: lib/claper_web/live/user_settings_live/show.html.heex:80 +#: lib/claper_web/live/user_settings_live/show.html.heex:123 +#, elixir-autogen, elixir-format +msgid "Save" +msgstr "Mentés" + +#: lib/claper_web/live/user_settings_live/show.ex:137 +#, elixir-autogen, elixir-format +msgid "A link to confirm your email change has been sent to the new address." +msgstr "Az e-mail változtatást megerősítő linket elküldtük az új e-mail címre." + +#: lib/claper_web/live/user_settings_live/show.ex:53 +#, elixir-autogen, elixir-format +msgid "Change the email address you want associated with your account." +msgstr "Fiók e-mail címének módosítása." + +#: lib/claper_web/live/user_settings_live/show.ex:50 +#, elixir-autogen, elixir-format +msgid "Update your email" +msgstr "E-mail megváltoztatása" + +#: lib/claper_web/notifiers/user_notifier.ex:12 +#: lib/claper_web/templates/user_notifier/magic.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Connect to Claper" +msgstr "Csatlakozás a Claperhez" + +#: lib/claper_web/templates/user_notifier/magic.html.heex:29 +#, elixir-autogen, elixir-format +msgid "ACCESS TO MY ACCOUNT" +msgstr "Hozzáférés a fiókomhoz" + +#: lib/claper_web/notifiers/user_notifier.ex:34 +#, elixir-autogen, elixir-format +msgid "Update email instructions" +msgstr "E-mail frissítése" + +#: lib/claper_web/templates/user_notifier/change.html.heex:29 +#, elixir-autogen, elixir-format +msgid "CONFIRM EMAIL" +msgstr "E-MAIL MEGERŐSÍTÉSE" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:32 +#: lib/claper_web/templates/user_notifier/magic.html.heex:32 +#: lib/claper_web/templates/user_notifier/reset.html.heex:32 +#, elixir-autogen, elixir-format +msgid "If you didn't create an account with us, please ignore this." +msgstr "Amennyiben nem regisztrált fiókot nálunk, kérjük, hagyja ezt az üzenetet figyelmen kívül." + +#: lib/claper_web/templates/user_notifier/magic.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can log into your account by clicking here." +msgstr "Ide kattintva jelentkezhet be a fiókjába." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:71 +#: lib/claper_web/live/event_live/post_component.ex:75 +#: lib/claper_web/live/event_live/post_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Are you sure?" +msgstr "Biztos benne?" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:192 +#, elixir-autogen, elixir-format +msgid "Presentation attached" +msgstr "Prezentáció csatolva" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:152 +#, elixir-autogen, elixir-format +msgid "Presentation uploaded" +msgstr "Prezentáció feltöltve" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:163 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 +#, elixir-autogen, elixir-format +msgid "Remove" +msgstr "Eltávolítás" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:173 +#, elixir-autogen, elixir-format +msgid "Select your presentation" +msgstr "Válassza ki a prezentációt" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:115 +#, elixir-autogen, elixir-format +msgid "Upload a file" +msgstr "Töltsön fel egy fájlt" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:119 +#, elixir-autogen, elixir-format +msgid "or drag and drop" +msgstr "vagy húzza ide" + +#: lib/claper_web/live/event_live/event_form_component.ex:322 +#, elixir-autogen, elixir-format +msgid "You have selected an incorrect file type" +msgstr "Helytelen fájltípus" + +#: lib/claper_web/live/event_live/event_form_component.ex:321 +#, elixir-autogen, elixir-format +msgid "Your file is too large" +msgstr "Túl nagy fájl" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:202 +#, elixir-autogen, elixir-format +msgid "Change file" +msgstr "Fájl megváltoztatása" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 +#, elixir-autogen, elixir-format +msgid "Presentation replaced" +msgstr "Prezentáció lecserélve" + +#: lib/claper_web/live/event_live/manage.html.heex:305 +#, elixir-autogen, elixir-format +msgid "Edit poll" +msgstr "Szavazás szerkesztése" + +#: lib/claper_web/live/event_live/manage.html.heex:304 +#, elixir-autogen, elixir-format +msgid "New poll" +msgstr "Új szavazás" + +#: lib/claper_web/live/poll_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your poll" +msgstr "A szavazás címe" + +#: lib/claper_web/live/event_live/event_form_component.ex:323 +#, elixir-autogen, elixir-format +msgid "Upload failed" +msgstr "Hiba a feltöltéskor" + +#: lib/claper_web/live/event_live/manage.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Add poll to know opinion of your public." +msgstr "Adjon hozzá egy szavazást, hogy megismerje a közönség véleményét." + +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 +#, elixir-autogen, elixir-format +msgid "Poll" +msgstr "Szavazás" + +#: lib/claper_web/live/poll_live/form_component.html.heex:26 +#, elixir-format, ex-autogen, elixir-autogen +msgid "Choice %{count}" +msgid_plural "Choice %{count}" +msgstr[0] "%{count} lehetőség" +msgstr[1] "" + +#: lib/claper_web/live/event_live/poll_component.ex:47 +#, elixir-autogen, elixir-format +msgid "Current poll" +msgstr "Jelenlegi szavazás" + +#: lib/claper_web/live/event_live/poll_component.ex:28 +#, elixir-autogen, elixir-format +msgid "See current poll" +msgstr "Jelenlegi szavazás megtekintése" + +#: lib/claper_web/live/event_live/poll_component.ex:127 +#: lib/claper_web/live/event_live/poll_component.ex:135 +#, elixir-autogen, elixir-format +msgid "Vote" +msgstr "Szavazás" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 +#, elixir-autogen, elixir-format +msgid "User email address" +msgstr "A felhasználó e-mail címe" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 +#, elixir-autogen, elixir-format +msgid "Changing your file will remove all interaction elements like polls associated." +msgstr "A fájl lecserélése magával vonja az összes hozzákapcsolt interakció (pl. szavazás) törlését." + +#: lib/claper_web/live/event_live/manage.html.heex:1213 +#, elixir-autogen, elixir-format +msgid "Messages from attendees will appear here." +msgstr "A résztvevők üzenetei itt fognak megjelenni." + +#: lib/claper_web/live/event_live/event_card_component.ex:344 +#, elixir-autogen, elixir-format +msgid "Processing your file..." +msgstr "Fájl feldolgozása..." + +#: lib/claper_web/live/poll_live/form_component.html.heex:114 +#, elixir-autogen, elixir-format +msgid "This will delete all responses associated and the poll itself, are you sure?" +msgstr "Ez a szavazással együtt törli az összes beérkezett választ is. Biztos benne?" + +#: lib/claper_web/live/event_live/show.html.heex:345 +#, elixir-autogen, elixir-format +msgid "Ask, comment..." +msgstr "Kérdezzen, kommenteljen..." + +#: lib/claper_web/live/event_live/manage.html.heex:1159 +#: lib/claper_web/live/stat_live/index.html.heex:102 +#: lib/claper_web/live/stat_live/index.html.heex:180 +#, elixir-autogen, elixir-format +msgid "Messages" +msgstr "Üzenetek" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 +#, elixir-autogen, elixir-format +msgid "Add facilitator" +msgstr "Facilitátor hozzáadása" + +#: lib/claper_web/templates/error/404.html.heex:31 +#, elixir-autogen, elixir-format +msgid "Oops, page doesn't exist." +msgstr "Az oldal nem található." + +#: lib/claper_web/templates/error/500.html.heex:31 +#, elixir-autogen, elixir-format +msgid "The site is under maintenance, we'll be back very soon!" +msgstr "Karbantartás alatt. Próbálja újra később." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#, elixir-autogen, elixir-format +msgid "Facilitators can present and manage interactions" +msgstr "A facilitátorok kezelhetik és vezethetik az interakciókat" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:45 +#: lib/claper_web/templates/user_notifier/change.html.heex:42 +#: lib/claper_web/templates/user_notifier/confirm.html.heex:42 +#: lib/claper_web/templates/user_notifier/magic.html.heex:42 +#: lib/claper_web/templates/user_notifier/reset.html.heex:42 +#, elixir-autogen, elixir-format +msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" +msgstr "Ha a fenti gomb nem működik, másolja be az alábbi címet a böngészőbe" + +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 +#, elixir-autogen, elixir-format +msgid "Add interaction" +msgstr "Interakció hozzáadása" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:54 +#: lib/claper_web/live/event_live/manageable_post_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" +msgstr "Ezen felhasználó blokkolásával az üzenetei törlődnek, és nem fog tudni újra csatlakozni. Biztos benne?" + +#: lib/claper_web/live/event_live/show.ex:51 +#: lib/claper_web/live/event_live/show.ex:206 +#: lib/claper_web/live/event_live/show.ex:221 +#, elixir-autogen, elixir-format +msgid "You have been banned from this event" +msgstr "Ki van tiltva erről az eseményről" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:48 +#: lib/claper_web/live/event_live/manageable_post_component.ex:77 +#, elixir-autogen, elixir-format +msgid "Ban" +msgstr "Kitiltás" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:18 +#, elixir-autogen, elixir-format +msgid ", click on the provided link to connect (check your spam !)" +msgstr ", kattintson a kapott linkre a kapcsolódáshoz, és ellenőrizze a spam mappát." + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:29 +#, elixir-autogen, elixir-format +msgid "Export your current presentation to PDF from your favorite slide presentation software (PowerPoint, etc)" +msgstr "Exportálja a jelenlegi prezentációt PDF formátumba kedvenc prezentációs szoftveréből (PowerPoint, stb)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:50 +#, elixir-autogen, elixir-format +msgid "Wait few minutes for your file to be processed" +msgstr "Várjon néhány percet a fájlfeldolgozás befejezéséhez" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:43 +#, elixir-autogen, elixir-format +msgid "Choose a name for your event, a code for your attendees to join and dates when your attendees could start interacting" +msgstr "Válasszon egy nevet az eseménynek, egy csatlakozási kódot és kezdési dátumot" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:64 +#, elixir-autogen, elixir-format +msgid "Click Start to open your presentation and move the window on the big screen" +msgstr "Kattintson a Start gombra a prezentáció megnyitásához és kivetítéséhez" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:57 +#, elixir-autogen, elixir-format +msgid "Click on Present/Customize to add interaction on your slides" +msgstr "Kattintson a Prezentálás/személyre szabás gombra, hogy interakciókat adhasson a diákhoz" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:22 +#, elixir-autogen, elixir-format +msgid "Congrats! You've taken the first step to improving your presentations. Here are the next steps to create step up your presentations with Claper:" +msgstr "Gratulálunk! Megtette az első lépést a prezentációja fejlesztésében. Itt vannak a következő lépések, amivel javíthatja a prezentációját a Claperben:" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:69 +#, elixir-autogen, elixir-format +msgid "Enjoy ! ✨" +msgstr "Jó szórakozást! ✨" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:20 +#, elixir-autogen, elixir-format +msgid "We sent you an email, click on the provided link to connect (check your spam !)" +msgstr "Küldtünk egy e-mailt, kattintson a kapott linkre a csatlakozáshoz (vagy ellenőrizze a spam mappát)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Welcome !" +msgstr "Üdvözöljük!" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Click on the create button on your dashboard" +msgstr "Kattintson a létrehozás gombra a kezdőlapon" + +#: lib/claper_web/notifiers/user_notifier.ex:23 +#, elixir-autogen, elixir-format +msgid "Next steps to boost your presentations" +msgstr "A következő lépések, hogy új szintre emelje prezentációját" + +#: lib/claper_web/live/stat_live/index.html.heex:109 +#, elixir-autogen, elixir-format +msgid "from %{count} people" +msgid_plural "from %{count} peoples" +msgstr[0] "%{count} embertől" +msgstr[1] "" + +#: lib/claper_web/live/stat_live/index.html.heex:15 +#, elixir-autogen, elixir-format +msgid "Event" +msgstr "Esemény" + +#: lib/claper_web/live/stat_live/index.html.heex:386 +#, elixir-autogen, elixir-format +msgid "No messages has been sent" +msgstr "Nincsenek küldött üzenetek" + +#: lib/claper_web/live/event_live/event_card_component.ex:426 +#, elixir-autogen, elixir-format +msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" +msgstr "Az esemény minden adata törlődni fog, a visszaállítás nem lehetséges. Folytatja?" + +#: lib/claper_web/live/stat_live/index.html.heex:45 +#: lib/claper_web/live/stat_live/index.html.heex:77 +#, elixir-autogen, elixir-format +msgid "attendee" +msgid_plural "attendees" +msgstr[0] "résztvevő" +msgstr[1] "résztvevők" + +#: lib/claper_web/live/stat_live/index.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Audience peak" +msgstr "Részvételi csúcs" + +#: lib/claper_web/live/stat_live/index.html.heex:139 +#, elixir-autogen, elixir-format +msgid "Engagement rate" +msgstr "Aktivitási arány" + +#: lib/claper_web/live/event_live/event_card_component.ex:282 +#, elixir-autogen, elixir-format +msgid "Error when processing the file" +msgstr "Hiba a fájl feldolgozásakor" + +#: lib/claper_web/live/event_live/join.html.heex:24 +#: lib/claper_web/live/event_live/join.html.heex:47 +#, elixir-autogen, elixir-format +msgid "About" +msgstr "Rólunk" + +#: lib/claper_web/live/event_live/join.html.heex:38 +#: lib/claper_web/live/event_live/join.html.heex:61 +#: lib/claper_web/templates/user_session/new.html.heex:62 +#, elixir-autogen, elixir-format +msgid "Login" +msgstr "Bejelentkezés" + +#: lib/claper_web/templates/user_session/new.html.heex:25 +#, elixir-autogen, elixir-format +msgid "Connect to your account" +msgstr "Lépjen be a fiókjába" + +#: lib/claper_web/live/event_live/show.html.heex:473 +#, elixir-autogen, elixir-format +msgid "Or use the code:" +msgstr "Vagy használja a kódot:" + +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Create account" +msgstr "Regisztráció" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 +#: lib/claper_web/live/user_settings_live/show.html.heex:161 +#: lib/claper_web/templates/user_registration/new.html.heex:37 +#: lib/claper_web/templates/user_reset_password/edit.html.heex:34 +#: lib/claper_web/templates/user_session/new.html.heex:50 +#: lib/claper_web/templates/user_session/new.html.heex:52 +#, elixir-autogen, elixir-format +msgid "Password" +msgstr "Jelszó" + +#: lib/claper_web/live/user_settings_live/show.ex:62 +#, elixir-autogen, elixir-format +msgid "Change the password used to access your account." +msgstr "Jelszó megváltoztatása." + +#: lib/claper_web/live/user_settings_live/show.html.heex:70 +#, elixir-autogen, elixir-format +msgid "Current password" +msgstr "Jelenlegi jelszó" + +#: lib/claper_web/live/user_settings_live/show.html.heex:76 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#, elixir-autogen, elixir-format +msgid "New password" +msgstr "Új jelszó" + +#: lib/claper_web/live/user_settings_live/show.ex:59 +#, elixir-autogen, elixir-format +msgid "Update your password" +msgstr "Változtassa meg jelszavát" + +#: lib/claper_web/live/user_settings_live/show.ex:159 +#, elixir-autogen, elixir-format +msgid "Your password has been updated." +msgstr "A jelszó megváltozott." + +#: lib/claper_web/live/form_live/form_component.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Field %{count}" +msgid_plural "Field %{count}" +msgstr[0] "Mező %{count}" +msgstr[1] "Mező %{count}" + +#: lib/claper_web/live/event_live/manage.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Add form to collect data from your public." +msgstr "Adjon hozzá egy űrlapot, hogy adatokat gyűjthessen a közönségtől." + +#: lib/claper_web/live/event_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Current form" +msgstr "Jelenlegi űrlap" + +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format +msgid "Edit form" +msgstr "Űrlap szerkesztése" + +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 +#, elixir-autogen, elixir-format +msgid "Form" +msgstr "Űrlap" + +#: lib/claper_web/live/event_live/manage.html.heex:1183 +#, elixir-autogen, elixir-format +msgid "Form submissions" +msgstr "Beküldött űrlapok" + +#: lib/claper_web/live/event_live/manage.html.heex:1382 +#, elixir-autogen, elixir-format +msgid "Form submissions from attendees will appear here." +msgstr "A résztvevők által beküldött űrlapok itt fognak megjelenni." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 +#, elixir-autogen, elixir-format +msgid "Name" +msgstr "Név" + +#: lib/claper_web/live/event_live/manage.html.heex:325 +#, elixir-autogen, elixir-format +msgid "New form" +msgstr "Új űrlap" + +#: lib/claper_web/live/stat_live/index.html.heex:305 +#, elixir-autogen, elixir-format +msgid "No form submission has been sent" +msgstr "Nincsenek beküldött űrlapok." + +#: lib/claper_web/live/event_live/form_component.ex:32 +#, elixir-autogen, elixir-format +msgid "See current form" +msgstr "Jelenlegi űrlap megtekintése" + +#: lib/claper_web/live/event_live/form_component.ex:97 +#: lib/claper_web/live/event_live/quiz_component.ex:183 +#, elixir-autogen, elixir-format +msgid "Submit" +msgstr "Küldés" + +#: lib/claper_web/live/form_live/form_component.html.heex:32 +#, elixir-autogen, elixir-format +msgid "Text" +msgstr "Szöveg" + +#: lib/claper_web/live/event_live/manage.html.heex:1402 +#, elixir-autogen, elixir-format +msgid "This cannot be undone, confirm ?" +msgstr "A műveletet nem lehet visszavonni. Folytatja?" + +#: lib/claper_web/live/form_live/form_component.html.heex:105 +#, elixir-autogen, elixir-format +msgid "This will delete all responses associated and the form itself, are you sure?" +msgstr "Az űrlap és minden hozzá tartozó válasz törlődni fog. Folytatja?" + +#: lib/claper_web/live/form_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your form" +msgstr "Az űrlap címe" + +#: lib/claper_web/live/form_live/form_component.html.heex:34 +#, elixir-autogen, elixir-format +msgid "Type" +msgstr "Típus" + +#: lib/claper_web/live/event_live/poll_component.ex:52 +#, elixir-autogen, elixir-format +msgid "Select one option" +msgstr "Válasszon egy opciót" + +#: lib/claper_web/live/event_live/poll_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Select one or multiple options" +msgstr "Válasszon egy vagy több opciót" + +#: lib/claper_web/live/poll_live/form_component.html.heex:92 +#, elixir-autogen, elixir-format +msgid "Multiple answers" +msgstr "Több válaszlehetőség" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 +#, elixir-autogen, elixir-format +msgid "PDF, PPT, PPTX up to %{size} MB" +msgstr "PDF, PPT, PPTX %{size} MB maximum méretig" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#, elixir-autogen, elixir-format +msgid "Enable messages" +msgstr "Üzenetek engedélyezése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#, elixir-autogen, elixir-format +msgid "Show messages" +msgstr "Üzenetek mutatása" + +#: lib/claper_web/live/event_live/show.html.heex:365 +#, elixir-autogen, elixir-format +msgid "Messages deactivated" +msgstr "Üzenetek letiltva." + +#: lib/claper_web/live/event_live/show.html.heex:208 +#: lib/claper_web/live/event_live/show.html.heex:229 +#: lib/claper_web/live/event_live/show.html.heex:329 +#, elixir-autogen, elixir-format +msgid "Anonymous" +msgstr "Névtelen" + +#: lib/claper_web/live/event_live/show.html.heex:255 +#: lib/claper_web/templates/lti/launch/error.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Close" +msgstr "Bezárás" + +#: lib/claper_web/live/event_live/show.html.heex:236 +#: lib/claper_web/live/event_live/show.html.heex:281 +#, elixir-autogen, elixir-format +msgid "Enter your name" +msgstr "Írja be a nevét" + +#: lib/claper_web/live/event_live/presenter.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Or go to %{url} and use the code:" +msgstr "Vagy látogassa meg a következő linket: %{url} és használja a következő kódot:" + +#: lib/claper_web/live/event_live/show.html.heex:249 +#, elixir-autogen, elixir-format +msgid "Use your name" +msgstr "Használja a nevét" + +#: lib/claper_web/live/event_live/show.html.heex:229 +#, elixir-autogen, elixir-format +msgid "disabled" +msgstr "letiltva" + +#: lib/claper_web/controllers/user_registration_controller.ex:14 +#, elixir-autogen, elixir-format +msgid "Account creation is disabled" +msgstr "A regisztráció le van tiltva" + +#: lib/claper_web/live/event_live/manage.html.heex:261 +#, elixir-autogen, elixir-format +msgid "Add a Youtube video or any web content." +msgstr "Adjon hozzá egy Youtube videót vagy más internetes tartalmat." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:51 +#, elixir-autogen, elixir-format +msgid "Confirm new password" +msgstr "Új jelszó megerősítése" + +#: lib/claper_web/templates/user_session/new.html.heex:79 +#, elixir-autogen, elixir-format +msgid "Forgot your password?" +msgstr "Elfelejtette a jelszavát?" + +#: lib/claper_web/controllers/user_reset_password_controller.ex:26 +#, elixir-autogen, elixir-format +msgid "If your email is in our system, you'll receive instructions to reset your password shortly." +msgstr "Amennyiben az e-mail címe regisztrálva van rendszerünkben, hamarosan küldünk egy e-mailt a jelszó visszaállításához." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:42 +#, elixir-autogen, elixir-format +msgid "Password confirmation" +msgstr "Jelszó megerősítése" + +#: lib/claper_web/controllers/user_reset_password_controller.ex:44 +#, elixir-autogen, elixir-format +msgid "Password updated successfully." +msgstr "A jelszó sikeresen megváltoztatva." + +#: lib/claper_web/controllers/user_reset_password_controller.ex:59 +#, elixir-autogen, elixir-format +msgid "Reset password link is invalid or it has expired." +msgstr "A jelszó-visszaállítási link helytelen vagy lejárt." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:12 +#: lib/claper_web/templates/user_reset_password/new.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Reset your password" +msgstr "Jelszó visszaállítása" + +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Send link to reset password" +msgstr "Jelszó-visszaállítási link küldése" + +#: lib/claper_web/live/event_live/embed_component.ex:55 +#, elixir-autogen, elixir-format +msgid "Current web content" +msgstr "Jelenlegi internetes tartalom" + +#: lib/claper_web/live/event_live/manage.html.heex:347 +#, elixir-autogen, elixir-format +msgid "Edit web content" +msgstr "Internetes tartalom szerkesztése" + +#: lib/claper_web/live/event_live/manage.html.heex:346 +#, elixir-autogen, elixir-format +msgid "New web content" +msgstr "Új internetes tartalom" + +#: lib/claper_web/live/event_live/embed_component.ex:32 +#, elixir-autogen, elixir-format +msgid "See current web content" +msgstr "Jelenlegi internetes tartalom megtekintése" + +#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#, elixir-autogen, elixir-format +msgid "This will delete the web content, are you sure?" +msgstr "Az internetes tartalom törlődni fog. Folytatja?" + +#: lib/claper_web/live/embed_live/form_component.html.heex:14 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title" +msgstr "Cím" + +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 +#, elixir-autogen, elixir-format +msgid "Web content" +msgstr "Internetes tartalom" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:38 +#: lib/claper_web/live/event_live/manageable_post_component.ex:67 +#, elixir-autogen, elixir-format +msgid "Pin" +msgstr "Kitűzés" + +#: lib/claper_web/live/event_live/post_component.ex:59 +#: lib/claper_web/live/event_live/post_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Pinned" +msgstr "Kitűzve" + +#: lib/claper_web/live/event_live/manage.html.heex:1175 +#, elixir-autogen, elixir-format +msgid "Pinned messages" +msgstr "Kitűzött üzenetek" + +#: lib/claper_web/live/event_live/manage.html.heex:1336 +#, elixir-autogen, elixir-format +msgid "Pinned messages will appear here." +msgstr "A kitűzött üzenetek itt fognak megjelenni." + +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 +#, elixir-autogen, elixir-format +msgid "Show only pinned messages" +msgstr "Csak a kitűzött üzenetek mutatása" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:36 +#: lib/claper_web/live/event_live/manageable_post_component.ex:65 +#, elixir-autogen, elixir-format +msgid "Unpin" +msgstr "Kitűzés megszüntetése" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:35 +#, elixir-autogen, elixir-format +msgid "Login or create account" +msgstr "Bejelentkezés vagy regisztráció" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:22 +#, elixir-autogen, elixir-format +msgid "Someone invited you to manage the event: %{name}" +msgstr "%{name} meghívott az esemény kezelésére." + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:25 +#, elixir-autogen, elixir-format +msgid "To accept the invitation, please login or create an account with this email: %{email}" +msgstr "A meghívás elfogadásához jelentkezzen be, vagy hozzon létre egy fiókot a %{email} e-mail címmel" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:17 +#, elixir-autogen, elixir-format +msgid "You have been invited" +msgstr "Ön meghívást kapott" + +#: lib/claper_web/notifiers/leader_notifier.ex:12 +#, elixir-autogen, elixir-format +msgid "You have been invited to manage an event" +msgstr "Meghívást kapott egy esemény kezelésére" + +#: lib/claper_web/live/event_live/form_component.ex:114 +#, elixir-autogen, elixir-format, fuzzy +msgid "Saved" +msgstr "Elmentve" + +#: lib/claper_web/live/user_settings_live/show.html.heex:301 +#, elixir-autogen, elixir-format +msgid "All your events and files will be permanently deleted, are you sure?" +msgstr "Minden a fiókhoz tartozó esemény és fájl törlődni fog. Folytatja?" + +#: lib/claper_web/live/event_live/event_card_component.ex:183 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "Biztosan lezárja az eseményt? A művelet nem vonható vissza." + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "Résztvevők szobája" + +#: lib/claper_web/live/user_settings_live/show.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Be careful, these actions are irreversible" +msgstr "Figyelem, a művelet nem visszafordítható." + +#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "Veszély" + +#: lib/claper_web/live/user_settings_live/show.html.heex:297 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete account" +msgstr "Fiók törlése" + +#: lib/claper_web/live/event_live/manage.html.heex:565 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "Prezentáció megnyitása" + +#: lib/claper_web/live/event_live/event_card_component.ex:370 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "Jelentés megtekintése" + +#: lib/claper_web/controllers/user_registration_controller.ex:50 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "Fiókja törlésre került." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "Access code" +msgstr "Hozzáférési kód" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." +msgstr "A PPT/PPTX fájlokban található animációk nem támogatottak, ezért kérjük, exportálja a prezentációt PDF formátumba a helyes megjelenítéshez." + +#: lib/claper_web/live/event_live/manage.html.heex:1147 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees interactions" +msgstr "Résztvevők interakciói" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/quiz_component.ex:151 +#: lib/claper_web/live/event_live/quiz_component.ex:198 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "Vissza" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 +#, elixir-autogen, elixir-format, fuzzy +msgid "Facilitators" +msgstr "Facilitátorok" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:7 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/templates/lti/registration/success.html.heex:26 +#, elixir-autogen, elixir-format, fuzzy +msgid "Finish" +msgstr "Befejezés" + +#: lib/claper_web/live/event_live/manage.html.heex:1149 +#, elixir-autogen, elixir-format +msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." +msgstr "Itt találhatóak majd a résztvevők interakciói. Lehetőség van az üzenetek kitűzésére, illetve az üzenetek és a beérkező űrlapok kezelésére." + +#: lib/claper_web/live/event_live/manage.html.heex:1149 +#, elixir-autogen, elixir-format +msgid "Identify users by their unique avatars." +msgstr "Azonosítsa a felhasználókat egyedi profilképeik alapján." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:176 +#: lib/claper_web/live/event_live/quiz_component.ex:161 +#: lib/claper_web/live/event_live/quiz_component.ex:209 +#, elixir-autogen, elixir-format, fuzzy +msgid "Next" +msgstr "Következő" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." +msgstr "Válassza ki a prezentációt. Engedélyezett fájlformátumok: PDF, PPT, PPTX. Figyeljen arra, hogy a fájl mérete ne haladja meg a maximálisan feltölthető fájlméretet." + +#: lib/claper_web/live/event_live/manage.html.heex:545 +#, elixir-autogen, elixir-format, fuzzy +msgid "Time to launch your presentation!" +msgstr "Itt az idő a prezentáció elindítására!" + +#: lib/claper_web/live/event_live/manage.html.heex:1451 +#, elixir-autogen, elixir-format +msgid "Use the associated keyboard shortcuts for quick toggling of these settings." +msgstr "Használja a kapcsolódó billentyűparancsokat a beállítások gyors váltogatásához." + +#: lib/claper_web/live/event_live/manage.html.heex:1451 +#, elixir-autogen, elixir-format +msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." +msgstr "Lehetősége van a beállításokat a prezentációs képernyőn és a résztvevői szobában egyenként állítani." + +#: lib/claper_web/live/event_live/index.html.heex:149 +#, elixir-autogen, elixir-format +msgid "Your first steps with Claper" +msgstr "Első lépések a Claper-rel" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." +msgstr "Az eseményt a kezdési dátum előtt megnyitó résztvevők egy várószobába kerülnek átirányításra." + +#: lib/claper_web/live/event_live/index.html.heex:167 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create event" +msgstr "Esemény létrehozása" + +#: lib/claper_web/live/event_live/index.html.heex:225 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create your first event" +msgstr "Hozza létre első eseményét" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "Kezdési dátum" + +#: lib/claper_web/live/event_live/index.html.heex:119 +#, elixir-autogen, elixir-format +msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." +msgstr "Amennyiben nincs elég ideje, és prezentáció nélküli interakciókat szeretne készíteni, hozzon létre egy új eseményt itt." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." +msgstr "Ha segítségre van szüksége az esemény kezelésében, adjon hozzáférést más felhasználóknak. Adja meg a meghívni kívánt személyek e-mail címeit. A megadott címmel való regisztráció után automatikusan kezelni tudják az eseményt." + +#: lib/claper_web/live/event_live/index.html.heex:124 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "Kevés az ideje?" + +#: lib/claper_web/live/event_live/event_card_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "Élő" + +#: lib/claper_web/live/event_live/index.html.heex:112 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "Eseményeim" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Name of your event" +msgstr "Az esemény neve" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 +#, elixir-autogen, elixir-format, fuzzy +msgid "Note: Facilitators do not have the ability to delete your event." +msgstr "Megjegyzés: A facilitátorok nem tudják törölni az eseményt." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation file (optional)" +msgstr "Prezentáció (opcionális)" + +#: lib/claper_web/live/event_live/index.html.heex:142 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "Gyors esemény" + +#: lib/claper_web/live/event_live/index.ex:102 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "Gyors esemény sikeresen létrehozva" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Return to your last event" +msgstr "Vissza az utolsó eseményre" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select the start date for your event. Future dates are permissible." +msgstr "Válassza ki az esemény kezdési dátumát. Csak jövőbeni dátumok engedélyezettek." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:88 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select your presentation (optional)" +msgstr "Válassza ki a prezentációt (opcionális)" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 +#, elixir-autogen, elixir-format, fuzzy +msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." +msgstr "A résztvevők ezt a kódot fogják használni a csatlakozáshoz. Lehetőség van egyéni kódot is létrehozni." + +#: lib/claper_web/live/event_live/show.ex:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "Az esemény befejeződött" + +#: lib/claper_web/live/event_live/index.html.heex:148 +#, elixir-autogen, elixir-format, fuzzy +msgid "Welcome to Claper! You can create a new event here." +msgstr "Üdvözli a Claper! Hozzon létre egy új eseményt." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "When your event will start?" +msgstr "Mikor kezdődik az esemény?" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "Hozza létre következő prezentációját ezzel:" + +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 +#: lib/claper_web/live/event_live/show.ex:25 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "Az esemény nem található" + +#: lib/claper_web/live/user_settings_live/show.html.heex:244 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "Fiók testreszabása" + +#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "Nyelv" + +#: lib/claper_web/live/user_settings_live/show.html.heex:241 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "Beállítások" + +#: lib/claper_web/live/user_settings_live/show.ex:180 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "Beállítások frissítve." + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "Kérdés" + +#: lib/claper_web/live/event_live/manage.html.heex:1167 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "Kérdések" + +#: lib/claper_web/live/event_live/manage.html.heex:1254 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "A kérdések itt fognak megjelenni." + +#: lib/claper_web/live/event_live/manage.html.heex:1296 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "Rendezés dátum szerint" + +#: lib/claper_web/live/event_live/manage.html.heex:1275 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "Rendezés népszerűség szerint" + +#: lib/claper_web/live/event_live/event_card_component.ex:152 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "Eseménykezelő" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "Dokumentáció" + +#: lib/claper_web/live/user_settings_live/show.html.heex:5 +#: lib/claper_web/templates/layout/_user_menu.html.heex:6 +#, elixir-autogen, elixir-format +msgid "My account" +msgstr "Fiókom" + +#: lib/claper_web/live/user_settings_live/show.html.heex:139 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your personal informations to access your account" +msgstr "Személyes adatok a fiókhoz való hozzáféréshez" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable reactions" +msgstr "Reakciók engedélyezése" + +#: lib/claper_web/templates/lti/registration/success.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Activate the tool in your LMS" +msgstr "Aktiválja az eszközt az LMS rendszerben" + +#: lib/claper_web/templates/lti/registration/new.html.heex:24 +#, elixir-autogen, elixir-format +msgid "Bring Claper to your LMS" +msgstr "Integrálja a Clapert az LMS rendszerével" + +#: lib/claper_web/templates/lti/registration/success.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Check the permissions to share name and email of users" +msgstr "Ellenőrizze az engedélyeket a felhasználók nevének és e-mail címének megosztásához" + +#: lib/claper_web/templates/lti/registration/success.html.heex:15 +#, elixir-autogen, elixir-format +msgid "Configure it to be opened in a new window" +msgstr "Állítsa be, hogy új ablakban nyíljon meg" + +#: lib/claper_web/templates/lti/launch/error.html.heex:5 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "Hiba" + +#: lib/claper_web/templates/lti/registration/new.html.heex:27 +#, elixir-autogen, elixir-format +msgid "Register your platform" +msgstr "Regisztrálja rendszerét" + +#: lib/claper_web/templates/lti/registration/success.html.heex:5 +#, elixir-autogen, elixir-format +msgid "Registration completed" +msgstr "Sikeres regisztráció" + +#: lib/claper_web/templates/lti/launch/error.html.heex:9 +#, elixir-autogen, elixir-format +msgid "You cannot perform this action" +msgstr "Nem végezheti el a kért műveletet" + +#: lib/claper_web/templates/lti/registration/success.html.heex:10 +#, elixir-autogen, elixir-format +msgid "Your next steps" +msgstr "Következő lépések" + +#: lib/claper_web/templates/lti/registration/new.html.heex:40 +#, elixir-autogen, elixir-format +msgid "Add Claper" +msgstr "A Claper hozzáadása" + +#: lib/claper_web/live/event_live/manage.html.heex:123 +#: lib/claper_web/live/event_live/manage.html.heex:538 +#, elixir-autogen, elixir-format +msgid "Close preview" +msgstr "Előnézet bezárása" + +#: lib/claper_web/live/event_live/manage.html.heex:734 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create your first interaction." +msgstr "Készítse el első interakcióját." + +#: lib/claper_web/live/event_live/manage.html.heex:1093 +#, elixir-autogen, elixir-format, fuzzy +msgid "Disable" +msgstr "Letiltás" + +#: lib/claper_web/live/event_live/manage.html.heex:1110 +#, elixir-autogen, elixir-format +msgid "Enable" +msgstr "Engedélyezés" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable messages to change this option" +msgstr "Engedélyezze az üzeneteket ezen beállítás megváltoztatásához" + +#: lib/claper_web/live/event_live/manage.html.heex:122 +#: lib/claper_web/live/event_live/manage.html.heex:537 +#, elixir-autogen, elixir-format +msgid "Open preview" +msgstr "Előnézet megnyitása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 +#, elixir-autogen, elixir-format +msgid "Show messages to change this option" +msgstr "Jelenítse meg az üzeneteket a beállítás megváltoztatásához" + +#: lib/claper_web/live/event_live/manage.html.heex:731 +#, elixir-autogen, elixir-format +msgid "This slide does not have any interactions." +msgstr "Nincsenek interakciók ezen a dián." + +#: lib/claper_web/live/user_settings_live/show.html.heex:176 +#, elixir-autogen, elixir-format +msgid "Accounts linked" +msgstr "Hozzákapcsolt fiókok" + +#: lib/claper_web/live/user_settings_live/show.html.heex:208 +#: lib/claper_web/live/user_settings_live/show.html.heex:226 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to unlink this account?" +msgstr "Biztos benne hogy leválasztja ezt a fiókot?" + +#: lib/claper_web/templates/user_session/new.html.heex:74 +#, elixir-autogen, elixir-format +msgid "Login with %{provider}" +msgstr "Bejelentkezés ezzel: %{provider}" + +#: lib/claper_web/live/user_settings_live/show.ex:101 +#: lib/claper_web/live/user_settings_live/show.ex:115 +#, elixir-autogen, elixir-format +msgid "The account has been unlinked." +msgstr "A fiók sikeresen leválasztva." + +#: lib/claper_web/live/event_live/manage.html.heex:707 +#, elixir-autogen, elixir-format +msgid "This section contains all your interactions." +msgstr "Itt látható az összes interakció." + +#: lib/claper_web/live/user_settings_live/show.html.heex:211 +#: lib/claper_web/live/user_settings_live/show.html.heex:229 +#, elixir-autogen, elixir-format, fuzzy +msgid "Unlink" +msgstr "Leválasztás" + +#: lib/claper_web/live/event_live/manage.html.heex:707 +#, elixir-autogen, elixir-format +msgid "You can add interactions to your presentation slides." +msgstr "Interakciókat adhat a diáihoz." + +#: lib/claper_web/live/event_live/manage.html.heex:706 +#, elixir-autogen, elixir-format +msgid "Your interactions" +msgstr "Interakciók" + +#: lib/claper_web/live/user_settings_live/show.html.heex:119 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm password" +msgstr "Jelszó megerősítése" + +#: lib/claper_web/live/user_settings_live/show.ex:68 +#, elixir-autogen, elixir-format +msgid "Set a new password" +msgstr "Új jelszó" + +#: lib/claper_web/live/user_settings_live/show.ex:71 +#, elixir-autogen, elixir-format +msgid "Set a new password for your account before unlinking it." +msgstr "Adjon meg egy új jelszót a fiók leválasztása előtt." + +#: lib/claper_web/live/user_settings_live/show.ex:204 +#, elixir-autogen, elixir-format +msgid "Your password has been set, you can now unlink your account." +msgstr "Jelszó beállítva, most már leválaszthatja a fiókot." + +#: lib/claper_web/live/embed_live/form_component.html.heex:34 +#, elixir-autogen, elixir-format +msgid "Iframe code" +msgstr "Iframe kód" + +#: lib/claper_web/live/embed_live/form_component.html.heex:35 +#, elixir-autogen, elixir-format +msgid "Link to the content" +msgstr "Link a tartalomhoz" + +#: lib/claper/embeds/embed.ex:65 +#: lib/claper/embeds/embed.ex:74 +#: lib/claper/embeds/embed.ex:83 +#: lib/claper/embeds/embed.ex:92 +#, elixir-autogen, elixir-format +msgid "Please enter a valid %{provider} link" +msgstr "Adjon meg egy érvényes linket a következőhöz: %{provider}" + +#: lib/claper/embeds/embed.ex:62 +#: lib/claper/embeds/embed.ex:71 +#: lib/claper/embeds/embed.ex:80 +#: lib/claper/embeds/embed.ex:89 +#, elixir-autogen, elixir-format +msgid "Please enter a valid link starting with http:// or https://" +msgstr "Adjon meg egy http:// vagy https:// előtaggal kezdődő érvényes linket" + +#: lib/claper/embeds/embed.ex:98 +#, elixir-autogen, elixir-format +msgid "Please enter valid HTML content with an iframe tag" +msgstr "Adjon meg érvényes HTML tartalmat iframe taggel" + +#: lib/claper_web/live/embed_live/form_component.html.heex:23 +#, elixir-autogen, elixir-format +msgid "Provider" +msgstr "Szolgáltató" + +#: lib/claper_web/live/poll_live/form_component.html.heex:85 +#, elixir-autogen, elixir-format +msgid "Attendees can see the results on their device" +msgstr "A résztvevők az eszközükön megtekinthetik az eredményeket" + +#: lib/claper_web/live/embed_live/form_component.html.heex:50 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees can view the web content on their device" +msgstr "A résztvevük az eszközükön megtekinthetik a webes tartalmat" + +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 +#, elixir-autogen, elixir-format +msgid "Options" +msgstr "Beállítások" + +#: lib/claper_web/live/event_live/event_card_component.ex:268 +#: lib/claper_web/live/event_live/event_card_component.ex:418 +#, elixir-autogen, elixir-format +msgid "Duplicate" +msgstr "Másolat" + +#: lib/claper_web/templates/error/csrf_error.html.heex:8 +#, elixir-autogen, elixir-format +msgid "A required security token was not found or was invalid." +msgstr "A szükséges biztonsági token nem található vagy érvénytelen." + +#: lib/claper_web/templates/error/csrf_error.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Back to Login" +msgstr "Vissza a bejelentkezéshez" + +#: lib/claper_web/templates/error/csrf_error.html.heex:5 +#, elixir-autogen, elixir-format +msgid "CSRF Verification Failed" +msgstr "CSRF ellenőrzés sikertelen" + +#: lib/claper_web/templates/error/csrf_error.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Clear cookies (at least for Claper domain)" +msgstr "Törölje a sütiket (legalább a Claper domainre vonatkozókat)" + +#: lib/claper_web/templates/error/csrf_error.html.heex:20 +#, elixir-autogen, elixir-format +msgid "Ensure the URL does not contain an extra \"/\" anywhere" +msgstr "Győződjön meg róla, hogy a megadott URL cím nem tartalmaz felesleges \"/\" karaktereket" + +#: lib/claper_web/templates/error/csrf_error.html.heex:23 +#, elixir-autogen, elixir-format +msgid "If the problem persists, please contact support." +msgstr "Amennyiben a probléma továbbra is fennáll, vegye fel a kapcsolatot az üzemeltetőkkel." + +#: lib/claper_web/templates/error/csrf_error.html.heex:14 +#, elixir-autogen, elixir-format +msgid "If you're continually seeing this issue, try the following:" +msgstr "Amennyiben ez a probléma gyakran előfordul, próbálja meg a következőt:" + +#: lib/claper_web/templates/error/csrf_error.html.heex:18 +#, elixir-autogen, elixir-format +msgid "Reload the page you're trying to access (don't re-submit data)" +msgstr "Töltse újra az elérni kívánt oldalt, de ne küldje újra az adatokat." + +#: lib/claper_web/templates/error/csrf_error.html.heex:19 +#, elixir-autogen, elixir-format +msgid "Try logging in again" +msgstr "Jelentkezzen be újra" + +#: lib/claper_web/live/event_live/event_card_component.ex:201 +#, elixir-autogen, elixir-format +msgid "End" +msgstr "Befejezés" + +#: lib/claper_web/live/event_live/event_card_component.ex:212 +#: lib/claper_web/live/event_live/event_card_component.ex:292 +#: lib/claper_web/live/event_live/event_card_component.ex:381 +#, elixir-autogen, elixir-format +msgid "More options" +msgstr "További lehetőségek" + +#: lib/claper_web/live/event_live/manage.ex:818 +#, elixir-autogen, elixir-format +msgid "No" +msgstr "Nem" + +#: lib/claper_web/live/event_live/manage.ex:818 +#, elixir-autogen, elixir-format +msgid "Yes" +msgstr "Igen" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:29 +#, elixir-autogen, elixir-format +msgid "CONFIRM ACCOUNT" +msgstr "FIÓK MEGERŐSÍTÉSE" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Confirm account" +msgstr "Fiók megerősítése" + +#: lib/claper_web/notifiers/user_notifier.ex:45 +#, elixir-autogen, elixir-format +msgid "Confirmation instructions" +msgstr "A megerősítés lépései" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:29 +#, elixir-autogen, elixir-format +msgid "RESET PASSWORD" +msgstr "JELSZÓ VISSZAÁLLÍTÁSA" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Reset password" +msgstr "Jelszó visszaállítása" + +#: lib/claper_web/notifiers/user_notifier.ex:56 +#, elixir-autogen, elixir-format +msgid "Reset password instructions" +msgstr "Jelszó-visszaállítás lépései" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your account by visiting the URL below" +msgstr "Erősítse meg fiókját az alábbi linkre kattintva" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can reset your password by visiting the URL below" +msgstr "A jelszó visszaállításához kattintson az alábbi linkre" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 +#, elixir-autogen, elixir-format +msgid "back to the home page" +msgstr "Vissza a főoldalra" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 +#, elixir-autogen, elixir-format, fuzzy +msgid "Add Question" +msgstr "Kérdés hozzáadása" + +#: lib/claper_web/live/event_live/manage.html.heex:293 +#, elixir-autogen, elixir-format +msgid "Add a quiz to test knowledge." +msgstr "Kvíz hozzáadása a tudás felméréséhez" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 +#, elixir-autogen, elixir-format +msgid "Add answer" +msgstr "Válasz hozzáadása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 +#, elixir-autogen, elixir-format, fuzzy +msgid "Allow anonymous messages" +msgstr "Névtelen üzenetek engedélyezése" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 +#, elixir-autogen, elixir-format +msgid "Answer %{index}" +msgstr "%{index}. válasz" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees" +msgstr "Résztvevők" + +#: lib/claper_web/live/event_live/manageable_quiz_component.ex:29 +#: lib/claper_web/live/stat_live/index.html.heex:426 +#, elixir-autogen, elixir-format, fuzzy +msgid "Average score" +msgstr "Átlag" + +#: lib/claper_web/live/event_live/quiz_component.ex:60 +#, elixir-autogen, elixir-format +msgid "Current quiz" +msgstr "Jelenlegi kvíz" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 +#, elixir-autogen, elixir-format, fuzzy +msgid "Deny anonymous messages" +msgstr "Névtelen üzenetek tiltása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 +#, elixir-autogen, elixir-format, fuzzy +msgid "Disable messages" +msgstr "Üzenetek tiltása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 +#, elixir-autogen, elixir-format, fuzzy +msgid "Disable reactions" +msgstr "Reakciók tiltása" + +#: lib/claper_web/live/event_live/manage.html.heex:368 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit quiz" +msgstr "Kvíz szerkesztése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 +#, elixir-autogen, elixir-format +msgid "Hide instructions to join" +msgstr "Csatlakozási információk elrejtése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 +#, elixir-autogen, elixir-format, fuzzy +msgid "Hide messages" +msgstr "Üzenetek elrejtése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:62 +#: lib/claper_web/live/event_live/manager_settings_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Hide results on presentation" +msgstr "Eredmények eltüntetése a prezentációról" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:36 +#: lib/claper_web/live/event_live/index.html.heex:28 +#: lib/claper_web/live/event_live/manage.html.heex:35 +#, elixir-autogen, elixir-format +msgid "How it works ?" +msgstr "Hogyan működik ?" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "Interaction" +msgstr "Interakció" + +#: lib/claper_web/live/event_live/manage.html.heex:367 +#, elixir-autogen, elixir-format +msgid "New quiz" +msgstr "Új kvíz" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation" +msgstr "Prezentáció" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:168 +#, elixir-autogen, elixir-format +msgid "Previous" +msgstr "Előző" + +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 +#, elixir-autogen, elixir-format +msgid "Quiz" +msgstr "Kvíz" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#, elixir-autogen, elixir-format +msgid "Remove question" +msgstr "Kérdés eltávolítása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:144 +#, elixir-autogen, elixir-format +msgid "Review questions" +msgstr "Kérdések áttekintése" + +#: lib/claper_web/live/event_live/quiz_component.ex:41 +#, elixir-autogen, elixir-format, fuzzy +msgid "See current quiz" +msgstr "Jelenlegi kvíz megtekintése" + +#: lib/claper_web/live/event_live/manage.html.heex:387 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select presentation" +msgstr "Prezentáció kiválasztása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show all messages" +msgstr "Minden üzenet megjelenítése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show instructions to join" +msgstr "Csatlakozási információk mutatása" + +#: lib/claper_web/live/event_live/quiz_component.ex:121 +#, elixir-autogen, elixir-format +msgid "Show results" +msgstr "Eredmények mutatása" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:65 +#: lib/claper_web/live/event_live/manager_settings_component.ex:115 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show results on presentation" +msgstr "Eredmények megjelenítése a prezentáción" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "This will delete all responses associated and the quiz itself, are you sure?" +msgstr "A kvíz és a hozzátartozó válaszok törlődni fognak. Biztos benne?" + +#: lib/claper_web/live/event_live/quiz_component.ex:124 +#, elixir-autogen, elixir-format +msgid "Waiting for results..." +msgstr "Várakozás az eredményekre..." + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 +#, elixir-autogen, elixir-format +msgid "Your question" +msgstr "Az Ön kérdése" + +#: lib/claper_web/live/event_live/quiz_component.ex:113 +#, elixir-autogen, elixir-format +msgid "Your score" +msgstr "Az ön pontszáma" + +#: lib/claper_web/live/stat_live/index.html.heex:236 +#: lib/claper_web/live/stat_live/index.html.heex:298 +#: lib/claper_web/live/stat_live/index.html.heex:380 +#: lib/claper_web/live/stat_live/index.html.heex:422 +#, elixir-autogen, elixir-format +msgid "Export" +msgstr "Exportálás" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 +#, elixir-autogen, elixir-format +msgid "Export to QTI (XML)" +msgstr "Exportálás QTI (XML) formátumba" + +#: lib/claper_web/live/stat_live/index.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Forms" +msgstr "Űrlapok" + +#: lib/claper_web/live/stat_live/index.html.heex:170 +#, elixir-autogen, elixir-format, fuzzy +msgid "Interactions" +msgstr "Interakciók" + +#: lib/claper_web/live/stat_live/index.html.heex:338 +#, elixir-autogen, elixir-format +msgid "No form has been created" +msgstr "Nincsenek űrlapok" + +#: lib/claper_web/live/stat_live/index.html.heex:272 +#, elixir-autogen, elixir-format +msgid "No poll has been created" +msgstr "Nincsenek szavazások" + +#: lib/claper_web/live/stat_live/index.html.heex:476 +#, elixir-autogen, elixir-format +msgid "No quiz has been created" +msgstr "Nincsenek kvízek" + +#: lib/claper_web/live/stat_live/index.html.heex:359 +#, elixir-autogen, elixir-format +msgid "No web content has been created" +msgstr "Nincsenek webes tartalmak" + +#: lib/claper_web/live/stat_live/index.html.heex:187 +#, elixir-autogen, elixir-format, fuzzy +msgid "Polls" +msgstr "Szavazások" + +#: lib/claper_web/live/stat_live/index.html.heex:208 +#, elixir-autogen, elixir-format, fuzzy +msgid "Quizzes" +msgstr "Kvízek" + +#: lib/claper_web/live/stat_live/index.ex:62 +#, elixir-autogen, elixir-format +msgid "Report" +msgstr "Jelentés" + +#: lib/claper_web/live/stat_live/index.html.heex:70 +#, elixir-autogen, elixir-format +msgid "Unique attendees" +msgstr "Egyedi résztvevők" + +#: lib/claper_web/live/stat_live/index.html.heex:201 +#, elixir-autogen, elixir-format, fuzzy +msgid "Web Content" +msgstr "Webes Tartalom" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 +#, elixir-autogen, elixir-format +msgid "Active" +msgstr "Aktív" + +#: lib/claper_web/live/event_live/index.html.heex:218 +#, elixir-autogen, elixir-format +msgid "Load more" +msgstr "Több betöltése" + +#: lib/claper_web/live/event_live/index.html.heex:195 +#, elixir-autogen, elixir-format +msgid "Shared with you" +msgstr "Önnel megosztva" + +#: lib/claper_web/templates/lti/registration/new.html.heex:43 +#, elixir-autogen, elixir-format +msgid "You must login to continue" +msgstr "Jelentkezzen be a folytatáshoz" + +#: lib/claper/quizzes/quiz_question.ex:51 +#, elixir-autogen, elixir-format +msgid "must have at least one correct answer" +msgstr "legalább egy helyes válasz szükséges" + +#: lib/claper_web/live/event_live/manage.html.heex:547 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." +msgstr "Kattintson ide a prezentáció ablakának megnyitásához. Nyomja le a F billentyűt a teljes képernyő bekapcsolásához." + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 +#, elixir-autogen, elixir-format, fuzzy +msgid "Allow anonymous submissions" +msgstr "Névtelen beküldés engedélyezése" + +#: lib/claper_web/live/event_live/quiz_component.ex:167 +#, elixir-autogen, elixir-format +msgid "Please sign in to submit your answers" +msgstr "Jelentkezzen be a válaszok beküldéséhez" + +#: lib/claper_web/live/event_live/quiz_component.ex:170 +#, elixir-autogen, elixir-format +msgid "Sign in" +msgstr "Bejelentkezés" + +#: lib/claper_web/live/stat_live/index.html.heex:435 +#, elixir-autogen, elixir-format +msgid "Total submissions" +msgstr "Összes beküldés" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Beállítások" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Aktív" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "Biztos benne hogy leválasztja ezt a fiókot?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "Biztos benne hogy leválasztja ezt a fiókot?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "Biztos benne hogy leválasztja ezt a fiókot?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Részvételi csúcs" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Fájl megváltoztatása" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format +msgid "Confirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Esemény létrehozása" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Létrehozás" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Létrehozás" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Létrehozás" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Jelenlegi kvíz" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Törlés" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Törlés" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Szerkesztés" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Jelenlegi jelszó" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Esemény" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Űrlapok" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Aktív" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "Szolgáltató" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "Szolgáltató" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "A jelszó sikeresen megváltoztatva." + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Válasszon egy opciót" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "A jelszó sikeresen megváltoztatva." + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Jelentés megtekintése" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "résztvevő" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format +msgid "Back to events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "Back to providers" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format +msgid "Back to users" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format +msgid "New provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format +msgid "New user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format +msgid "No providers found" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format +msgid "Provider deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Szolgáltató" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "E-mail megerősítése" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Amennyiben nem regisztrált fiókot nálunk, kérjük, hagyja ezt az üzenetet figyelmen kívül." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Az e-mail megváltoztatásához kattintson az alábbi linkre:" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Résztvevők számának elrejtése" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Résztvevők számának megjelenítése" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Kötelező" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(opcionális)" diff --git a/priv/gettext/hu/LC_MESSAGES/errors.po b/priv/gettext/hu/LC_MESSAGES/errors.po new file mode 100644 index 0000000..04f7625 --- /dev/null +++ b/priv/gettext/hu/LC_MESSAGES/errors.po @@ -0,0 +1,97 @@ +## `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" + +## From Ecto.Changeset.cast/4 +msgid "can't be blank" +msgstr "nem lehet üres" + +## From Ecto.Changeset.unique_constraint/3 +msgid "has already been taken" +msgstr "már foglalt" + +## From Ecto.Changeset.put_change/3 +msgid "is invalid" +msgstr "érvénytelen" + +## From Ecto.Changeset.validate_acceptance/3 +msgid "must be accepted" +msgstr "el kell fogadni" + +## From Ecto.Changeset.validate_format/3 +msgid "has invalid format" +msgstr "formátuma érvénytelen" + +## From Ecto.Changeset.validate_subset/3 +msgid "has an invalid entry" +msgstr "érvénytelen bejegyzést tartalmaz" + +## From Ecto.Changeset.validate_exclusion/3 +msgid "is reserved" +msgstr "foglalt" + +## From Ecto.Changeset.validate_confirmation/3 +msgid "does not match confirmation" +msgstr "nem egyezik meg a megerősítéssel" + +## From Ecto.Changeset.no_assoc_constraint/3 +msgid "is still associated with this entry" +msgstr "még mindig ehhez a bejegyzéshez tartozik" + +msgid "are still associated with this entry" +msgstr "még mindig ehhez a bejegyzéshez tartoznak" + +msgid "should be %{count} character(s)" +msgid_plural "should be %{count} character(s)" +msgstr[0] "%{count} karakternek kell lennie" +msgstr[1] "%{count} karakternek kell lennie" + +## From Ecto.Changeset.validate_length/3 +msgid "should have %{count} item(s)" +msgid_plural "should have %{count} item(s)" +msgstr[0] "%{count} elemnek kell lennie" +msgstr[1] "%{count} elemnek kell lennie" + +msgid "should be at least %{count} character(s)" +msgid_plural "should be at least %{count} character(s)" +msgstr[0] "Legalább %{count} karakternek kell lennie" +msgstr[1] "Legalább %{count} karakternek kell lennie" + +msgid "should have at least %{count} item(s)" +msgid_plural "should have at least %{count} item(s)" +msgstr[0] "legalább %{count} elem lehet" +msgstr[1] "legalább %{count} elem lehet" + +msgid "should be at most %{count} character(s)" +msgid_plural "should be at most %{count} character(s)" +msgstr[0] "legfeljebb %{count} karakter lehet" +msgstr[1] "legfeljebb %{count} karakter lehet" + +msgid "should have at most %{count} item(s)" +msgid_plural "should have at most %{count} item(s)" +msgstr[0] "legfeljebb %{count} elem lehet" +msgstr[1] "legfeljebb %{count} elem lehet" + +## From Ecto.Changeset.validate_number/3 +msgid "must be less than %{number}" +msgstr "kisebbnek kell lennie ennél: %{number}" + +msgid "must be greater than %{number}" +msgstr "nagyobbnak kell lennie ennél: %{number}" + +msgid "must be less than or equal to %{number}" +msgstr "kisebbnek vagy egyenlőnek kell lennie ezzel: %{number}" + +msgid "must be greater than or equal to %{number}" +msgstr "nagyobbnak vagy egyenlőnek kell lennie ezzel: %{number}" + +msgid "must be equal to %{number}" +msgstr "egyenlőnek kell lennie ezzel: %{number}" diff --git a/priv/gettext/it/LC_MESSAGES/default.po b/priv/gettext/it/LC_MESSAGES/default.po index c19b49d..da913c4 100644 --- a/priv/gettext/it/LC_MESSAGES/default.po +++ b/priv/gettext/it/LC_MESSAGES/default.po @@ -9,15 +9,18 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.0.1\n" -#: lib/claper_web/live/event_live/manage.html.heex:1462 -#: lib/claper_web/live/event_live/manage.html.heex:1468 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Impostazioni" -#: lib/claper_web/live/event_live/manage.ex:808 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -44,7 +47,10 @@ msgstr "Ops, controlla che tutti i campi siano compilati correttamente." msgid "Change" msgstr "Cambia" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "Codice" @@ -55,7 +61,7 @@ msgstr "Codice" msgid "Email address" msgstr "Indirizzo email" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Esci" @@ -98,15 +104,18 @@ msgstr "Reagisci per primo !" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "Partecipa" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Cruscotto" @@ -123,7 +132,7 @@ msgid "seconds" msgstr "secondi" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Terminato" @@ -176,47 +185,50 @@ msgstr "Ritorna alla home" msgid "Created successfully" msgstr "Creato correttamente" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Modifica" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "Crea" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Elimina" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -260,12 +272,6 @@ msgstr "Aggiorna le istruzioni via email" msgid "CONFIRM EMAIL" msgstr "CONFERMA EMAIL" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "Conferma email" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -296,9 +302,9 @@ msgid "Presentation uploaded" msgstr "Presentazione caricata" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Rimuovi" @@ -333,17 +339,17 @@ msgstr "Il tuo file è troppo grande" msgid "Change file" msgstr "Cambia file" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Presentazione sostituita" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Modifica sondaggio" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Nuovo sondaggio" @@ -358,18 +364,18 @@ msgstr "Titolo del tuo sondaggio" msgid "Upload failed" msgstr "Caricamento non riuscito" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "Aggiungi un sondaggio per conoscere l'opinione del tuo pubblico." -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:791 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Sondaggio" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -392,18 +398,18 @@ msgstr "Vedi sondaggio attuale" msgid "Vote" msgstr "Vota" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Indirizzo email utente" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "La modifica del file rimuoverà tutti gli elementi di interazione associati, come i sondaggi." -#: lib/claper_web/live/event_live/manage.html.heex:1226 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "I messaggi delle persone partecipanti appariranno qui." @@ -413,29 +419,24 @@ msgstr "I messaggi delle persone partecipanti appariranno qui." msgid "Processing your file..." msgstr "Elaborazione del file in corso..." -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "Verranno eliminate tutte le risposte associate e il sondaggio stesso. Sei sicuro?" -#: lib/claper_web/live/event_live/manage.html.heex:507 -#, elixir-autogen, elixir-format -msgid "Press F in the presentation window to enable fullscreen" -msgstr "Premi F nella finestra di presentazione per abilitare la modalità a schermo intero" - #: lib/claper_web/live/event_live/show.html.heex:345 #, elixir-autogen, elixir-format msgid "Ask, comment..." msgstr "Chiedi, commenta..." -#: lib/claper_web/live/event_live/manage.html.heex:1172 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Messaggi" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Aggiungi aiutante" @@ -450,7 +451,7 @@ msgstr "Ops, la pagina non esiste." msgid "The site is under maintenance, we'll be back very soon!" msgstr "Il sito è in manutenzione, torneremo presto!" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "Gli aiutanti possono presentare e gestire le interazioni" @@ -464,13 +465,8 @@ msgstr "Gli aiutanti possono presentare e gestire le interazioni" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "Se riscontri problemi con il pulsante sopra, copia e incolla l'URL sottostante nel tuo browser web" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "Puoi modificare la tua email visitando l'URL sottostante" - -#: lib/claper_web/live/event_live/manage.html.heex:764 -#: lib/claper_web/live/event_live/manage.html.heex:1137 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "Aggiungi interazione" @@ -628,6 +624,7 @@ msgstr "Oppure usa il codice:" msgid "Create account" msgstr "Crea utenza" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -663,14 +660,14 @@ msgstr "Aggiorna la tua password" msgid "Your password has been updated." msgstr "La tua password è stata aggiornata." -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "Campo %{count}" msgstr[1] "Campi %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "Aggiungi un modulo per raccogliere dati dal tuo pubblico." @@ -680,34 +677,41 @@ msgstr "Aggiungi un modulo per raccogliere dati dal tuo pubblico." msgid "Current form" msgstr "Modulo corrente" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "Modifica modulo" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:835 -#: lib/claper_web/live/event_live/manage.html.heex:1422 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "Modulo" -#: lib/claper_web/live/event_live/manage.html.heex:1196 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Invio di moduli" -#: lib/claper_web/live/event_live/manage.html.heex:1395 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "I moduli compilati dai partecipanti appariranno qui." -#: lib/claper_web/live/event_live/manage.ex:807 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "Nome" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "Nuovo modulo" @@ -728,17 +732,17 @@ msgstr "Vedi il modulo corrente" msgid "Submit" msgstr "Invia" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "Testo" -#: lib/claper_web/live/event_live/manage.html.heex:1415 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Questa operazione non può essere annullata, confermi ?" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "Verranno eliminate tutte le risposte associate e il modulo stesso. Sei sicuro?" @@ -748,7 +752,7 @@ msgstr "Verranno eliminate tutte le risposte associate e il modulo stesso. Sei s msgid "Title of your form" msgstr "Titolo del tuo modulo" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "Tipo" @@ -763,7 +767,7 @@ msgstr "Seleziona un'opzione" msgid "Select one or multiple options" msgstr "Seleziona una o più opzioni" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "Risposte multiple" @@ -773,12 +777,12 @@ msgstr "Risposte multiple" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX fino a %{size} MB" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Abilita messaggi" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Mostra messaggi" @@ -827,7 +831,7 @@ msgstr "disabilitato" msgid "Account creation is disabled" msgstr "La creazione dell'utenza è disabilitata" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Aggiungi un video di Youtube o qualsiasi contenuto web." @@ -878,12 +882,12 @@ msgstr "Invia il link per reimpostare la password" msgid "Current web content" msgstr "Contenuto web attuale" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Modifica contenuto web" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Nuovo contenuto web" @@ -893,7 +897,7 @@ msgstr "Nuovo contenuto web" msgid "See current web content" msgstr "Vedi contenuto web corrente" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format msgid "This will delete the web content, are you sure?" msgstr "Questo eliminerà il contenuto web, sei sicuro?" @@ -904,8 +908,8 @@ msgstr "Questo eliminerà il contenuto web, sei sicuro?" msgid "Title" msgstr "Titolo" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:879 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Contenuto web" @@ -922,17 +926,17 @@ msgstr "Appunta" msgid "Pinned" msgstr "Appuntato" -#: lib/claper_web/live/event_live/manage.html.heex:1188 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "Messaggi appuntati" -#: lib/claper_web/live/event_live/manage.html.heex:1349 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "I messaggi appuntati verranno visualizzati qui." -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Mostra solo i messaggi appuntati" @@ -973,7 +977,7 @@ msgstr "Sei stato invitato a gestire un evento" msgid "Saved" msgstr "Salvato" -#: lib/claper_web/live/user_settings_live/show.html.heex:286 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "Tutti i tuoi eventi e file verranno eliminati definitivamente, sei sicuro?" @@ -988,22 +992,22 @@ msgstr "Vuoi davvero terminare questo evento? Questa azione non può essere annu msgid "Attendees room" msgstr "Sala partecipanti" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "Attenzione, queste azioni sono irreversibili" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "Zona pericolosa" -#: lib/claper_web/live/user_settings_live/show.html.heex:291 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format msgid "Delete account" msgstr "Elimina utenza" -#: lib/claper_web/live/event_live/manage.html.heex:571 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "Apri presentazione" @@ -1013,12 +1017,12 @@ msgstr "Apri presentazione" msgid "View report" msgstr "Vedi report" -#: lib/claper_web/live/user_settings_live/show.ex:219 +#: lib/claper_web/controllers/user_registration_controller.ex:50 #, elixir-autogen, elixir-format msgid "Your account has been deleted." msgstr "La tua utenza è stata eliminata." -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format msgid "Access code" msgstr "Codice di accesso" @@ -1028,51 +1032,46 @@ msgstr "Codice di accesso" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "Le animazioni nei file PPT/PPTX non sono supportate, motivo per cui consigliamo di esportare la presentazione in PDF per garantirne la corretta visualizzazione." -#: lib/claper_web/live/event_live/manage.html.heex:1160 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format msgid "Attendees interactions" msgstr "Interazioni con i partecipanti" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "Indietro" -#: lib/claper_web/live/event_live/manage.html.heex:553 -#, elixir-autogen, elixir-format -msgid "Click here to open the presentation window." -msgstr "Fare clic qui per aprire la finestra della presentazione." - -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format msgid "Facilitators" msgstr "Aiutanti" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format msgid "Finish" msgstr "Terminato" -#: lib/claper_web/live/event_live/manage.html.heex:1162 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "Qui troverai tutte le interazioni dei tuoi partecipanti. Puoi gestire messaggi, messaggi appuntati e moduli compilati." -#: lib/claper_web/live/event_live/manage.html.heex:1162 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "Identifica gli utenti tramite i loro avatar unici." #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1085,57 +1084,57 @@ msgstr "Prossimo" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "Seleziona il file della tua presentazione. I formati accettati sono PDF, PPT o PPTX. Assicurati che la dimensione del file non superi il limite massimo." -#: lib/claper_web/live/event_live/manage.html.heex:551 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format msgid "Time to launch your presentation!" msgstr "È il momento di lanciare la tua presentazione!" -#: lib/claper_web/live/event_live/manage.html.heex:1464 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "Per attivare/disattivare rapidamente queste impostazioni, utilizzare le scorciatoie da tastiera associate." -#: lib/claper_web/live/event_live/manage.html.heex:1464 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "È possibile controllare ogni impostazione della presentazione (visualizzata sul grande schermo) e della sala dei partecipanti." -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "I tuoi primi passi con Claper" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "I partecipanti che tenteranno di accedere all'evento prima di tale data verranno indirizzati a una sala d'attesa." -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format msgid "Create event" msgstr "Crea evento" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format msgid "Create your first event" msgstr "Crea il tuo primo evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "Data di inizio dell'evento" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "Se non hai tempo e vuoi solo interagire senza un file di presentazione, puoi creare un nuovo evento qui." -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "Se hai bisogno di assistenza nella gestione del tuo evento, puoi concedere l'accesso ad altre persone. Inserisci semplicemente i loro indirizzi email; una volta che avranno registrato un'utenza con queste email, saranno in grado di gestire l'evento." -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "Hai fretta ?" @@ -1145,18 +1144,18 @@ msgstr "Hai fretta ?" msgid "Live" msgstr "Dal vivo" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "I miei eventi" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format msgid "Name of your event" msgstr "Nome del tuo evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format msgid "Note: Facilitators do not have the ability to delete your event." msgstr "Nota: gli aiutanti non hanno la possibilità di eliminare il tuo evento." @@ -1166,12 +1165,12 @@ msgstr "Nota: gli aiutanti non hanno la possibilità di eliminare il tuo evento. msgid "Presentation file (optional)" msgstr "File di presentazione (facoltativo)" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "Evento veloce" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "Evento veloce creato correttamente" @@ -1181,7 +1180,7 @@ msgstr "Evento veloce creato correttamente" msgid "Return to your last event" msgstr "Torna al tuo ultimo evento" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format msgid "Select the start date for your event. Future dates are permissible." msgstr "Seleziona la data di inizio del tuo evento. Sono ammesse date future." @@ -1191,7 +1190,7 @@ msgstr "Seleziona la data di inizio del tuo evento. Sono ammesse date future." msgid "Select your presentation (optional)" msgstr "Seleziona la tua presentazione (facoltativo)" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "Questo codice verrà utilizzato dai tuoi partecipanti per accedere all'evento. Hai la possibilità di creare un codice personalizzato." @@ -1201,12 +1200,12 @@ msgstr "Questo codice verrà utilizzato dai tuoi partecipanti per accedere all'e msgid "This event has been terminated" msgstr "Questo evento è stato terminato" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format msgid "Welcome to Claper! You can create a new event here." msgstr "Benvenuto in Claper! Qui puoi creare un nuovo evento." -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format msgid "When your event will start?" msgstr "Quando inizierà il tuo evento?" @@ -1216,8 +1215,8 @@ msgstr "Quando inizierà il tuo evento?" msgid "Create your next presentation with" msgstr "Crea la tua prossima presentazione con" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1228,7 +1227,7 @@ msgstr "L'evento non esiste" msgid "Customize your account" msgstr "Personalizza la tua utenza" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "Lingua" @@ -1248,22 +1247,22 @@ msgstr "Le tue preferenze sono state aggiornate." msgid "Question" msgstr "Domanda" -#: lib/claper_web/live/event_live/manage.html.heex:1180 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "Domande" -#: lib/claper_web/live/event_live/manage.html.heex:1267 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "Le domande appariranno qui." -#: lib/claper_web/live/event_live/manage.html.heex:1309 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "Ordina per data" -#: lib/claper_web/live/event_live/manage.html.heex:1288 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "Ordina per popolarità" @@ -1273,7 +1272,8 @@ msgstr "Ordina per popolarità" msgid "Event manager" msgstr "Responsabile eventi" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "Documentazione" @@ -1289,7 +1289,7 @@ msgstr "La mia utenza" msgid "Your personal informations to access your account" msgstr "I tuoi dati personali per accedere alla tua utenza" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format msgid "Enable reactions" msgstr "Abilita reazioni" @@ -1345,43 +1345,43 @@ msgid "Add Claper" msgstr "Aggiungi Claper" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:544 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "Chiudi anteprima" -#: lib/claper_web/live/event_live/manage.html.heex:748 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format msgid "Create your first interaction." msgstr "Crea la tua prima interazione." -#: lib/claper_web/live/event_live/manage.html.heex:1106 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format msgid "Disable" msgstr "Disabilita" -#: lib/claper_web/live/event_live/manage.html.heex:1123 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "Abilita" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format msgid "Enable messages to change this option" msgstr "Abilita i messaggi per modificare questa opzione" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:543 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "Apri anteprima" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "Mostra messaggi per modificare questa opzione" -#: lib/claper_web/live/event_live/manage.html.heex:745 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "Questa diapositiva non ha interazioni." @@ -1408,7 +1408,7 @@ msgstr "Accedi con %{provider}" msgid "The account has been unlinked." msgstr "L'utenza è stata scollegata." -#: lib/claper_web/live/event_live/manage.html.heex:721 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "Questa sezione contiene tutte le tue interazioni." @@ -1419,12 +1419,12 @@ msgstr "Questa sezione contiene tutte le tue interazioni." msgid "Unlink" msgstr "Scollega" -#: lib/claper_web/live/event_live/manage.html.heex:721 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "Puoi aggiungere interazioni alle diapositive della tua presentazione." -#: lib/claper_web/live/event_live/manage.html.heex:720 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "Le tue interazioni" @@ -1449,12 +1449,12 @@ msgstr "Imposta una nuova password per la tua utenza prima di scollegarla." msgid "Your password has been set, you can now unlink your account." msgstr "La tua password è stata impostata, ora puoi scollegare la tua utenza." -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "Codice per iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "Collegamento al contenuto" @@ -1480,24 +1480,24 @@ msgstr "Inserisci un collegamento valido che inizia con http:// o https://" msgid "Please enter valid HTML content with an iframe tag" msgstr "Inserisci un contenuto HTML valido con un tag iframe" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "Provider" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "I partecipanti possono vedere i risultati sul loro dispositivo" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format msgid "Attendees can view the web content on their device" msgstr "I partecipanti possono visualizzare il contenuto web sul proprio dispositivo" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "Opzioni" @@ -1565,12 +1565,12 @@ msgstr "Fine" msgid "More options" msgstr "Altre opzioni" -#: lib/claper_web/live/event_live/manage.ex:789 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "No" -#: lib/claper_web/live/event_live/manage.ex:789 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "Sì" @@ -1620,32 +1620,32 @@ msgstr "Puoi reimpostare la tua password visitando l'URL sottostante" msgid "back to the home page" msgstr "torna alla pagina iniziale" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format msgid "Add Question" msgstr "Aggiungi Domanda" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "Aggiungi un quiz per testare le conoscenze." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "Aggiungi risposta" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format msgid "Allow anonymous messages" msgstr "Consenti messaggi anonimi" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "Risposta %{index}" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "Partecipanti" @@ -1661,32 +1661,32 @@ msgstr "Punteggio medio" msgid "Current quiz" msgstr "Quiz attuale" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format msgid "Deny anonymous messages" msgstr "Rifiuta messaggi anonimi" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format msgid "Disable messages" msgstr "Disabilita messaggi" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format msgid "Disable reactions" msgstr "Disabilita reazioni" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format msgid "Edit quiz" msgstr "Modifica quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "Nascondi istruzioni per partecipare" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format msgid "Hide messages" msgstr "Nascondi messaggi" @@ -1709,12 +1709,12 @@ msgstr "Come funziona ?" msgid "Interaction" msgstr "Interazione" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "Nuovo quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "Presentazione" @@ -1724,13 +1724,13 @@ msgstr "Presentazione" msgid "Previous" msgstr "Precedente" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:925 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "Quiz" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "Rimuovi domanda" @@ -1745,17 +1745,17 @@ msgstr "Passa in rassegna le domande" msgid "See current quiz" msgstr "Vedi quiz attuale" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "Seleziona presentazione" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format msgid "Show all messages" msgstr "Mostra tutti i messaggi" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format msgid "Show instructions to join" msgstr "Mostra istruzioni per partecipare" @@ -1771,7 +1771,7 @@ msgstr "Mostra risultati" msgid "Show results on presentation" msgstr "Mostra risultati sulla presentazione" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "Questo eliminerà tutte le risposte associate e il quiz stesso, sei sicuro?" @@ -1781,7 +1781,7 @@ msgstr "Questo eliminerà tutte le risposte associate e il quiz stesso, sei sicu msgid "Waiting for results..." msgstr "In attesa dei risultati..." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "La tua domanda" @@ -1799,7 +1799,7 @@ msgstr "Il tuo punteggio" msgid "Export" msgstr "Esporta" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "Esporta in QTI (XML)" @@ -1859,17 +1859,21 @@ msgstr "Partecipanti unici" msgid "Web Content" msgstr "Contenuto Web" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "Attivo" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "Carica altro" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "Condiviso con te" @@ -1879,17 +1883,17 @@ msgstr "Condiviso con te" msgid "You must login to continue" msgstr "Devi accedere per continuare" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "deve avere almeno una risposta corretta" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "Clicca qui per aprire la finestra di presentazione. Premi F nella finestra di presentazione per abilitare la modalità a schermo intero." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format msgid "Allow anonymous submissions" msgstr "Consenti invii anonimi" @@ -1908,3 +1912,771 @@ msgstr "Accedi" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "Risposte totali" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "Un codice unico per far partecipare i partecipanti a questo evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "Un nome unico per questo evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "Un nome unico per identificare questo provider OIDC" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "L'account è confermato e attivo" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Azioni" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Eventi attivi" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "Sei sicuro di voler eliminare questo evento?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "Sei sicuro di voler eliminare questo provider?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "Sei sicuro di voler eliminare questo utente?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "Utente assegnato" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Picco di pubblico" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "Codice di autorizzazione" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "Annulla" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Scegli file" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "ID Cliente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "Segreto Cliente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "Completato" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirmed" +msgstr "Confermato" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "Confermato il" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Crea evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "Crea provider" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Crea utente" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Creato" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Creato il" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Attualmente in corso" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Elimina evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "Elimina provider" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Elimina utente" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "Modifica provider OIDC" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "Modifica evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "Modifica provider" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Modifica utente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "Abilita questo provider OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "Inserisci ID cliente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "Inserisci segreto cliente" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "Inserisci codice evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "Inserisci nome evento" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Inserisci password" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "Inserisci nome provider" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "Inserisci email utente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "Creazione eventi" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "Evento creato con successo" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "Evento eliminato con successo" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "Dettagli evento" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "Evento aggiornato con successo" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Eventi" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "Eventi esportati con successo" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "Scade il" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "File selezionato" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Form Post" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "Frammento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "Come dovrebbe essere restituita la risposta di autorizzazione (predefinito: 'query')" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "Ibrido" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "Implicito" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Inattivo" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "Password iniziale per l'utente" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "Emittente" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "URL emittente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "Ultimi 30 giorni" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "Ultimo aggiornamento" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "Nuovo evento" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "Nessun evento trovato" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "Nessun file scelto" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "Nessun proprietario" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "Nessun ruolo" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "Nessun utente trovato" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "Non scaduto" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "Non iniziato" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "Tipo di risposta OAuth 2.0 (predefinito: 'code')" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "Provider OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "Dettagli provider OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "Provider OIDC" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "Ambiti OIDC da richiedere (predefinito: 'openid email profile')" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "Proprietario" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "Provider creato con successo" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "Provider aggiornato con successo" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "Query" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "Eventi recenti" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "URI di reindirizzamento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "Modalità di risposta" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "Tipo di risposta" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "Ruolo" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "Salvataggio in corso..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "Programmato" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "Ambito" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "Cerca eventi..." + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "Cerca un utente..." + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "Cerca provider..." + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "Cerca utenti..." + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Seleziona un'opzione" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "Seleziona..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "Data di inizio" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "Iniziato il" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "Stato" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "L'URL dell'emittente OIDC (deve iniziare con http:// o https://)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "L'URL di callback per la tua applicazione (deve iniziare con http:// o https://)" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "L'utente proprietario di questo evento (obbligatorio)" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "Eventi totali" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "Utenti totali" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "Non confermato" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "Aggiorna evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "Aggiorna provider" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "Aggiorna utente" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "Account utente" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "Crescita utenti" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "Utente creato con successo" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "Utente eliminato con successo" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "Dettagli utente" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "Utente aggiornato con successo" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "Livello di accesso dell'utente" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "Indirizzo email dell'utente (deve essere unico)" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "Utenti" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "Utenti esportati con successo" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "Visualizza evento" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Visualizza provider" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "Visualizza utente" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "Quando scade questo evento (opzionale)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "Se questo provider è attualmente attivo e disponibile per l'autenticazione" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "partecipanti" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "https://example.com" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "https://yourapp.com/auth/callback" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "openid email profile" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "vs mese scorso" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to events" +msgstr "Torna agli eventi" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to providers" +msgstr "Torna ai provider" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to users" +msgstr "Torna agli utenti" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "New provider" +msgstr "Nuovo provider" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format, fuzzy +msgid "New user" +msgstr "Nuovo utente" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format, fuzzy +msgid "No providers found" +msgstr "Nessun provider trovato" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider deleted successfully" +msgstr "Provider eliminato con successo" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Dettagli provider" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "Admin" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "Torna all'app" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Confirm email change" +msgstr "Conferma la modifica dell'email" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format +msgid "If you didn't request an email change, please ignore this." +msgstr "Se non hai richiesto una modifica dell'indirizzo email, ignora questo messaggio." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can confirm your email change by visiting the URL below" +msgstr "Puoi confermare la modifica dell'indirizzo email visitando l'URL sottostante" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Nascondi numero dei partecipanti" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Mostra numero dei partecipanti" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Obbligatorio" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(facoltativo)" diff --git a/priv/gettext/lv/LC_MESSAGES/default.po b/priv/gettext/lv/LC_MESSAGES/default.po new file mode 100644 index 0000000..5c9f9b3 --- /dev/null +++ b/priv/gettext/lv/LC_MESSAGES/default.po @@ -0,0 +1,2685 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: claper\n" +"Language: lv\n" +"Plural-Forms: nplurals=3; plural=(n%10==0 || n%100>=11 && n%100<=19) ? 0 : ((n%10==1 && n%100 != 11) ? 1 : 2);\n" + +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 +#: lib/claper_web/live/user_settings_live/show.ex:77 +#, elixir-autogen, elixir-format +msgid "Settings" +msgstr "Iestatījumi" + +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 +#: lib/claper_web/live/user_settings_live/show.html.heex:34 +#: lib/claper_web/templates/user_registration/new.html.heex:29 +#: lib/claper_web/templates/user_reset_password/new.html.heex:28 +#: lib/claper_web/templates/user_session/new.html.heex:42 +#, elixir-autogen, elixir-format +msgid "Email" +msgstr "E-pasts" + +#: lib/claper_web/templates/user_registration/new.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Join the Claper experience" +msgstr "Pievienojieties Claper pieredzei" + +#: lib/claper_web/templates/user_registration/new.html.heex:19 +#: lib/claper_web/templates/user_reset_password/edit.html.heex:25 +#: lib/claper_web/templates/user_reset_password/new.html.heex:19 +#, elixir-autogen, elixir-format +msgid "Oops, check that all fields are filled in correctly." +msgstr "Ups, pārbaudiet, vai visi lauki ir aizpildīti pareizi." + +#: lib/claper_web/live/user_settings_live/show.html.heex:155 +#: lib/claper_web/live/user_settings_live/show.html.heex:170 +#, elixir-autogen, elixir-format +msgid "Change" +msgstr "Mainīt" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 +#, elixir-autogen, elixir-format +msgid "Code" +msgstr "Kods" + +#: lib/claper_web/live/user_settings_live/show.html.heex:146 +#: lib/claper_web/templates/user_session/new.html.heex:40 +#, elixir-autogen, elixir-format +msgid "Email address" +msgstr "E-pasta adrese" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 +#, elixir-autogen, elixir-format +msgid "Logout" +msgstr "Izrakstīties" + +#: lib/claper_web/live/user_settings_live/show.html.heex:136 +#, elixir-autogen, elixir-format +msgid "Personal informations" +msgstr "Personīgā informācija" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:13 +#, elixir-autogen, elixir-format +msgid "We already sent you an email to login, please retry in 5 minutes." +msgstr "Mēs jau nosūtījām jums e-pastu, lai pieteiktos. Lūdzu, mēģiniet vēlreiz pēc 5 minūtēm." + +#: lib/claper_web/templates/user_registration/confirm.html.heex:16 +#, elixir-autogen, elixir-format +msgid "We sent you an email at" +msgstr "Mēs nosūtījām jums e-pastu uz adresi" + +#: lib/claper_web/live/event_live/show.html.heex:437 +#, elixir-autogen, elixir-format +msgid "days" +msgstr "dienas" + +#: lib/claper_web/live/event_live/show.html.heex:443 +#, elixir-autogen, elixir-format +msgid "hours" +msgstr "stundas" + +#: lib/claper_web/live/event_live/show.html.heex:449 +#, elixir-autogen, elixir-format +msgid "minutes" +msgstr "minūtes" + +#: lib/claper_web/live/event_live/show.html.heex:165 +#, elixir-autogen, elixir-format +msgid "Be the first to react !" +msgstr "Esi pirmais, kas noreaģē!" + +#: lib/claper_web/live/event_live/event_card_component.ex:111 +#: lib/claper_web/live/event_live/join.ex:41 +#: lib/claper_web/live/event_live/join.html.heex:94 +#: lib/claper_web/live/event_live/manage.html.heex:492 +#: lib/claper_web/live/event_live/show.html.heex:286 +#, elixir-autogen, elixir-format +msgid "Join" +msgstr "Pievienoties" + +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 +#, elixir-autogen, elixir-format +msgid "Dashboard" +msgstr "Vadības panelis" + +#: lib/claper_web/live/event_live/post_component.ex:33 +#: lib/claper_web/live/event_live/post_component.ex:112 +#, elixir-autogen, elixir-format +msgid "Host" +msgstr "Organizators" + +#: lib/claper_web/live/event_live/show.html.heex:455 +#, elixir-autogen, elixir-format +msgid "seconds" +msgstr "sekundes" + +#: lib/claper_web/live/event_live/event_card_component.ex:60 +#: lib/claper_web/live/event_live/index.html.heex:187 +#, elixir-autogen, elixir-format +msgid "Finished" +msgstr "Pabeigts" + +#: lib/claper_web/live/event_live/event_card_component.ex:90 +#, elixir-autogen, elixir-format +msgid "Finished on" +msgstr "Pabeigts" + +#: lib/claper_web/live/event_live/event_card_component.ex:55 +#, elixir-autogen, elixir-format +msgid "Incoming" +msgstr "Drīzumā" + +#: lib/claper_web/live/event_live/show.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Leave" +msgstr "Pamest" + +#: lib/claper_web/live/event_live/presenter.html.heex:26 +#: lib/claper_web/live/event_live/show.html.heex:464 +#, elixir-autogen, elixir-format +msgid "Scan to interact in real-time" +msgstr "Noskenējiet, lai mijiedarbotos reāllaikā" + +#: lib/claper_web/live/event_live/event_card_component.ex:86 +#, elixir-autogen, elixir-format +msgid "Starting on" +msgstr "Sākot no" + +#: lib/claper_web/live/event_live/event_form_component.ex:268 +#, elixir-autogen, elixir-format +msgid "Updated successfully" +msgstr "Veiksmīgi atjaunināts" + +#: lib/claper_web/templates/user_session/new.html.heex:22 +#, elixir-autogen, elixir-format +msgid "It's time to empower your presentations." +msgstr "Ir pienācis laiks uzlabot jūsu prezentācijas." + +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Return to home" +msgstr "Atgriezties uz sākumlapu" + +#: lib/claper_web/live/event_live/event_form_component.ex:212 +#: lib/claper_web/live/event_live/event_form_component.ex:248 +#, elixir-autogen, elixir-format +msgid "Created successfully" +msgstr "Veiksmīgi izveidots" + +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 +#: lib/claper_web/live/event_live/event_card_component.ex:250 +#: lib/claper_web/live/event_live/event_card_component.ex:330 +#: lib/claper_web/live/event_live/form_component.ex:97 +#: lib/claper_web/live/event_live/index.ex:204 +#, elixir-autogen, elixir-format +msgid "Edit" +msgstr "Rediģēt" + +#: lib/claper_web/live/embed_live/form_component.html.heex:63 +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#: lib/claper_web/live/event_live/event_form_component.html.heex:62 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 +#, elixir-autogen, elixir-format +msgid "Create" +msgstr "Izveidot" + +#: lib/claper_web/live/embed_live/form_component.html.heex:68 +#: lib/claper_web/live/event_live/event_card_component.ex:444 +#: lib/claper_web/live/event_live/event_form_component.html.heex:67 +#: lib/claper_web/live/event_live/manage.html.heex:1397 +#: lib/claper_web/live/event_live/manageable_post_component.ex:92 +#: lib/claper_web/live/event_live/post_component.ex:70 +#: lib/claper_web/live/event_live/post_component.ex:142 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#, elixir-autogen, elixir-format +msgid "Delete" +msgstr "Dzēst" + +#: lib/claper_web/live/embed_live/form_component.html.heex:64 +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#: lib/claper_web/live/event_live/event_form_component.html.heex:61 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 +#: lib/claper_web/live/user_settings_live/show.html.heex:38 +#: lib/claper_web/live/user_settings_live/show.html.heex:80 +#: lib/claper_web/live/user_settings_live/show.html.heex:123 +#, elixir-autogen, elixir-format +msgid "Save" +msgstr "Saglabāt" + +#: lib/claper_web/live/user_settings_live/show.ex:137 +#, elixir-autogen, elixir-format +msgid "A link to confirm your email change has been sent to the new address." +msgstr "Uz jauno adresi ir nosūtīta saite, lai apstiprinātu e-pasta maiņu." + +#: lib/claper_web/live/user_settings_live/show.ex:53 +#, elixir-autogen, elixir-format +msgid "Change the email address you want associated with your account." +msgstr "Mainiet e-pasta adresi, kuru vēlaties saistīt ar savu kontu." + +#: lib/claper_web/live/user_settings_live/show.ex:50 +#, elixir-autogen, elixir-format +msgid "Update your email" +msgstr "Atjauniniet savu e-pasta adresi" + +#: lib/claper_web/notifiers/user_notifier.ex:12 +#: lib/claper_web/templates/user_notifier/magic.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Connect to Claper" +msgstr "Pieslēdzieties Claper" + +#: lib/claper_web/templates/user_notifier/magic.html.heex:29 +#, elixir-autogen, elixir-format +msgid "ACCESS TO MY ACCOUNT" +msgstr "PIEKĻUVE MANAM KONTAM" + +#: lib/claper_web/notifiers/user_notifier.ex:34 +#, elixir-autogen, elixir-format +msgid "Update email instructions" +msgstr "E-pasta adreses maiņas instrukcijas" + +#: lib/claper_web/templates/user_notifier/change.html.heex:29 +#, elixir-autogen, elixir-format +msgid "CONFIRM EMAIL" +msgstr "APSTIPRINĀT E-PASTU" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:32 +#: lib/claper_web/templates/user_notifier/magic.html.heex:32 +#: lib/claper_web/templates/user_notifier/reset.html.heex:32 +#, elixir-autogen, elixir-format +msgid "If you didn't create an account with us, please ignore this." +msgstr "Ja neesat izveidojuši mūsu kontu, lūdzu, ignorējiet šo informāciju." + +#: lib/claper_web/templates/user_notifier/magic.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can log into your account by clicking here." +msgstr "Varat pieteikties savā kontā, noklikšķinot šeit." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:71 +#: lib/claper_web/live/event_live/post_component.ex:75 +#: lib/claper_web/live/event_live/post_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Are you sure?" +msgstr "Vai esat pārliecināti?" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:192 +#, elixir-autogen, elixir-format +msgid "Presentation attached" +msgstr "Prezentācija ir pievienota" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:152 +#, elixir-autogen, elixir-format +msgid "Presentation uploaded" +msgstr "Prezentācija ir augšupielādēta" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:163 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 +#, elixir-autogen, elixir-format +msgid "Remove" +msgstr "Noņemt" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:173 +#, elixir-autogen, elixir-format +msgid "Select your presentation" +msgstr "Izvēlieties savu prezentāciju" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:115 +#, elixir-autogen, elixir-format +msgid "Upload a file" +msgstr "Failu augšupielāde" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:119 +#, elixir-autogen, elixir-format +msgid "or drag and drop" +msgstr "vai velciet un nometiet" + +#: lib/claper_web/live/event_live/event_form_component.ex:322 +#, elixir-autogen, elixir-format +msgid "You have selected an incorrect file type" +msgstr "Jūs esat izvēlējies nepareizu faila tipu" + +#: lib/claper_web/live/event_live/event_form_component.ex:321 +#, elixir-autogen, elixir-format +msgid "Your file is too large" +msgstr "Jūsu fails ir pārāk liels" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:202 +#, elixir-autogen, elixir-format +msgid "Change file" +msgstr "Mainīt failu" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 +#, elixir-autogen, elixir-format +msgid "Presentation replaced" +msgstr "Prezentācija aizstāta" + +#: lib/claper_web/live/event_live/manage.html.heex:305 +#, elixir-autogen, elixir-format +msgid "Edit poll" +msgstr "Rediģēt aptauju" + +#: lib/claper_web/live/event_live/manage.html.heex:304 +#, elixir-autogen, elixir-format +msgid "New poll" +msgstr "Jauna aptauja" + +#: lib/claper_web/live/poll_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your poll" +msgstr "Jūsu aptaujas nosaukums" + +#: lib/claper_web/live/event_live/event_form_component.ex:323 +#, elixir-autogen, elixir-format +msgid "Upload failed" +msgstr "Neizdevās augšupielādēt" + +#: lib/claper_web/live/event_live/manage.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Add poll to know opinion of your public." +msgstr "Pievienojiet aptauju, lai uzzinātu auditorijas viedokli." + +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 +#, elixir-autogen, elixir-format +msgid "Poll" +msgstr "Aptauja" + +#: lib/claper_web/live/poll_live/form_component.html.heex:26 +#, elixir-format, ex-autogen, elixir-autogen +msgid "Choice %{count}" +msgid_plural "Choice %{count}" +msgstr[0] "Izvēle %{count}" +msgstr[1] "Izvēle %{count}" +msgstr[2] "Izvēle %{count}" + +#: lib/claper_web/live/event_live/poll_component.ex:47 +#, elixir-autogen, elixir-format +msgid "Current poll" +msgstr "Pašreizējā aptauja" + +#: lib/claper_web/live/event_live/poll_component.ex:28 +#, elixir-autogen, elixir-format +msgid "See current poll" +msgstr "Skatīt pašreizējo aptauju" + +#: lib/claper_web/live/event_live/poll_component.ex:127 +#: lib/claper_web/live/event_live/poll_component.ex:135 +#, elixir-autogen, elixir-format +msgid "Vote" +msgstr "Balsot" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 +#, elixir-autogen, elixir-format +msgid "User email address" +msgstr "Lietotāja e-pasta adrese" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 +#, elixir-autogen, elixir-format +msgid "Changing your file will remove all interaction elements like polls associated." +msgstr "Mainot failu, tiks noņemti visi mijiedarbības elementi, piemēram, aptaujas." + +#: lib/claper_web/live/event_live/manage.html.heex:1213 +#, elixir-autogen, elixir-format +msgid "Messages from attendees will appear here." +msgstr "Dalībnieku ziņojumi parādīsies šeit." + +#: lib/claper_web/live/event_live/event_card_component.ex:344 +#, elixir-autogen, elixir-format +msgid "Processing your file..." +msgstr "Jūsu faila apstrāde..." + +#: lib/claper_web/live/poll_live/form_component.html.heex:114 +#, elixir-autogen, elixir-format +msgid "This will delete all responses associated and the poll itself, are you sure?" +msgstr "Tas izdzēsīs visas saistītās atbildes un pašu aptauju, vai esat pārliecināti?" + +#: lib/claper_web/live/event_live/show.html.heex:345 +#, elixir-autogen, elixir-format +msgid "Ask, comment..." +msgstr "Jautājiet, komentējiet..." + +#: lib/claper_web/live/event_live/manage.html.heex:1159 +#: lib/claper_web/live/stat_live/index.html.heex:102 +#: lib/claper_web/live/stat_live/index.html.heex:180 +#, elixir-autogen, elixir-format +msgid "Messages" +msgstr "Ziņojumi" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 +#, elixir-autogen, elixir-format +msgid "Add facilitator" +msgstr "Pievienot moderatoru" + +#: lib/claper_web/templates/error/404.html.heex:31 +#, elixir-autogen, elixir-format +msgid "Oops, page doesn't exist." +msgstr "Ups, lapa neeksistē." + +#: lib/claper_web/templates/error/500.html.heex:31 +#, elixir-autogen, elixir-format +msgid "The site is under maintenance, we'll be back very soon!" +msgstr "Vietne tiek uzturēta, mēs atgriezīsimies ļoti drīz!" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#, elixir-autogen, elixir-format +msgid "Facilitators can present and manage interactions" +msgstr "Moderatori var prezentēt un vadīt mijiedarbību" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:45 +#: lib/claper_web/templates/user_notifier/change.html.heex:42 +#: lib/claper_web/templates/user_notifier/confirm.html.heex:42 +#: lib/claper_web/templates/user_notifier/magic.html.heex:42 +#: lib/claper_web/templates/user_notifier/reset.html.heex:42 +#, elixir-autogen, elixir-format +msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" +msgstr "Ja jums rodas problēmas ar iepriekš norādīto pogu, nokopējiet un ielīmējiet tīmekļa pārlūkprogrammā tālāk norādīto URL adresi" + +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 +#, elixir-autogen, elixir-format +msgid "Add interaction" +msgstr "Pievienot mijiedarbību" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:54 +#: lib/claper_web/live/event_live/manageable_post_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" +msgstr "Bloķējot šo lietotāju, tiks dzēsti visi lietotāja ziņojumi un viņš vairs nevarēs pievienoties, apstipriniet?" + +#: lib/claper_web/live/event_live/show.ex:51 +#: lib/claper_web/live/event_live/show.ex:206 +#: lib/claper_web/live/event_live/show.ex:221 +#, elixir-autogen, elixir-format +msgid "You have been banned from this event" +msgstr "Jums ir aizliegts piedalīties šajā pasākumā" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:48 +#: lib/claper_web/live/event_live/manageable_post_component.ex:77 +#, elixir-autogen, elixir-format +msgid "Ban" +msgstr "Bloķēt" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:18 +#, elixir-autogen, elixir-format +msgid ", click on the provided link to connect (check your spam !)" +msgstr ", noklikšķiniet uz norādītās saites, lai pieslēgtos (pārbaudiet savu surogātpastu!)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:29 +#, elixir-autogen, elixir-format +msgid "Export your current presentation to PDF from your favorite slide presentation software (PowerPoint, etc)" +msgstr "Eksportējiet savu pašreizējo prezentāciju uz PDF no savas iecienītākās prezentāciju programmatūras (PowerPoint utt.)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:50 +#, elixir-autogen, elixir-format +msgid "Wait few minutes for your file to be processed" +msgstr "Gaidiet dažas minūtes, lai jūsu fails tiktu apstrādāts" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:43 +#, elixir-autogen, elixir-format +msgid "Choose a name for your event, a code for your attendees to join and dates when your attendees could start interacting" +msgstr "Izvēlieties nosaukumu savam pasākumam, kodu, ar kuru dalībnieki var pievienoties, un datumus, kad dalībnieki var sākt mijiedarboties" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:64 +#, elixir-autogen, elixir-format +msgid "Click Start to open your presentation and move the window on the big screen" +msgstr "Noklikšķiniet uz Start, lai atvērtu prezentāciju un pārvietotu logu uz lielā ekrāna" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:57 +#, elixir-autogen, elixir-format +msgid "Click on Present/Customize to add interaction on your slides" +msgstr "Noklikšķiniet uz Prezentēt/Pielāgot, lai pievienotu mijiedarbību diapozitīviem" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:22 +#, elixir-autogen, elixir-format +msgid "Congrats! You've taken the first step to improving your presentations. Here are the next steps to create step up your presentations with Claper:" +msgstr "Apsveicam! Jūs esat spēruši pirmo soli, lai uzlabotu savas prezentācijas. Šeit ir nākamie soļi, lai ar Claper uzlabotu savas prezentācijas:" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:69 +#, elixir-autogen, elixir-format +msgid "Enjoy ! ✨" +msgstr "Izbaudiet! ✨" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:20 +#, elixir-autogen, elixir-format +msgid "We sent you an email, click on the provided link to connect (check your spam !)" +msgstr "Mēs nosūtījām jums e-pastu, noklikšķiniet uz norādītās saites, lai pieslēgtos (pārbaudiet savu surogātpastu!)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Welcome !" +msgstr "Laipni lūdzam!" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Click on the create button on your dashboard" +msgstr "Noklikšķiniet uz Izveidot pogas vadības panelī" + +#: lib/claper_web/notifiers/user_notifier.ex:23 +#, elixir-autogen, elixir-format +msgid "Next steps to boost your presentations" +msgstr "Nākamie soļi, lai uzlabotu prezentāciju kvalitāti" + +#: lib/claper_web/live/stat_live/index.html.heex:109 +#, elixir-autogen, elixir-format +msgid "from %{count} people" +msgid_plural "from %{count} peoples" +msgstr[0] "no %{count} cilvēku" +msgstr[1] "no %{count} cilvēka" +msgstr[2] "no %{count} cilvēku" + +#: lib/claper_web/live/stat_live/index.html.heex:15 +#, elixir-autogen, elixir-format +msgid "Event" +msgstr "Pasākums" + +#: lib/claper_web/live/stat_live/index.html.heex:386 +#, elixir-autogen, elixir-format +msgid "No messages has been sent" +msgstr "Nav nosūtīts neviens ziņojums" + +#: lib/claper_web/live/event_live/event_card_component.ex:426 +#, elixir-autogen, elixir-format +msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" +msgstr "Tādējādi tiks dzēsti visi ar jūsu notikumu saistītie dati, un to nevar atcelt. Apstiprināt?" + +#: lib/claper_web/live/stat_live/index.html.heex:45 +#: lib/claper_web/live/stat_live/index.html.heex:77 +#, elixir-autogen, elixir-format +msgid "attendee" +msgid_plural "attendees" +msgstr[0] "dalībnieku" +msgstr[1] "dalībnieks" +msgstr[2] "dalībnieki" + +#: lib/claper_web/live/stat_live/index.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Audience peak" +msgstr "Auditorijas maksimums" + +#: lib/claper_web/live/stat_live/index.html.heex:139 +#, elixir-autogen, elixir-format +msgid "Engagement rate" +msgstr "Iesaistīšanās līmenis" + +#: lib/claper_web/live/event_live/event_card_component.ex:282 +#, elixir-autogen, elixir-format +msgid "Error when processing the file" +msgstr "Kļūda apstrādājot failu" + +#: lib/claper_web/live/event_live/join.html.heex:24 +#: lib/claper_web/live/event_live/join.html.heex:47 +#, elixir-autogen, elixir-format +msgid "About" +msgstr "Par" + +#: lib/claper_web/live/event_live/join.html.heex:38 +#: lib/claper_web/live/event_live/join.html.heex:61 +#: lib/claper_web/templates/user_session/new.html.heex:62 +#, elixir-autogen, elixir-format +msgid "Login" +msgstr "Pieteikšanās" + +#: lib/claper_web/templates/user_session/new.html.heex:25 +#, elixir-autogen, elixir-format +msgid "Connect to your account" +msgstr "Pieslēdzieties savam kontam" + +#: lib/claper_web/live/event_live/show.html.heex:473 +#, elixir-autogen, elixir-format +msgid "Or use the code:" +msgstr "Vai arī izmantojiet kodu:" + +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Create account" +msgstr "Izveidot kontu" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 +#: lib/claper_web/live/user_settings_live/show.html.heex:161 +#: lib/claper_web/templates/user_registration/new.html.heex:37 +#: lib/claper_web/templates/user_reset_password/edit.html.heex:34 +#: lib/claper_web/templates/user_session/new.html.heex:50 +#: lib/claper_web/templates/user_session/new.html.heex:52 +#, elixir-autogen, elixir-format +msgid "Password" +msgstr "Parole" + +#: lib/claper_web/live/user_settings_live/show.ex:62 +#, elixir-autogen, elixir-format +msgid "Change the password used to access your account." +msgstr "Mainiet paroli, kas tiek izmantota, lai piekļūtu jūsu kontam." + +#: lib/claper_web/live/user_settings_live/show.html.heex:70 +#, elixir-autogen, elixir-format +msgid "Current password" +msgstr "Pašreizējā parole" + +#: lib/claper_web/live/user_settings_live/show.html.heex:76 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#, elixir-autogen, elixir-format +msgid "New password" +msgstr "Jauna parole" + +#: lib/claper_web/live/user_settings_live/show.ex:59 +#, elixir-autogen, elixir-format +msgid "Update your password" +msgstr "Atjaunināt paroli" + +#: lib/claper_web/live/user_settings_live/show.ex:159 +#, elixir-autogen, elixir-format +msgid "Your password has been updated." +msgstr "Jūsu parole ir atjaunināta." + +#: lib/claper_web/live/form_live/form_component.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Field %{count}" +msgid_plural "Field %{count}" +msgstr[0] "Lauks %{count}" +msgstr[1] "Lauks %{count}" +msgstr[2] "Lauks %{count}" + +#: lib/claper_web/live/event_live/manage.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Add form to collect data from your public." +msgstr "Pievienojiet veidlapu, lai savāktu datus no auditorijas." + +#: lib/claper_web/live/event_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Current form" +msgstr "Pašreizējā forma" + +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format +msgid "Edit form" +msgstr "Rediģēt veidlapu" + +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 +#, elixir-autogen, elixir-format +msgid "Form" +msgstr "Veidlapa" + +#: lib/claper_web/live/event_live/manage.html.heex:1183 +#, elixir-autogen, elixir-format +msgid "Form submissions" +msgstr "Veidlapu iesniegumi" + +#: lib/claper_web/live/event_live/manage.html.heex:1382 +#, elixir-autogen, elixir-format +msgid "Form submissions from attendees will appear here." +msgstr "Dalībnieku iesniegtās veidlapas parādīsies šeit." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 +#, elixir-autogen, elixir-format +msgid "Name" +msgstr "Nosaukums" + +#: lib/claper_web/live/event_live/manage.html.heex:325 +#, elixir-autogen, elixir-format +msgid "New form" +msgstr "Jauna veidlapa" + +#: lib/claper_web/live/stat_live/index.html.heex:305 +#, elixir-autogen, elixir-format +msgid "No form submission has been sent" +msgstr "Nav nosūtīts neviens veidlapas iesniegums" + +#: lib/claper_web/live/event_live/form_component.ex:32 +#, elixir-autogen, elixir-format +msgid "See current form" +msgstr "Skatīt pašreizējo veidlapu" + +#: lib/claper_web/live/event_live/form_component.ex:97 +#: lib/claper_web/live/event_live/quiz_component.ex:183 +#, elixir-autogen, elixir-format +msgid "Submit" +msgstr "Iesniegt" + +#: lib/claper_web/live/form_live/form_component.html.heex:32 +#, elixir-autogen, elixir-format +msgid "Text" +msgstr "Teksts" + +#: lib/claper_web/live/event_live/manage.html.heex:1402 +#, elixir-autogen, elixir-format +msgid "This cannot be undone, confirm ?" +msgstr "Šo darbību nevar atsaukt, apstiprināt?" + +#: lib/claper_web/live/form_live/form_component.html.heex:105 +#, elixir-autogen, elixir-format +msgid "This will delete all responses associated and the form itself, are you sure?" +msgstr "Tas izdzēsīs visas saistītās atbildes un pašu veidlapu, vai esat pārliecināti?" + +#: lib/claper_web/live/form_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your form" +msgstr "Jūsu veidlapas nosaukums" + +#: lib/claper_web/live/form_live/form_component.html.heex:34 +#, elixir-autogen, elixir-format +msgid "Type" +msgstr "Tips" + +#: lib/claper_web/live/event_live/poll_component.ex:52 +#, elixir-autogen, elixir-format +msgid "Select one option" +msgstr "Izvēlieties vienu iespēju" + +#: lib/claper_web/live/event_live/poll_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Select one or multiple options" +msgstr "Izvēlieties vienu vai vairākas opcijas" + +#: lib/claper_web/live/poll_live/form_component.html.heex:92 +#, elixir-autogen, elixir-format +msgid "Multiple answers" +msgstr "Vairākas atbildes" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 +#, elixir-autogen, elixir-format +msgid "PDF, PPT, PPTX up to %{size} MB" +msgstr "PDF, PPT, PPTX līdz %{size} MB" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#, elixir-autogen, elixir-format +msgid "Enable messages" +msgstr "Iespējot ziņojumus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#, elixir-autogen, elixir-format +msgid "Show messages" +msgstr "Rādīt ziņojumus" + +#: lib/claper_web/live/event_live/show.html.heex:365 +#, elixir-autogen, elixir-format +msgid "Messages deactivated" +msgstr "Ziņojumi atspējoti" + +#: lib/claper_web/live/event_live/show.html.heex:208 +#: lib/claper_web/live/event_live/show.html.heex:229 +#: lib/claper_web/live/event_live/show.html.heex:329 +#, elixir-autogen, elixir-format +msgid "Anonymous" +msgstr "Anonīms" + +#: lib/claper_web/live/event_live/show.html.heex:255 +#: lib/claper_web/templates/lti/launch/error.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Close" +msgstr "Aizvērt" + +#: lib/claper_web/live/event_live/show.html.heex:236 +#: lib/claper_web/live/event_live/show.html.heex:281 +#, elixir-autogen, elixir-format +msgid "Enter your name" +msgstr "Ievadiet savu vārdu" + +#: lib/claper_web/live/event_live/presenter.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Or go to %{url} and use the code:" +msgstr "Vai arī dodieties uz %{url} un izmantojiet kodu:" + +#: lib/claper_web/live/event_live/show.html.heex:249 +#, elixir-autogen, elixir-format +msgid "Use your name" +msgstr "Izmantojiet savu vārdu" + +#: lib/claper_web/live/event_live/show.html.heex:229 +#, elixir-autogen, elixir-format +msgid "disabled" +msgstr "atspējots" + +#: lib/claper_web/controllers/user_registration_controller.ex:14 +#, elixir-autogen, elixir-format +msgid "Account creation is disabled" +msgstr "Konta izveide ir atspējota" + +#: lib/claper_web/live/event_live/manage.html.heex:261 +#, elixir-autogen, elixir-format +msgid "Add a Youtube video or any web content." +msgstr "Pievienojiet Youtube videoklipu vai jebkuru tīmekļa saturu." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:51 +#, elixir-autogen, elixir-format +msgid "Confirm new password" +msgstr "Jaunās paroles apstiprināšana" + +#: lib/claper_web/templates/user_session/new.html.heex:79 +#, elixir-autogen, elixir-format +msgid "Forgot your password?" +msgstr "Aizmirsāt paroli?" + +#: lib/claper_web/controllers/user_reset_password_controller.ex:26 +#, elixir-autogen, elixir-format +msgid "If your email is in our system, you'll receive instructions to reset your password shortly." +msgstr "Ja jūsu e-pasta adrese ir mūsu sistēmā, drīz saņemsiet norādījumus par paroles atiestatīšanu." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:42 +#, elixir-autogen, elixir-format +msgid "Password confirmation" +msgstr "Paroles apstiprināšana" + +#: lib/claper_web/controllers/user_reset_password_controller.ex:44 +#, elixir-autogen, elixir-format +msgid "Password updated successfully." +msgstr "Parole veiksmīgi atjaunināta." + +#: lib/claper_web/controllers/user_reset_password_controller.ex:59 +#, elixir-autogen, elixir-format +msgid "Reset password link is invalid or it has expired." +msgstr "Paroles atiestatīšanas saite ir nederīga vai tās derīguma termiņš ir beidzies." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:12 +#: lib/claper_web/templates/user_reset_password/new.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Reset your password" +msgstr "Paroles atiestatīšana" + +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Send link to reset password" +msgstr "Nosūtīt saiti, lai atiestatītu paroli" + +#: lib/claper_web/live/event_live/embed_component.ex:55 +#, elixir-autogen, elixir-format +msgid "Current web content" +msgstr "Pašreizējais tīmekļa saturs" + +#: lib/claper_web/live/event_live/manage.html.heex:347 +#, elixir-autogen, elixir-format +msgid "Edit web content" +msgstr "Tīmekļa satura rediģēšana" + +#: lib/claper_web/live/event_live/manage.html.heex:346 +#, elixir-autogen, elixir-format +msgid "New web content" +msgstr "Jauns tīmekļa saturs" + +#: lib/claper_web/live/event_live/embed_component.ex:32 +#, elixir-autogen, elixir-format +msgid "See current web content" +msgstr "Skatiet pašreizējo tīmekļa saturu" + +#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#, elixir-autogen, elixir-format +msgid "This will delete the web content, are you sure?" +msgstr "Tas izdzēsīs tīmekļa saturu, vai esat pārliecināti?" + +#: lib/claper_web/live/embed_live/form_component.html.heex:14 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title" +msgstr "Nosaukums" + +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 +#, elixir-autogen, elixir-format +msgid "Web content" +msgstr "Tīmekļa saturs" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:38 +#: lib/claper_web/live/event_live/manageable_post_component.ex:67 +#, elixir-autogen, elixir-format +msgid "Pin" +msgstr "Piespraust" + +#: lib/claper_web/live/event_live/post_component.ex:59 +#: lib/claper_web/live/event_live/post_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Pinned" +msgstr "Piesprausts" + +#: lib/claper_web/live/event_live/manage.html.heex:1175 +#, elixir-autogen, elixir-format +msgid "Pinned messages" +msgstr "Piespraustie ziņojumi" + +#: lib/claper_web/live/event_live/manage.html.heex:1336 +#, elixir-autogen, elixir-format +msgid "Pinned messages will appear here." +msgstr "Šeit tiks rādīti piespraustie ziņojumi." + +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 +#, elixir-autogen, elixir-format +msgid "Show only pinned messages" +msgstr "Rādīt tikai piespraustos ziņojumus" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:36 +#: lib/claper_web/live/event_live/manageable_post_component.ex:65 +#, elixir-autogen, elixir-format +msgid "Unpin" +msgstr "Atspraust" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:35 +#, elixir-autogen, elixir-format +msgid "Login or create account" +msgstr "Pieslēdzieties vai izveidojiet kontu" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:22 +#, elixir-autogen, elixir-format +msgid "Someone invited you to manage the event: %{name}" +msgstr "Kāds jūs uzaicināja vadīt pasākumu: %{name}" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:25 +#, elixir-autogen, elixir-format +msgid "To accept the invitation, please login or create an account with this email: %{email}" +msgstr "Lai pieņemtu ielūgumu, lūdzu, piesakieties vai izveidojiet kontu, izmantojot šo e-pasta adresi: %{email}" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:17 +#, elixir-autogen, elixir-format +msgid "You have been invited" +msgstr "Jūs esat uzaicināti" + +#: lib/claper_web/notifiers/leader_notifier.ex:12 +#, elixir-autogen, elixir-format +msgid "You have been invited to manage an event" +msgstr "Jūs esat uzaicināti vadīt pasākumu" + +#: lib/claper_web/live/event_live/form_component.ex:114 +#, elixir-autogen, elixir-format +msgid "Saved" +msgstr "Saglabāts" + +#: lib/claper_web/live/user_settings_live/show.html.heex:301 +#, elixir-autogen, elixir-format +msgid "All your events and files will be permanently deleted, are you sure?" +msgstr "Visi jūsu notikumi un faili tiks neatgriezeniski dzēsti, vai esat pārliecināti?" + +#: lib/claper_web/live/event_live/event_card_component.ex:183 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "Vai esat pārliecināti, ka vēlaties pārtraukt šo notikumu? Šo darbību nevar atcelt." + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "Dalībnieku telpa" + +#: lib/claper_web/live/user_settings_live/show.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Be careful, these actions are irreversible" +msgstr "Esiet uzmanīgi, šīs darbības ir neatgriezeniskas" + +#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "Bīstamā zona" + +#: lib/claper_web/live/user_settings_live/show.html.heex:297 +#, elixir-autogen, elixir-format +msgid "Delete account" +msgstr "Dzēst kontu" + +#: lib/claper_web/live/event_live/manage.html.heex:565 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "Atvērt prezentāciju" + +#: lib/claper_web/live/event_live/event_card_component.ex:370 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "Apskatīt ziņojumu" + +#: lib/claper_web/controllers/user_registration_controller.ex:50 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "Jūsu konts ir dzēsts." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 +#, elixir-autogen, elixir-format +msgid "Access code" +msgstr "Piekļuves kods" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." +msgstr "Animācijas PPT/PPTX failos netiek atbalstītas, tāpēc mēs iesakām eksportēt prezentāciju PDF formātā, lai nodrošinātu tās pareizu rādīšanu." + +#: lib/claper_web/live/event_live/manage.html.heex:1147 +#, elixir-autogen, elixir-format +msgid "Attendees interactions" +msgstr "Dalībnieku mijiedarbība" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/quiz_component.ex:151 +#: lib/claper_web/live/event_live/quiz_component.ex:198 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "Atpakaļ" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 +#, elixir-autogen, elixir-format +msgid "Facilitators" +msgstr "Moderatori" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:7 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/templates/lti/registration/success.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Finish" +msgstr "Beigt" + +#: lib/claper_web/live/event_live/manage.html.heex:1149 +#, elixir-autogen, elixir-format +msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." +msgstr "Šeit atradīsiet visas dalībnieku mijiedarbības. Varat pārvaldīt ziņojumus, piespraustos ziņojumus un iesniegtās veidlapas." + +#: lib/claper_web/live/event_live/manage.html.heex:1149 +#, elixir-autogen, elixir-format +msgid "Identify users by their unique avatars." +msgstr "Identificēt lietotājus pēc viņu unikālajiem avatariem." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:176 +#: lib/claper_web/live/event_live/quiz_component.ex:161 +#: lib/claper_web/live/event_live/quiz_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Next" +msgstr "Nākamais" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:84 +#, elixir-autogen, elixir-format +msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." +msgstr "Izvēlieties prezentācijas failu. Pieņemamie formāti ir PDF, PPT vai PPTX. Pārliecinieties, ka faila lielums nepārsniedz maksimālo ierobežojumu." + +#: lib/claper_web/live/event_live/manage.html.heex:545 +#, elixir-autogen, elixir-format +msgid "Time to launch your presentation!" +msgstr "Laiks uzsākt prezentāciju!" + +#: lib/claper_web/live/event_live/manage.html.heex:1451 +#, elixir-autogen, elixir-format +msgid "Use the associated keyboard shortcuts for quick toggling of these settings." +msgstr "Lai ātri pārslēgtu šos iestatījumus, izmantojiet saistītās tastatūras īsceļus." + +#: lib/claper_web/live/event_live/manage.html.heex:1451 +#, elixir-autogen, elixir-format +msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." +msgstr "Varat kontrolēt katru iestatījumu gan prezentācijai (rādīšanai uz lielā ekrāna), gan dalībnieka istabai." + +#: lib/claper_web/live/event_live/index.html.heex:149 +#, elixir-autogen, elixir-format +msgid "Your first steps with Claper" +msgstr "Jūsu pirmie soļi ar Claper" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 +#, elixir-autogen, elixir-format +msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." +msgstr "Apmeklētāji, kas mēģinās iekļūt pasākumā pirms šī datuma, tiks novirzīti uz uzgaidāmo telpu." + +#: lib/claper_web/live/event_live/index.html.heex:167 +#, elixir-autogen, elixir-format +msgid "Create event" +msgstr "Izveidot notikumu" + +#: lib/claper_web/live/event_live/index.html.heex:225 +#, elixir-autogen, elixir-format +msgid "Create your first event" +msgstr "Izveidojiet savu pirmo notikumu" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "Pasākuma sākuma datums" + +#: lib/claper_web/live/event_live/index.html.heex:119 +#, elixir-autogen, elixir-format +msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." +msgstr "Ja jums nav laika un vēlaties mijiedarbību bez prezentācijas faila, varat šeit izveidot jaunu notikumu." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 +#, elixir-autogen, elixir-format +msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." +msgstr "Ja jums ir nepieciešama palīdzība pasākuma pārvaldībā, varat piešķirt piekļuvi citiem. Vienkārši ievadiet viņu e-pasta adreses; kad viņi reģistrēs kontu ar šiem e-pastiem, viņi varēs pārvaldīt pasākumu." + +#: lib/claper_web/live/event_live/index.html.heex:124 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "Steidzaties?" + +#: lib/claper_web/live/event_live/event_card_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "Tiešraide" + +#: lib/claper_web/live/event_live/index.html.heex:112 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "Mani pasākumi" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 +#, elixir-autogen, elixir-format +msgid "Name of your event" +msgstr "Jūsu pasākuma nosaukums" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 +#, elixir-autogen, elixir-format +msgid "Note: Facilitators do not have the ability to delete your event." +msgstr "Piezīme: moderatoriem nav iespējas dzēst jūsu pasākumu." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 +#, elixir-autogen, elixir-format +msgid "Presentation file (optional)" +msgstr "Prezentācijas fails (pēc izvēles)" + +#: lib/claper_web/live/event_live/index.html.heex:142 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "Ātrs notikums" + +#: lib/claper_web/live/event_live/index.ex:102 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "Veiksmīgi izveidots ātrais notikums" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format +msgid "Return to your last event" +msgstr "Atgriezties pie pēdējā notikuma" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 +#, elixir-autogen, elixir-format +msgid "Select the start date for your event. Future dates are permissible." +msgstr "Izvēlieties pasākuma sākuma datumu. Ir pieļaujami arī turpmākie datumi." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:88 +#, elixir-autogen, elixir-format +msgid "Select your presentation (optional)" +msgstr "Izvēlieties savu prezentāciju (pēc izvēles)" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 +#, elixir-autogen, elixir-format +msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." +msgstr "Šo kodu dalībnieki izmantos, lai piekļūtu pasākumam. Jums ir iespēja izveidot pielāgotu kodu." + +#: lib/claper_web/live/event_live/show.ex:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "Šis notikums ir pārtraukts" + +#: lib/claper_web/live/event_live/index.html.heex:148 +#, elixir-autogen, elixir-format +msgid "Welcome to Claper! You can create a new event here." +msgstr "Laipni lūdzam Claper! Šeit varat izveidot jaunu notikumu." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 +#, elixir-autogen, elixir-format +msgid "When your event will start?" +msgstr "Kad sāksies jūsu pasākums?" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "Izveidojiet nākamo prezentāciju, izmantojot" + +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 +#: lib/claper_web/live/event_live/show.ex:25 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "Notikums neeksistē" + +#: lib/claper_web/live/user_settings_live/show.html.heex:244 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "Pielāgojiet savu kontu" + +#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "Valoda" + +#: lib/claper_web/live/user_settings_live/show.html.heex:241 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "Iestatījumi" + +#: lib/claper_web/live/user_settings_live/show.ex:180 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "Jūsu iestatījumi ir atjaunināti." + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "Jautājums" + +#: lib/claper_web/live/event_live/manage.html.heex:1167 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "Jautājumi" + +#: lib/claper_web/live/event_live/manage.html.heex:1254 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "Jautājumi būs redzami šeit." + +#: lib/claper_web/live/event_live/manage.html.heex:1296 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "Atlasīt pēc datuma" + +#: lib/claper_web/live/event_live/manage.html.heex:1275 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "Atlasīt pēc popularitātes" + +#: lib/claper_web/live/event_live/event_card_component.ex:152 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "Pasākumu vadītājs" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "Dokumentācija" + +#: lib/claper_web/live/user_settings_live/show.html.heex:5 +#: lib/claper_web/templates/layout/_user_menu.html.heex:6 +#, elixir-autogen, elixir-format +msgid "My account" +msgstr "Mans konts" + +#: lib/claper_web/live/user_settings_live/show.html.heex:139 +#, elixir-autogen, elixir-format +msgid "Your personal informations to access your account" +msgstr "Jūsu personiskā informācija, lai piekļūtu savam kontam" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 +#, elixir-autogen, elixir-format +msgid "Enable reactions" +msgstr "Iespējot reakcijas" + +#: lib/claper_web/templates/lti/registration/success.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Activate the tool in your LMS" +msgstr "Aktivizējiet rīku savā LMS" + +#: lib/claper_web/templates/lti/registration/new.html.heex:24 +#, elixir-autogen, elixir-format +msgid "Bring Claper to your LMS" +msgstr "Pievienojiet Claper savai LMS" + +#: lib/claper_web/templates/lti/registration/success.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Check the permissions to share name and email of users" +msgstr "Pārbaudiet lietotāju vārda un e-pasta kopīgošanas atļaujas" + +#: lib/claper_web/templates/lti/registration/success.html.heex:15 +#, elixir-autogen, elixir-format +msgid "Configure it to be opened in a new window" +msgstr "Konfigurējiet, lai tas tiktu atvērts jaunā logā" + +#: lib/claper_web/templates/lti/launch/error.html.heex:5 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "Ups" + +#: lib/claper_web/templates/lti/registration/new.html.heex:27 +#, elixir-autogen, elixir-format +msgid "Register your platform" +msgstr "Reģistrējiet savu platformu" + +#: lib/claper_web/templates/lti/registration/success.html.heex:5 +#, elixir-autogen, elixir-format +msgid "Registration completed" +msgstr "Reģistrācija pabeigta" + +#: lib/claper_web/templates/lti/launch/error.html.heex:9 +#, elixir-autogen, elixir-format +msgid "You cannot perform this action" +msgstr "Šo darbību nevar veikt" + +#: lib/claper_web/templates/lti/registration/success.html.heex:10 +#, elixir-autogen, elixir-format +msgid "Your next steps" +msgstr "Nākamie soļi" + +#: lib/claper_web/templates/lti/registration/new.html.heex:40 +#, elixir-autogen, elixir-format +msgid "Add Claper" +msgstr "Pievienot Claper" + +#: lib/claper_web/live/event_live/manage.html.heex:123 +#: lib/claper_web/live/event_live/manage.html.heex:538 +#, elixir-autogen, elixir-format +msgid "Close preview" +msgstr "Aizvērt priekšskatījumu" + +#: lib/claper_web/live/event_live/manage.html.heex:734 +#, elixir-autogen, elixir-format +msgid "Create your first interaction." +msgstr "Izveidojiet pirmo mijiedarbību." + +#: lib/claper_web/live/event_live/manage.html.heex:1093 +#, elixir-autogen, elixir-format +msgid "Disable" +msgstr "Atspējot" + +#: lib/claper_web/live/event_live/manage.html.heex:1110 +#, elixir-autogen, elixir-format +msgid "Enable" +msgstr "Iespējot" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 +#, elixir-autogen, elixir-format +msgid "Enable messages to change this option" +msgstr "Iespējiet ziņojumus, lai mainītu šo opciju" + +#: lib/claper_web/live/event_live/manage.html.heex:122 +#: lib/claper_web/live/event_live/manage.html.heex:537 +#, elixir-autogen, elixir-format +msgid "Open preview" +msgstr "Atvērt priekšskatījumu" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 +#, elixir-autogen, elixir-format +msgid "Show messages to change this option" +msgstr "Rādīt ziņojumus, lai mainītu šo opciju" + +#: lib/claper_web/live/event_live/manage.html.heex:731 +#, elixir-autogen, elixir-format +msgid "This slide does not have any interactions." +msgstr "Šim slaidam nav mijiedarbības." + +#: lib/claper_web/live/user_settings_live/show.html.heex:176 +#, elixir-autogen, elixir-format +msgid "Accounts linked" +msgstr "Saistītie konti" + +#: lib/claper_web/live/user_settings_live/show.html.heex:208 +#: lib/claper_web/live/user_settings_live/show.html.heex:226 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to unlink this account?" +msgstr "Vai esat pārliecināti, ka vēlaties atcelt šī konta sasaisti?" + +#: lib/claper_web/templates/user_session/new.html.heex:74 +#, elixir-autogen, elixir-format +msgid "Login with %{provider}" +msgstr "Pieteikšanās ar %{provider}" + +#: lib/claper_web/live/user_settings_live/show.ex:101 +#: lib/claper_web/live/user_settings_live/show.ex:115 +#, elixir-autogen, elixir-format +msgid "The account has been unlinked." +msgstr "Konts ir atsaistīts." + +#: lib/claper_web/live/event_live/manage.html.heex:707 +#, elixir-autogen, elixir-format +msgid "This section contains all your interactions." +msgstr "Šajā sadaļā ir iekļautas visas jūsu mijiedarbības." + +#: lib/claper_web/live/user_settings_live/show.html.heex:211 +#: lib/claper_web/live/user_settings_live/show.html.heex:229 +#, elixir-autogen, elixir-format +msgid "Unlink" +msgstr "Atsaistīt" + +#: lib/claper_web/live/event_live/manage.html.heex:707 +#, elixir-autogen, elixir-format +msgid "You can add interactions to your presentation slides." +msgstr "Prezentācijas slaidiem varat pievienot mijiedarbību." + +#: lib/claper_web/live/event_live/manage.html.heex:706 +#, elixir-autogen, elixir-format +msgid "Your interactions" +msgstr "Jūsu mijiedarbība" + +#: lib/claper_web/live/user_settings_live/show.html.heex:119 +#, elixir-autogen, elixir-format +msgid "Confirm password" +msgstr "Paroles apstiprināšana" + +#: lib/claper_web/live/user_settings_live/show.ex:68 +#, elixir-autogen, elixir-format +msgid "Set a new password" +msgstr "Jaunas paroles iestatīšana" + +#: lib/claper_web/live/user_settings_live/show.ex:71 +#, elixir-autogen, elixir-format +msgid "Set a new password for your account before unlinking it." +msgstr "Pirms konta atsaistīšanas iestatiet jaunu paroli." + +#: lib/claper_web/live/user_settings_live/show.ex:204 +#, elixir-autogen, elixir-format +msgid "Your password has been set, you can now unlink your account." +msgstr "Jūsu parole ir iestatīta, tagad varat atsaistīt kontu." + +#: lib/claper_web/live/embed_live/form_component.html.heex:34 +#, elixir-autogen, elixir-format +msgid "Iframe code" +msgstr "Iframe kods" + +#: lib/claper_web/live/embed_live/form_component.html.heex:35 +#, elixir-autogen, elixir-format +msgid "Link to the content" +msgstr "Saite uz saturu" + +#: lib/claper/embeds/embed.ex:65 +#: lib/claper/embeds/embed.ex:74 +#: lib/claper/embeds/embed.ex:83 +#: lib/claper/embeds/embed.ex:92 +#, elixir-autogen, elixir-format +msgid "Please enter a valid %{provider} link" +msgstr "Lūdzu, ievadiet derīgu %{provider} saiti" + +#: lib/claper/embeds/embed.ex:62 +#: lib/claper/embeds/embed.ex:71 +#: lib/claper/embeds/embed.ex:80 +#: lib/claper/embeds/embed.ex:89 +#, elixir-autogen, elixir-format +msgid "Please enter a valid link starting with http:// or https://" +msgstr "Lūdzu, ievadiet derīgu saiti, kas sākas ar http:// vai https://" + +#: lib/claper/embeds/embed.ex:98 +#, elixir-autogen, elixir-format +msgid "Please enter valid HTML content with an iframe tag" +msgstr "Lūdzu, ievadiet derīgu HTML saturu ar iframe tagu" + +#: lib/claper_web/live/embed_live/form_component.html.heex:23 +#, elixir-autogen, elixir-format +msgid "Provider" +msgstr "Nodrošinātājs" + +#: lib/claper_web/live/poll_live/form_component.html.heex:85 +#, elixir-autogen, elixir-format +msgid "Attendees can see the results on their device" +msgstr "Dalībnieki var redzēt rezultātus savā ierīcē" + +#: lib/claper_web/live/embed_live/form_component.html.heex:50 +#, elixir-autogen, elixir-format +msgid "Attendees can view the web content on their device" +msgstr "Apmeklētāji var skatīt tīmekļa saturu savā ierīcē" + +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 +#, elixir-autogen, elixir-format +msgid "Options" +msgstr "Iespējas" + +#: lib/claper_web/live/event_live/event_card_component.ex:268 +#: lib/claper_web/live/event_live/event_card_component.ex:418 +#, elixir-autogen, elixir-format +msgid "Duplicate" +msgstr "Dublēt" + +#: lib/claper_web/templates/error/csrf_error.html.heex:8 +#, elixir-autogen, elixir-format +msgid "A required security token was not found or was invalid." +msgstr "Nepieciešamais drošības žetons netika atrasts vai bija nederīgs." + +#: lib/claper_web/templates/error/csrf_error.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Back to Login" +msgstr "Atgriezties pie pieteikšanās" + +#: lib/claper_web/templates/error/csrf_error.html.heex:5 +#, elixir-autogen, elixir-format +msgid "CSRF Verification Failed" +msgstr "CSRF verifikācija neizdevās" + +#: lib/claper_web/templates/error/csrf_error.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Clear cookies (at least for Claper domain)" +msgstr "Notīriet sīkfailus (vismaz Claper domēnam)" + +#: lib/claper_web/templates/error/csrf_error.html.heex:20 +#, elixir-autogen, elixir-format +msgid "Ensure the URL does not contain an extra \"/\" anywhere" +msgstr "Pārliecinieties, ka URL adresē nav papildu \"/\"" + +#: lib/claper_web/templates/error/csrf_error.html.heex:23 +#, elixir-autogen, elixir-format +msgid "If the problem persists, please contact support." +msgstr "Ja problēma saglabājas, sazinieties ar atbalsta dienestu." + +#: lib/claper_web/templates/error/csrf_error.html.heex:14 +#, elixir-autogen, elixir-format +msgid "If you're continually seeing this issue, try the following:" +msgstr "Ja šī problēma atkārtojas, izmēģiniet šādu darbību:" + +#: lib/claper_web/templates/error/csrf_error.html.heex:18 +#, elixir-autogen, elixir-format +msgid "Reload the page you're trying to access (don't re-submit data)" +msgstr "Atkārtoti ielādējiet lapu, kurai mēģināt piekļūt (neveiciet atkārtotu datu nosūtīšanu)" + +#: lib/claper_web/templates/error/csrf_error.html.heex:19 +#, elixir-autogen, elixir-format +msgid "Try logging in again" +msgstr "Mēģiniet vēlreiz pieteikties" + +#: lib/claper_web/live/event_live/event_card_component.ex:201 +#, elixir-autogen, elixir-format +msgid "End" +msgstr "Izbeigt" + +#: lib/claper_web/live/event_live/event_card_component.ex:212 +#: lib/claper_web/live/event_live/event_card_component.ex:292 +#: lib/claper_web/live/event_live/event_card_component.ex:381 +#, elixir-autogen, elixir-format +msgid "More options" +msgstr "Vairāk iespēju" + +#: lib/claper_web/live/event_live/manage.ex:818 +#, elixir-autogen, elixir-format +msgid "No" +msgstr "Nē" + +#: lib/claper_web/live/event_live/manage.ex:818 +#, elixir-autogen, elixir-format +msgid "Yes" +msgstr "Jā" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:29 +#, elixir-autogen, elixir-format +msgid "CONFIRM ACCOUNT" +msgstr "APSTIPRINĀT KONTU" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Confirm account" +msgstr "Apstiprināt kontu" + +#: lib/claper_web/notifiers/user_notifier.ex:45 +#, elixir-autogen, elixir-format +msgid "Confirmation instructions" +msgstr "Apstiprināšanas norādījumi" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:29 +#, elixir-autogen, elixir-format +msgid "RESET PASSWORD" +msgstr "PAROLES ATIESTATĪŠANA" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Reset password" +msgstr "Paroles atiestatīšana" + +#: lib/claper_web/notifiers/user_notifier.ex:56 +#, elixir-autogen, elixir-format +msgid "Reset password instructions" +msgstr "Paroles atiestatīšanas instrukcijas" + +#: lib/claper_web/templates/user_notifier/confirm.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can confirm your account by visiting the URL below" +msgstr "Varat apstiprināt savu kontu, apmeklējot tālāk norādīto URL adresi" + +#: lib/claper_web/templates/user_notifier/reset.html.heex:22 +#, elixir-autogen, elixir-format +msgid "You can reset your password by visiting the URL below" +msgstr "Savu paroli varat atiestatīt, apmeklējot tālāk norādīto URL adresi" + +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 +#, elixir-autogen, elixir-format +msgid "back to the home page" +msgstr "atpakaļ uz sākumlapu" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 +#, elixir-autogen, elixir-format +msgid "Add Question" +msgstr "Pievienot jautājumu" + +#: lib/claper_web/live/event_live/manage.html.heex:293 +#, elixir-autogen, elixir-format +msgid "Add a quiz to test knowledge." +msgstr "Pievienojiet viktorīnu, lai pārbaudītu zināšanas." + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 +#, elixir-autogen, elixir-format +msgid "Add answer" +msgstr "Pievienot atbildi" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 +#, elixir-autogen, elixir-format +msgid "Allow anonymous messages" +msgstr "Atļaut anonīmus ziņojumus" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 +#, elixir-autogen, elixir-format +msgid "Answer %{index}" +msgstr "Atbilde %{index}" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 +#, elixir-autogen, elixir-format +msgid "Attendees" +msgstr "Dalībnieki" + +#: lib/claper_web/live/event_live/manageable_quiz_component.ex:29 +#: lib/claper_web/live/stat_live/index.html.heex:426 +#, elixir-autogen, elixir-format +msgid "Average score" +msgstr "Vidējais rezultāts" + +#: lib/claper_web/live/event_live/quiz_component.ex:60 +#, elixir-autogen, elixir-format +msgid "Current quiz" +msgstr "Pašreizējā viktorīna" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 +#, elixir-autogen, elixir-format +msgid "Deny anonymous messages" +msgstr "Aizliegt anonīmus ziņojumus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 +#, elixir-autogen, elixir-format +msgid "Disable messages" +msgstr "Izslēgt ziņojumus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 +#, elixir-autogen, elixir-format +msgid "Disable reactions" +msgstr "Izslēgt reakcijas" + +#: lib/claper_web/live/event_live/manage.html.heex:368 +#, elixir-autogen, elixir-format +msgid "Edit quiz" +msgstr "Rediģēt viktorīnu" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 +#, elixir-autogen, elixir-format +msgid "Hide instructions to join" +msgstr "Paslēpt pievienošanās instrukcijas" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 +#, elixir-autogen, elixir-format +msgid "Hide messages" +msgstr "Slēpt ziņojumus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:62 +#: lib/claper_web/live/event_live/manager_settings_component.ex:112 +#, elixir-autogen, elixir-format +msgid "Hide results on presentation" +msgstr "Paslēpt rezultātus prezentācijā" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:36 +#: lib/claper_web/live/event_live/index.html.heex:28 +#: lib/claper_web/live/event_live/manage.html.heex:35 +#, elixir-autogen, elixir-format +msgid "How it works ?" +msgstr "Kā tas darbojas?" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:22 +#, elixir-autogen, elixir-format +msgid "Interaction" +msgstr "Mijiedarbība" + +#: lib/claper_web/live/event_live/manage.html.heex:367 +#, elixir-autogen, elixir-format +msgid "New quiz" +msgstr "Jauna viktorīna" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 +#, elixir-autogen, elixir-format +msgid "Presentation" +msgstr "Prezentācija" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:168 +#, elixir-autogen, elixir-format +msgid "Previous" +msgstr "Iepriekšējais" + +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 +#, elixir-autogen, elixir-format +msgid "Quiz" +msgstr "Viktorīna" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#, elixir-autogen, elixir-format +msgid "Remove question" +msgstr "Noņemt jautājumu" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:144 +#, elixir-autogen, elixir-format +msgid "Review questions" +msgstr "Pārskata jautājumi" + +#: lib/claper_web/live/event_live/quiz_component.ex:41 +#, elixir-autogen, elixir-format +msgid "See current quiz" +msgstr "Skatīt pašreizējo viktorīnu" + +#: lib/claper_web/live/event_live/manage.html.heex:387 +#, elixir-autogen, elixir-format +msgid "Select presentation" +msgstr "Izvēlieties prezentāciju" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 +#, elixir-autogen, elixir-format +msgid "Show all messages" +msgstr "Rādīt visus ziņojumus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 +#, elixir-autogen, elixir-format +msgid "Show instructions to join" +msgstr "Rādīt pievienošanās instrukcijas" + +#: lib/claper_web/live/event_live/quiz_component.ex:121 +#, elixir-autogen, elixir-format +msgid "Show results" +msgstr "Rādīt rezultātus" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:65 +#: lib/claper_web/live/event_live/manager_settings_component.ex:115 +#, elixir-autogen, elixir-format +msgid "Show results on presentation" +msgstr "Rādīt rezultātus prezentācijā" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 +#, elixir-autogen, elixir-format +msgid "This will delete all responses associated and the quiz itself, are you sure?" +msgstr "Tas izdzēsīs visas saistītās atbildes un pašu viktorīnu, vai esat pārliecināti?" + +#: lib/claper_web/live/event_live/quiz_component.ex:124 +#, elixir-autogen, elixir-format +msgid "Waiting for results..." +msgstr "Gaidām rezultātus..." + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 +#, elixir-autogen, elixir-format +msgid "Your question" +msgstr "Jūsu jautājums" + +#: lib/claper_web/live/event_live/quiz_component.ex:113 +#, elixir-autogen, elixir-format +msgid "Your score" +msgstr "Jūsu rezultāts" + +#: lib/claper_web/live/stat_live/index.html.heex:236 +#: lib/claper_web/live/stat_live/index.html.heex:298 +#: lib/claper_web/live/stat_live/index.html.heex:380 +#: lib/claper_web/live/stat_live/index.html.heex:422 +#, elixir-autogen, elixir-format +msgid "Export" +msgstr "Eksportēt" + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 +#, elixir-autogen, elixir-format +msgid "Export to QTI (XML)" +msgstr "Eksportēšana uz QTI (XML)" + +#: lib/claper_web/live/stat_live/index.html.heex:194 +#, elixir-autogen, elixir-format +msgid "Forms" +msgstr "Veidlapas" + +#: lib/claper_web/live/stat_live/index.html.heex:170 +#, elixir-autogen, elixir-format +msgid "Interactions" +msgstr "Mijiedarbība" + +#: lib/claper_web/live/stat_live/index.html.heex:338 +#, elixir-autogen, elixir-format +msgid "No form has been created" +msgstr "Nav izveidota neviena veidlapa" + +#: lib/claper_web/live/stat_live/index.html.heex:272 +#, elixir-autogen, elixir-format +msgid "No poll has been created" +msgstr "Nav izveidota neviena aptauja" + +#: lib/claper_web/live/stat_live/index.html.heex:476 +#, elixir-autogen, elixir-format +msgid "No quiz has been created" +msgstr "Nav izveidota viktorīna" + +#: lib/claper_web/live/stat_live/index.html.heex:359 +#, elixir-autogen, elixir-format +msgid "No web content has been created" +msgstr "Tīmekļa saturs nav izveidots" + +#: lib/claper_web/live/stat_live/index.html.heex:187 +#, elixir-autogen, elixir-format +msgid "Polls" +msgstr "Aptaujas" + +#: lib/claper_web/live/stat_live/index.html.heex:208 +#, elixir-autogen, elixir-format +msgid "Quizzes" +msgstr "Viktorīnas" + +#: lib/claper_web/live/stat_live/index.ex:62 +#, elixir-autogen, elixir-format +msgid "Report" +msgstr "Ziņojums" + +#: lib/claper_web/live/stat_live/index.html.heex:70 +#, elixir-autogen, elixir-format +msgid "Unique attendees" +msgstr "Unikālie apmeklētāji" + +#: lib/claper_web/live/stat_live/index.html.heex:201 +#, elixir-autogen, elixir-format +msgid "Web Content" +msgstr "Tīmekļa saturs" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 +#, elixir-autogen, elixir-format +msgid "Active" +msgstr "Aktīvs" + +#: lib/claper_web/live/event_live/index.html.heex:218 +#, elixir-autogen, elixir-format +msgid "Load more" +msgstr "Ielādēt vairāk" + +#: lib/claper_web/live/event_live/index.html.heex:195 +#, elixir-autogen, elixir-format +msgid "Shared with you" +msgstr "Kopīgots ar jums" + +#: lib/claper_web/templates/lti/registration/new.html.heex:43 +#, elixir-autogen, elixir-format +msgid "You must login to continue" +msgstr "Jums ir jāpiesakās, lai turpinātu" + +#: lib/claper/quizzes/quiz_question.ex:51 +#, elixir-autogen, elixir-format +msgid "must have at least one correct answer" +msgstr "jābūt vismaz vienai pareizai atbildei" + +#: lib/claper_web/live/event_live/manage.html.heex:547 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." +msgstr "Noklikšķiniet šeit, lai atvērtu prezentācijas logu. Prezentācijas logā nospiediet F, lai iespējotu pilnekrāna režīmu." + +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 +#, elixir-autogen, elixir-format +msgid "Allow anonymous submissions" +msgstr "Atļaut anonīmus iesniegumus" + +#: lib/claper_web/live/event_live/quiz_component.ex:167 +#, elixir-autogen, elixir-format +msgid "Please sign in to submit your answers" +msgstr "Lūdzu, pierakstieties, lai iesniegtu savas atbildes" + +#: lib/claper_web/live/event_live/quiz_component.ex:170 +#, elixir-autogen, elixir-format +msgid "Sign in" +msgstr "Pierakstīties" + +#: lib/claper_web/live/stat_live/index.html.heex:435 +#, elixir-autogen, elixir-format +msgid "Total submissions" +msgstr "Kopējais iesniegto pieteikumu skaits" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Iespējas" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Aktīvs" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "Vai esat pārliecināti, ka vēlaties atcelt šī konta sasaisti?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "Vai esat pārliecināti, ka vēlaties atcelt šī konta sasaisti?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "Vai esat pārliecināti, ka vēlaties atcelt šī konta sasaisti?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Auditorijas maksimums" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Mainīt failu" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format +msgid "Confirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Izveidot notikumu" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Izveidot" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Izveidot" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Izveidot" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Pašreizējā viktorīna" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Dzēst" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Dzēst" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Rediģēt" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Pašreizējā parole" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Pasākums" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Veidlapas" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Aktīvs" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "Nodrošinātājs" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "Nodrošinātājs" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "Parole veiksmīgi atjaunināta." + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "" + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Izvēlieties vienu iespēju" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "Parole veiksmīgi atjaunināta." + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Apskatīt ziņojumu" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "dalībnieku" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format +msgid "Back to events" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "Back to providers" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format +msgid "Back to users" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format +msgid "New provider" +msgstr "" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format +msgid "New user" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format +msgid "No providers found" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format +msgid "Provider deleted successfully" +msgstr "" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Nodrošinātājs" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "Apstiprināt e-pastu" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Ja neesat izveidojuši mūsu kontu, lūdzu, ignorējiet šo informāciju." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Savu e-pasta adresi varat mainīt, apmeklējot tālāk norādīto URL adresi" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Slēpt dalībnieku skaitu" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Rādīt dalībnieku skaitu" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Obligāti aizpildāms" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(pēc izvēles)" diff --git a/priv/gettext/lv/LC_MESSAGES/errors.po b/priv/gettext/lv/LC_MESSAGES/errors.po new file mode 100644 index 0000000..2efc0fc --- /dev/null +++ b/priv/gettext/lv/LC_MESSAGES/errors.po @@ -0,0 +1,90 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: POEditor.com\n" +"Project-Id-Version: Claper\n" +"Language: lv\n" +"Plural-Forms: nplurals=3; plural=(n%10==0 || n%100>=11 && n%100<=19) ? 0 : ((n%10==1 && n%100 != 11) ? 1 : 2);\n" + +msgid "can't be blank" +msgstr "nedrīkst būt tukšs" + +msgid "has already been taken" +msgstr "jau ir aizņemts" + +msgid "is invalid" +msgstr "ir nederīgs" + +msgid "must be accepted" +msgstr "jābūt pieņemtam" + +msgid "has invalid format" +msgstr "ir nederīgs formāts" + +msgid "has an invalid entry" +msgstr "ir nederīgs ieraksts" + +msgid "is reserved" +msgstr "ir rezervēts" + +msgid "does not match confirmation" +msgstr "neatbilst apstiprinājumam" + +msgid "is still associated with this entry" +msgstr "joprojām ir saistīts ar šo ierakstu" + +msgid "are still associated with this entry" +msgstr "joprojām ir saistīti ar šo ierakstu" + +msgid "should be %{count} character(s)" +msgid_plural "should be %{count} character(s)" +msgstr[0] "jābūt %{count} rakstzīmju" +msgstr[1] "jābūt %{count} rakstzīmei" +msgstr[2] "jābūt %{count} rakstzīmēm" + +msgid "should have %{count} item(s)" +msgid_plural "should have %{count} item(s)" +msgstr[0] "jābūt %{count} vienību" +msgstr[1] "jābūt %{count} vienībai" +msgstr[2] "jābūt %{count} vienībām" + +msgid "should be at least %{count} character(s)" +msgid_plural "should be at least %{count} character(s)" +msgstr[0] "jābūt vismaz %{count} rakstzīmju" +msgstr[1] "jābūt vismaz %{count} rakstzīmei" +msgstr[2] "jābūt vismaz %{count} rakstzīmēm" + +msgid "should have at least %{count} item(s)" +msgid_plural "should have at least %{count} item(s)" +msgstr[0] "jābūt vismaz %{count} vienību" +msgstr[1] "jābūt vismaz %{count} vienībai" +msgstr[2] "jābūt vismaz %{count} vienībām" + +msgid "should be at most %{count} character(s)" +msgid_plural "should be at most %{count} character(s)" +msgstr[0] "jābūt ne vairāk kā %{count} rakstzīmju" +msgstr[1] "jābūt ne vairāk kā %{count} rakstzīmei" +msgstr[2] "jābūt ne vairāk kā %{count} rakstzīmēm" + +msgid "should have at most %{count} item(s)" +msgid_plural "should have at most %{count} item(s)" +msgstr[0] "jābūt ne vairāk kā %{count} vienību" +msgstr[1] "jābūt ne vairāk kā %{count} vienībai" +msgstr[2] "jābūt ne vairāk kā %{count} vienībām" + +msgid "must be less than %{number}" +msgstr "jābūt mazākam par %{number}" + +msgid "must be greater than %{number}" +msgstr "jābūt lielākam par %{number}" + +msgid "must be less than or equal to %{number}" +msgstr "jābūt mazākam vai vienādam ar %{number}" + +msgid "must be greater than or equal to %{number}" +msgstr "jābūt lielākam vai vienādam ar %{number}" + +msgid "must be equal to %{number}" +msgstr "jābūt vienādam ar %{number}" diff --git a/priv/gettext/nl/LC_MESSAGES/default.po b/priv/gettext/nl/LC_MESSAGES/default.po index 110960d..4a59930 100644 --- a/priv/gettext/nl/LC_MESSAGES/default.po +++ b/priv/gettext/nl/LC_MESSAGES/default.po @@ -8,15 +8,18 @@ msgstr "" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/event_live/manage.html.heex:1457 -#: lib/claper_web/live/event_live/manage.html.heex:1463 +#: lib/claper_web/live/event_live/manage.html.heex:1449 +#: lib/claper_web/live/event_live/manage.html.heex:1455 #: lib/claper_web/live/user_settings_live/show.ex:77 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Instellingen" -#: lib/claper_web/live/event_live/manage.ex:815 -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/admin_live/user_live.html.heex:74 +#: lib/claper_web/live/admin_live/user_live.html.heex:254 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:18 +#: lib/claper_web/live/event_live/manage.ex:838 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:34 #: lib/claper_web/templates/user_registration/new.html.heex:29 #: lib/claper_web/templates/user_reset_password/new.html.heex:28 @@ -43,7 +46,10 @@ msgstr "Oeps, controleer of alle velden correct zijn ingevuld." msgid "Change" msgstr "Aanpassen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:287 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:83 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:32 +#: lib/claper_web/live/event_live/event_form_component.html.heex:309 #, elixir-autogen, elixir-format msgid "Code" msgstr "Code" @@ -54,7 +60,7 @@ msgstr "Code" msgid "Email address" msgstr "E-mailadres" -#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#: lib/claper_web/templates/layout/_user_menu.html.heex:23 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Uitloggen" @@ -97,15 +103,18 @@ msgstr "Wees de eerste die reageert!" #: lib/claper_web/live/event_live/event_card_component.ex:111 #: lib/claper_web/live/event_live/join.ex:41 #: lib/claper_web/live/event_live/join.html.heex:94 -#: lib/claper_web/live/event_live/manage.html.heex:493 +#: lib/claper_web/live/event_live/manage.html.heex:492 #: lib/claper_web/live/event_live/show.html.heex:286 #, elixir-autogen, elixir-format msgid "Join" msgstr "Meedoen" -#: lib/claper_web/live/event_live/index.ex:212 +#: lib/claper_web/live/admin_live/dashboard_live.ex:22 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:3 +#: lib/claper_web/live/event_live/index.ex:223 #: lib/claper_web/live/event_live/join.html.heex:31 #: lib/claper_web/live/event_live/join.html.heex:54 +#: lib/claper_web/templates/layout/admin.html.heex:198 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Dashboard" @@ -122,7 +131,7 @@ msgid "seconds" msgstr "seconden" #: lib/claper_web/live/event_live/event_card_component.ex:60 -#: lib/claper_web/live/event_live/index.html.heex:186 +#: lib/claper_web/live/event_live/index.html.heex:187 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Afgerond" @@ -175,47 +184,50 @@ msgstr "Terug" msgid "Created successfully" msgstr "Succesvol aangemaakt" +#: lib/claper_web/live/admin_live/event_live.html.heex:259 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:240 +#: lib/claper_web/live/admin_live/user_live.html.heex:240 #: lib/claper_web/live/event_live/event_card_component.ex:250 #: lib/claper_web/live/event_live/event_card_component.ex:330 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:193 +#: lib/claper_web/live/event_live/index.ex:204 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Bewerken" -#: lib/claper_web/live/embed_live/form_component.html.heex:69 +#: lib/claper_web/live/embed_live/form_component.html.heex:63 #: lib/claper_web/live/event_live/event_form_component.html.heex:55 #: lib/claper_web/live/event_live/event_form_component.html.heex:62 -#: lib/claper_web/live/event_live/index.ex:202 -#: lib/claper_web/live/event_live/index.html.heex:93 -#: lib/claper_web/live/form_live/form_component.html.heex:98 -#: lib/claper_web/live/poll_live/form_component.html.heex:106 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 +#: lib/claper_web/live/event_live/index.ex:213 +#: lib/claper_web/live/event_live/index.html.heex:94 +#: lib/claper_web/live/form_live/form_component.html.heex:93 +#: lib/claper_web/live/poll_live/form_component.html.heex:102 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:187 #, elixir-autogen, elixir-format msgid "Create" msgstr "Aanmaken" -#: lib/claper_web/live/embed_live/form_component.html.heex:74 +#: lib/claper_web/live/embed_live/form_component.html.heex:68 #: lib/claper_web/live/event_live/event_card_component.ex:444 #: lib/claper_web/live/event_live/event_form_component.html.heex:67 -#: lib/claper_web/live/event_live/manage.html.heex:1405 +#: lib/claper_web/live/event_live/manage.html.heex:1397 #: lib/claper_web/live/event_live/manageable_post_component.ex:92 #: lib/claper_web/live/event_live/post_component.ex:70 #: lib/claper_web/live/event_live/post_component.ex:142 -#: lib/claper_web/live/form_live/form_component.html.heex:103 -#: lib/claper_web/live/poll_live/form_component.html.heex:111 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:129 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:199 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:107 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:123 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:193 #, elixir-autogen, elixir-format msgid "Delete" msgstr "Verwijderen" -#: lib/claper_web/live/embed_live/form_component.html.heex:70 +#: lib/claper_web/live/embed_live/form_component.html.heex:64 #: lib/claper_web/live/event_live/event_form_component.html.heex:54 #: lib/claper_web/live/event_live/event_form_component.html.heex:61 -#: lib/claper_web/live/form_live/form_component.html.heex:99 -#: lib/claper_web/live/poll_live/form_component.html.heex:107 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:194 +#: lib/claper_web/live/form_live/form_component.html.heex:94 +#: lib/claper_web/live/poll_live/form_component.html.heex:103 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:188 #: lib/claper_web/live/user_settings_live/show.html.heex:38 #: lib/claper_web/live/user_settings_live/show.html.heex:80 #: lib/claper_web/live/user_settings_live/show.html.heex:123 @@ -259,12 +271,6 @@ msgstr "E-mailinstructies bijwerken" msgid "CONFIRM EMAIL" msgstr "BEVESTIG E-MAIL" -#: lib/claper_web/templates/user_notifier/change.html.heex:17 -#, elixir-autogen, elixir-format -msgid "Confirm email" -msgstr "Bevestig e-mail" - -#: lib/claper_web/templates/user_notifier/change.html.heex:32 #: lib/claper_web/templates/user_notifier/confirm.html.heex:32 #: lib/claper_web/templates/user_notifier/magic.html.heex:32 #: lib/claper_web/templates/user_notifier/reset.html.heex:32 @@ -295,9 +301,9 @@ msgid "Presentation uploaded" msgstr "Presentatie geupload" #: lib/claper_web/live/event_live/event_form_component.html.heex:163 -#: lib/claper_web/live/event_live/event_form_component.html.heex:241 -#: lib/claper_web/live/event_live/event_form_component.html.heex:369 -#: lib/claper_web/live/event_live/event_form_component.html.heex:393 +#: lib/claper_web/live/event_live/event_form_component.html.heex:261 +#: lib/claper_web/live/event_live/event_form_component.html.heex:391 +#: lib/claper_web/live/event_live/event_form_component.html.heex:415 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Verwijderen" @@ -332,17 +338,17 @@ msgstr "Het bestand is te groot" msgid "Change file" msgstr "Bestand aanpassen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 +#: lib/claper_web/live/event_live/event_form_component.html.heex:238 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Presentatie vervangen" -#: lib/claper_web/live/event_live/manage.html.heex:306 +#: lib/claper_web/live/event_live/manage.html.heex:305 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Peiling bewerken" -#: lib/claper_web/live/event_live/manage.html.heex:305 +#: lib/claper_web/live/event_live/manage.html.heex:304 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Nieuwe peiling" @@ -357,18 +363,18 @@ msgstr "Titel van de peiling" msgid "Upload failed" msgstr "Uploaden mislukt" -#: lib/claper_web/live/event_live/manage.html.heex:198 +#: lib/claper_web/live/event_live/manage.html.heex:197 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "Voeg een peiling toe om achter de mening van het publiek te komen." -#: lib/claper_web/live/event_live/manage.html.heex:195 -#: lib/claper_web/live/event_live/manage.html.heex:786 +#: lib/claper_web/live/event_live/manage.html.heex:194 +#: lib/claper_web/live/event_live/manage.html.heex:780 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Peiling" -#: lib/claper_web/live/poll_live/form_component.html.heex:30 +#: lib/claper_web/live/poll_live/form_component.html.heex:26 #, elixir-format, ex-autogen, elixir-autogen msgid "Choice %{count}" msgid_plural "Choice %{count}" @@ -391,18 +397,18 @@ msgstr "Bekijk huidige peiling" msgid "Vote" msgstr "Stemmen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:358 -#: lib/claper_web/live/event_live/event_form_component.html.heex:376 +#: lib/claper_web/live/event_live/event_form_component.html.heex:380 +#: lib/claper_web/live/event_live/event_form_component.html.heex:398 #, elixir-autogen, elixir-format msgid "User email address" msgstr "E-mailadres van gebruiker" -#: lib/claper_web/live/event_live/event_form_component.html.heex:207 +#: lib/claper_web/live/event_live/event_form_component.html.heex:217 #, elixir-autogen, elixir-format msgid "Changing your file will remove all interaction elements like polls associated." msgstr "Als je het bestand wijzigt, worden alle bijbehorende interactie-elementen, zoals peilingen, verwijderd." -#: lib/claper_web/live/event_live/manage.html.heex:1221 +#: lib/claper_web/live/event_live/manage.html.heex:1213 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Hier verschijnen berichten van deelnemers." @@ -412,7 +418,7 @@ msgstr "Hier verschijnen berichten van deelnemers." msgid "Processing your file..." msgstr "Bestand verwerken..." -#: lib/claper_web/live/poll_live/form_component.html.heex:118 +#: lib/claper_web/live/poll_live/form_component.html.heex:114 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "Hierdoor worden alle bijbehorende reacties en de peiling verwijderd. Weet je het zeker?" @@ -422,14 +428,14 @@ msgstr "Hierdoor worden alle bijbehorende reacties en de peiling verwijderd. Wee msgid "Ask, comment..." msgstr "Vraag, reageer..." -#: lib/claper_web/live/event_live/manage.html.heex:1167 +#: lib/claper_web/live/event_live/manage.html.heex:1159 #: lib/claper_web/live/stat_live/index.html.heex:102 #: lib/claper_web/live/stat_live/index.html.heex:180 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Berichten" -#: lib/claper_web/live/event_live/event_form_component.html.heex:341 +#: lib/claper_web/live/event_live/event_form_component.html.heex:363 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Facilitator toevoegen" @@ -444,7 +450,7 @@ msgstr "Oeps, pagina bestaat niet." msgid "The site is under maintenance, we'll be back very soon!" msgstr "Er wordt aan de site gewerkt, we komen snel terug!" -#: lib/claper_web/live/event_live/event_form_component.html.heex:320 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "Facilitators kunnen interacties presenteren en beheren" @@ -458,13 +464,8 @@ msgstr "Facilitators kunnen interacties presenteren en beheren" msgid "If you’re having trouble with the button above, copy and paste the URL below into your web browser" msgstr "Als je problemen ondervindt met de bovenstaande knop, kopieer en plak dan de onderstaande URL in de webbrowser" -#: lib/claper_web/templates/user_notifier/change.html.heex:22 -#, elixir-autogen, elixir-format -msgid "You can change your email by visiting the URL below" -msgstr "Je kunt het e-mailadres wijzigen door naar de onderstaande URL te gaan" - -#: lib/claper_web/live/event_live/manage.html.heex:759 -#: lib/claper_web/live/event_live/manage.html.heex:1132 +#: lib/claper_web/live/event_live/manage.html.heex:750 +#: lib/claper_web/live/event_live/manage.html.heex:1124 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "Voeg interactie toe" @@ -622,6 +623,7 @@ msgstr "Of gebruik de code:" msgid "Create account" msgstr "Account aanmaken" +#: lib/claper_web/live/admin_live/user_live/form_component.ex:32 #: lib/claper_web/live/user_settings_live/show.html.heex:161 #: lib/claper_web/templates/user_registration/new.html.heex:37 #: lib/claper_web/templates/user_reset_password/edit.html.heex:34 @@ -657,14 +659,14 @@ msgstr "Update jouw wachtwoord" msgid "Your password has been updated." msgstr "Het wachtwoord is bijgewerkt." -#: lib/claper_web/live/form_live/form_component.html.heex:30 +#: lib/claper_web/live/form_live/form_component.html.heex:26 #, elixir-autogen, elixir-format msgid "Field %{count}" msgid_plural "Field %{count}" msgstr[0] "Veld %{count}" msgstr[1] "Velden %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:231 +#: lib/claper_web/live/event_live/manage.html.heex:230 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "Voeg een formulier toe om gegevens van het publiek te verzamelen." @@ -674,34 +676,41 @@ msgstr "Voeg een formulier toe om gegevens van het publiek te verzamelen." msgid "Current form" msgstr "Huidig formulier" -#: lib/claper_web/live/event_live/manage.html.heex:327 +#: lib/claper_web/live/event_live/manage.html.heex:326 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "Formulier bewerken" -#: lib/claper_web/live/event_live/manage.html.heex:228 -#: lib/claper_web/live/event_live/manage.html.heex:830 -#: lib/claper_web/live/event_live/manage.html.heex:1417 +#: lib/claper_web/live/event_live/manage.html.heex:227 +#: lib/claper_web/live/event_live/manage.html.heex:824 +#: lib/claper_web/live/event_live/manage.html.heex:1409 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formulier" -#: lib/claper_web/live/event_live/manage.html.heex:1191 +#: lib/claper_web/live/event_live/manage.html.heex:1183 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Formulierinzendingen" -#: lib/claper_web/live/event_live/manage.html.heex:1390 +#: lib/claper_web/live/event_live/manage.html.heex:1382 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "Formulierinzendingen van deelnemers worden hier weergegeven." -#: lib/claper_web/live/event_live/manage.ex:814 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:106 +#: lib/claper_web/live/admin_live/event_live.html.heex:74 +#: lib/claper_web/live/admin_live/event_live.html.heex:273 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:19 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:74 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:254 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:24 +#: lib/claper_web/live/event_live/manage.ex:837 #, elixir-autogen, elixir-format msgid "Name" msgstr "Naam" -#: lib/claper_web/live/event_live/manage.html.heex:326 +#: lib/claper_web/live/event_live/manage.html.heex:325 #, elixir-autogen, elixir-format msgid "New form" msgstr "Nieuw formulier" @@ -722,17 +731,17 @@ msgstr "Bekijk huidig formulier" msgid "Submit" msgstr "Indienen" -#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: lib/claper_web/live/form_live/form_component.html.heex:32 #, elixir-autogen, elixir-format msgid "Text" msgstr "Tekst" -#: lib/claper_web/live/event_live/manage.html.heex:1410 +#: lib/claper_web/live/event_live/manage.html.heex:1402 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Dit kan niet ongedaan worden gemaakt. Bevestigen ?" -#: lib/claper_web/live/form_live/form_component.html.heex:110 +#: lib/claper_web/live/form_live/form_component.html.heex:105 #, elixir-autogen, elixir-format msgid "This will delete all responses associated and the form itself, are you sure?" msgstr "Hiermee worden alle bijbehorende reacties en het formulier zelf verwijderd. Weet je het zeker?" @@ -742,7 +751,7 @@ msgstr "Hiermee worden alle bijbehorende reacties en het formulier zelf verwijde msgid "Title of your form" msgstr "Titel van uw formulier" -#: lib/claper_web/live/form_live/form_component.html.heex:40 +#: lib/claper_web/live/form_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Type" msgstr "Type" @@ -757,7 +766,7 @@ msgstr "Selecteer een optie" msgid "Select one or multiple options" msgstr "Selecteer een of meerdere opties" -#: lib/claper_web/live/poll_live/form_component.html.heex:96 +#: lib/claper_web/live/poll_live/form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "Multiple answers" msgstr "Meerdere antwoorden" @@ -767,12 +776,12 @@ msgstr "Meerdere antwoorden" msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX tot %{size} MB" -#: lib/claper_web/live/event_live/manager_settings_component.ex:426 +#: lib/claper_web/live/event_live/manager_settings_component.ex:482 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Schakel berichten in" -#: lib/claper_web/live/event_live/manager_settings_component.ex:304 +#: lib/claper_web/live/event_live/manager_settings_component.ex:305 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Toon berichten" @@ -821,7 +830,7 @@ msgstr "uitgeschakeld" msgid "Account creation is disabled" msgstr "Het aanmaken van een account is uitgeschakeld" -#: lib/claper_web/live/event_live/manage.html.heex:262 +#: lib/claper_web/live/event_live/manage.html.heex:261 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Voeg een YouTube-video of andere webinhoud toe." @@ -872,12 +881,12 @@ msgstr "Link verzenden om wachtwoord opnieuw in te stellen" msgid "Current web content" msgstr "Huidige webinhoud" -#: lib/claper_web/live/event_live/manage.html.heex:348 +#: lib/claper_web/live/event_live/manage.html.heex:347 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Webinhoud bewerken" -#: lib/claper_web/live/event_live/manage.html.heex:347 +#: lib/claper_web/live/event_live/manage.html.heex:346 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Nieuwe webinhoud" @@ -887,7 +896,7 @@ msgstr "Nieuwe webinhoud" msgid "See current web content" msgstr "Bekijk huidige webinhoud" -#: lib/claper_web/live/embed_live/form_component.html.heex:80 +#: lib/claper_web/live/embed_live/form_component.html.heex:74 #, elixir-autogen, elixir-format msgid "This will delete the web content, are you sure?" msgstr "Hiermee wordt de webinhoud verwijderd. Weet je het zeker?" @@ -898,8 +907,8 @@ msgstr "Hiermee wordt de webinhoud verwijderd. Weet je het zeker?" msgid "Title" msgstr "Titel" -#: lib/claper_web/live/event_live/manage.html.heex:260 -#: lib/claper_web/live/event_live/manage.html.heex:874 +#: lib/claper_web/live/event_live/manage.html.heex:259 +#: lib/claper_web/live/event_live/manage.html.heex:866 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Webinhoud" @@ -916,17 +925,17 @@ msgstr "Vastzetten" msgid "Pinned" msgstr "Vastgezet" -#: lib/claper_web/live/event_live/manage.html.heex:1183 +#: lib/claper_web/live/event_live/manage.html.heex:1175 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "Vastgezette berichten" -#: lib/claper_web/live/event_live/manage.html.heex:1344 +#: lib/claper_web/live/event_live/manage.html.heex:1336 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Hier verschijnen vastgezette berichten." -#: lib/claper_web/live/event_live/manager_settings_component.ex:359 +#: lib/claper_web/live/event_live/manager_settings_component.ex:360 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Toon alleen vastgezette berichten" @@ -967,7 +976,7 @@ msgstr "Je bent uitgenodigd om een evenement te beheren" msgid "Saved" msgstr "Opgeslagen" -#: lib/claper_web/live/user_settings_live/show.html.heex:288 +#: lib/claper_web/live/user_settings_live/show.html.heex:301 #, elixir-autogen, elixir-format msgid "All your events and files will be permanently deleted, are you sure?" msgstr "Al jouw evenementen en bestanden worden definitief verwijderd. Weet je dat zeker?" @@ -982,22 +991,22 @@ msgstr "Weet je zeker dat je dit evenement wil stoppen? Deze actie kan niet onge msgid "Attendees room" msgstr "Deelnemers ruimte" -#: lib/claper_web/live/user_settings_live/show.html.heex:278 +#: lib/claper_web/live/user_settings_live/show.html.heex:291 #, elixir-autogen, elixir-format msgid "Be careful, these actions are irreversible" msgstr "Wees voorzichtig, deze acties zijn onomkeerbaar" -#: lib/claper_web/live/user_settings_live/show.html.heex:275 +#: lib/claper_web/live/user_settings_live/show.html.heex:288 #, elixir-autogen, elixir-format msgid "Danger zone" msgstr "Gevarenzone" -#: lib/claper_web/live/user_settings_live/show.html.heex:284 +#: lib/claper_web/live/user_settings_live/show.html.heex:297 #, elixir-autogen, elixir-format, fuzzy msgid "Delete account" msgstr "Account verwijderen" -#: lib/claper_web/live/event_live/manage.html.heex:566 +#: lib/claper_web/live/event_live/manage.html.heex:565 #, elixir-autogen, elixir-format msgid "Open presentation" msgstr "Presentatie openen" @@ -1012,7 +1021,7 @@ msgstr "Bekijk rapport" msgid "Your account has been deleted." msgstr "Je account is verwijderd." -#: lib/claper_web/live/event_live/event_form_component.html.heex:279 +#: lib/claper_web/live/event_live/event_form_component.html.heex:301 #, elixir-autogen, elixir-format, fuzzy msgid "Access code" msgstr "Toegangscode" @@ -1022,46 +1031,46 @@ msgstr "Toegangscode" msgid "Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly." msgstr "Animaties in PPT/PPTX-bestanden worden niet ondersteund. Daarom raden wij je aan de presentatie naar PDF te exporteren om er zeker van te zijn dat deze correct wordt weergegeven." -#: lib/claper_web/live/event_live/manage.html.heex:1155 +#: lib/claper_web/live/event_live/manage.html.heex:1147 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees interactions" msgstr "Interacties van deelnemers" #: lib/claper_web/live/event_live/event_form_component.html.heex:6 -#: lib/claper_web/live/event_live/index.html.heex:106 -#: lib/claper_web/live/event_live/manage.html.heex:429 +#: lib/claper_web/live/event_live/index.html.heex:107 +#: lib/claper_web/live/event_live/manage.html.heex:428 #: lib/claper_web/live/event_live/quiz_component.ex:151 #: lib/claper_web/live/event_live/quiz_component.ex:198 #, elixir-autogen, elixir-format msgid "Back" msgstr "Terug" -#: lib/claper_web/live/event_live/event_form_component.html.heex:314 +#: lib/claper_web/live/event_live/event_form_component.html.heex:336 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators" msgstr "Facilitators" #: lib/claper_web/live/event_live/event_form_component.html.heex:7 -#: lib/claper_web/live/event_live/index.html.heex:107 -#: lib/claper_web/live/event_live/manage.html.heex:430 +#: lib/claper_web/live/event_live/index.html.heex:108 +#: lib/claper_web/live/event_live/manage.html.heex:429 #: lib/claper_web/templates/lti/registration/success.html.heex:26 #, elixir-autogen, elixir-format, fuzzy msgid "Finish" msgstr "Finish" -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Here you'll find all interactions from your attendees. You can manage messages, pinned messages, and submitted forms." msgstr "Hier vind je alle interacties van je bezoekers. Je kunt berichten, vastgezette berichten en verzonden formulieren beheren." -#: lib/claper_web/live/event_live/manage.html.heex:1157 +#: lib/claper_web/live/event_live/manage.html.heex:1149 #, elixir-autogen, elixir-format msgid "Identify users by their unique avatars." msgstr "Identificeer gebruikers aan de hand van hun unieke avatars." #: lib/claper_web/live/event_live/event_form_component.html.heex:5 -#: lib/claper_web/live/event_live/index.html.heex:105 -#: lib/claper_web/live/event_live/manage.html.heex:428 +#: lib/claper_web/live/event_live/index.html.heex:106 +#: lib/claper_web/live/event_live/manage.html.heex:427 #: lib/claper_web/live/event_live/manager_settings_component.ex:176 #: lib/claper_web/live/event_live/quiz_component.ex:161 #: lib/claper_web/live/event_live/quiz_component.ex:209 @@ -1074,57 +1083,57 @@ msgstr "Volgende" msgid "Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit." msgstr "Selecteer het Presentatie. Geaccepteerde formaten zijn PDF, PPT of PPTX. Zorg ervoor dat de bestandsgrootte de maximale limiet niet overschrijdt." -#: lib/claper_web/live/event_live/manage.html.heex:546 +#: lib/claper_web/live/event_live/manage.html.heex:545 #, elixir-autogen, elixir-format, fuzzy msgid "Time to launch your presentation!" msgstr "Tijd om je presentatie te starten!" -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "Use the associated keyboard shortcuts for quick toggling of these settings." msgstr "Gebruik de bijbehorende sneltoetsen om snel tussen deze instellingen te schakelen." -#: lib/claper_web/live/event_live/manage.html.heex:1459 +#: lib/claper_web/live/event_live/manage.html.heex:1451 #, elixir-autogen, elixir-format msgid "You can control each setting for the presentation (showing on the big screen) and on the attendee's room." msgstr "Je kunt elke instelling voor de presentatie (weergave op het grote scherm) en in de ruimte van de deelnemer beheren." -#: lib/claper_web/live/event_live/index.html.heex:148 +#: lib/claper_web/live/event_live/index.html.heex:149 #, elixir-autogen, elixir-format msgid "Your first steps with Claper" msgstr "Je eerste stappen met Claper" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees attempting to access the event prior to this date will be directed to a waiting room." msgstr "Bezoekers die voor deze datum proberen toegang te krijgen tot het evenement, worden doorverwezen naar een wachtkamer." -#: lib/claper_web/live/event_live/index.html.heex:166 +#: lib/claper_web/live/event_live/index.html.heex:167 #, elixir-autogen, elixir-format, fuzzy msgid "Create event" msgstr "Evenement aanmaken" -#: lib/claper_web/live/event_live/index.html.heex:224 +#: lib/claper_web/live/event_live/index.html.heex:225 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first event" msgstr "Maak je eerste evenement aan" -#: lib/claper_web/live/event_live/event_form_component.html.heex:294 +#: lib/claper_web/live/event_live/event_form_component.html.heex:316 #, elixir-autogen, elixir-format msgid "Event start date" msgstr "Startdatum evenement" -#: lib/claper_web/live/event_live/index.html.heex:118 +#: lib/claper_web/live/event_live/index.html.heex:119 #, elixir-autogen, elixir-format msgid "If you don't have time and just want interactions without a presentation file, you can create a new event here." msgstr "Als je geen tijd heeft en alleen interacties wilt zonder een Presentatie, kun je hier een nieuw evenement aanmaken." -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "If you require assistance in managing your event, you can grant access to others. Simply enter their email addresses; once they register an account with these emails, they will be able to manage the event." msgstr "Als je hulp nodig hebt bij het beheren van uw evenement, kunt je anderen toegang verlenen. Voer eenvoudig hun e-mailadressen in; zodra ze een account registreren met deze e-mails, kunnen ze het evenement beheren." -#: lib/claper_web/live/event_live/index.html.heex:123 +#: lib/claper_web/live/event_live/index.html.heex:124 #, elixir-autogen, elixir-format msgid "In a hurry ?" msgstr "Heb je haast ?" @@ -1134,18 +1143,18 @@ msgstr "Heb je haast ?" msgid "Live" msgstr "Live" -#: lib/claper_web/live/event_live/index.html.heex:111 +#: lib/claper_web/live/event_live/index.html.heex:112 #, elixir-autogen, elixir-format msgid "My events" msgstr "Mijn evenementen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:271 -#: lib/claper_web/live/event_live/index.html.heex:86 +#: lib/claper_web/live/event_live/event_form_component.html.heex:291 +#: lib/claper_web/live/event_live/index.html.heex:83 #, elixir-autogen, elixir-format, fuzzy msgid "Name of your event" msgstr "Naam van je evenement" -#: lib/claper_web/live/event_live/event_form_component.html.heex:315 +#: lib/claper_web/live/event_live/event_form_component.html.heex:337 #, elixir-autogen, elixir-format, fuzzy msgid "Note: Facilitators do not have the ability to delete your event." msgstr "Let op: Facilitators hebben niet de mogelijkheid om je evenement te verwijderen." @@ -1155,12 +1164,12 @@ msgstr "Let op: Facilitators hebben niet de mogelijkheid om je evenement te verw msgid "Presentation file (optional)" msgstr "Presentatie (optioneel)" -#: lib/claper_web/live/event_live/index.html.heex:141 +#: lib/claper_web/live/event_live/index.html.heex:142 #, elixir-autogen, elixir-format msgid "Quick event" msgstr "Snel evenement" -#: lib/claper_web/live/event_live/index.ex:91 +#: lib/claper_web/live/event_live/index.ex:102 #, elixir-autogen, elixir-format msgid "Quick event created successfully" msgstr "Snel evenement succesvol aangemaakt" @@ -1170,7 +1179,7 @@ msgstr "Snel evenement succesvol aangemaakt" msgid "Return to your last event" msgstr "Keer terug naar je laatste evenement" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:317 #, elixir-autogen, elixir-format, fuzzy msgid "Select the start date for your event. Future dates are permissible." msgstr "Selecteer de startdatum voor het evenement. Toekomstige data zijn toegestaan." @@ -1180,22 +1189,22 @@ msgstr "Selecteer de startdatum voor het evenement. Toekomstige data zijn toeges msgid "Select your presentation (optional)" msgstr "Selecteer de presentatie (optioneel)" -#: lib/claper_web/live/event_live/event_form_component.html.heex:280 +#: lib/claper_web/live/event_live/event_form_component.html.heex:302 #, elixir-autogen, elixir-format, fuzzy msgid "This code will be used by your attendees to access the event. You have the option to create a custom code." msgstr "Deze code wordt door je bezoekers gebruikt om toegang te krijgen tot het evenement. Je hebt de mogelijkheid om een aangepaste code aan te maken." -#: lib/claper_web/live/event_live/show.ex:192 +#: lib/claper_web/live/event_live/show.ex:193 #, elixir-autogen, elixir-format msgid "This event has been terminated" msgstr "Dit evenement is gestopt" -#: lib/claper_web/live/event_live/index.html.heex:147 +#: lib/claper_web/live/event_live/index.html.heex:148 #, elixir-autogen, elixir-format, fuzzy msgid "Welcome to Claper! You can create a new event here." msgstr "Welkom bij Claper! Hier kun je een nieuw evenement aanmaken." -#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#: lib/claper_web/live/event_live/event_form_component.html.heex:326 #, elixir-autogen, elixir-format, fuzzy msgid "When your event will start?" msgstr "Wanneer begint het evenement?" @@ -1205,8 +1214,8 @@ msgstr "Wanneer begint het evenement?" msgid "Create your next presentation with" msgstr "Maak je volgende presentatie met" -#: lib/claper_web/live/event_live/manage.ex:27 -#: lib/claper_web/live/event_live/presenter.ex:24 +#: lib/claper_web/live/event_live/manage.ex:23 +#: lib/claper_web/live/event_live/presenter.ex:26 #: lib/claper_web/live/event_live/show.ex:25 #, elixir-autogen, elixir-format msgid "Event doesn't exist" @@ -1217,7 +1226,7 @@ msgstr "Evenement bestaat niet" msgid "Customize your account" msgstr "Pas je account aan" -#: lib/claper_web/live/user_settings_live/show.html.heex:265 +#: lib/claper_web/live/user_settings_live/show.html.heex:278 #, elixir-autogen, elixir-format msgid "Language" msgstr "Taal" @@ -1237,22 +1246,22 @@ msgstr "Je voorkeuren zijn bijgewerkt." msgid "Question" msgstr "Vraag" -#: lib/claper_web/live/event_live/manage.html.heex:1175 +#: lib/claper_web/live/event_live/manage.html.heex:1167 #, elixir-autogen, elixir-format msgid "Questions" msgstr "Vragen" -#: lib/claper_web/live/event_live/manage.html.heex:1262 +#: lib/claper_web/live/event_live/manage.html.heex:1254 #, elixir-autogen, elixir-format msgid "Questions will appear here." msgstr "Vragen zullen hier verschijnen" -#: lib/claper_web/live/event_live/manage.html.heex:1304 +#: lib/claper_web/live/event_live/manage.html.heex:1296 #, elixir-autogen, elixir-format msgid "Sort by date" msgstr "Sorteren op datum" -#: lib/claper_web/live/event_live/manage.html.heex:1283 +#: lib/claper_web/live/event_live/manage.html.heex:1275 #, elixir-autogen, elixir-format msgid "Sort by popularity" msgstr "Sorteer op populariteit" @@ -1262,7 +1271,8 @@ msgstr "Sorteer op populariteit" msgid "Event manager" msgstr "Evenementmanager" -#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#: lib/claper_web/templates/layout/_user_menu.html.heex:19 +#: lib/claper_web/templates/layout/admin.html.heex:262 #, elixir-autogen, elixir-format msgid "Documentation" msgstr "Documentatie" @@ -1278,7 +1288,7 @@ msgstr "Mijn account" msgid "Your personal informations to access your account" msgstr "Je persoonlijke gegevens om toegang te krijgen tot je account" -#: lib/claper_web/live/event_live/manager_settings_component.ex:533 +#: lib/claper_web/live/event_live/manager_settings_component.ex:589 #, elixir-autogen, elixir-format, fuzzy msgid "Enable reactions" msgstr "Schakel reacties in" @@ -1334,43 +1344,43 @@ msgid "Add Claper" msgstr "Voeg Claper toe" #: lib/claper_web/live/event_live/manage.html.heex:123 -#: lib/claper_web/live/event_live/manage.html.heex:539 +#: lib/claper_web/live/event_live/manage.html.heex:538 #, elixir-autogen, elixir-format msgid "Close preview" msgstr "Voorvertoning sluiten" -#: lib/claper_web/live/event_live/manage.html.heex:743 +#: lib/claper_web/live/event_live/manage.html.heex:734 #, elixir-autogen, elixir-format, fuzzy msgid "Create your first interaction." msgstr "Maak je eerste interactie aan" -#: lib/claper_web/live/event_live/manage.html.heex:1101 +#: lib/claper_web/live/event_live/manage.html.heex:1093 #, elixir-autogen, elixir-format, fuzzy msgid "Disable" msgstr "Uitschakelen" -#: lib/claper_web/live/event_live/manage.html.heex:1118 +#: lib/claper_web/live/event_live/manage.html.heex:1110 #, elixir-autogen, elixir-format msgid "Enable" msgstr "Inschakelen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:443 +#: lib/claper_web/live/event_live/manager_settings_component.ex:499 #, elixir-autogen, elixir-format, fuzzy msgid "Enable messages to change this option" msgstr "Schakel berichten in om deze optie te wijzigen" #: lib/claper_web/live/event_live/manage.html.heex:122 -#: lib/claper_web/live/event_live/manage.html.heex:538 +#: lib/claper_web/live/event_live/manage.html.heex:537 #, elixir-autogen, elixir-format msgid "Open preview" msgstr "Voorvertoning openen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:321 +#: lib/claper_web/live/event_live/manager_settings_component.ex:322 #, elixir-autogen, elixir-format msgid "Show messages to change this option" msgstr "Toon berichten om deze optie te wijzigen" -#: lib/claper_web/live/event_live/manage.html.heex:740 +#: lib/claper_web/live/event_live/manage.html.heex:731 #, elixir-autogen, elixir-format msgid "This slide does not have any interactions." msgstr "Deze dia heeft geen interacties." @@ -1397,7 +1407,7 @@ msgstr "Inloggen met %{provider}" msgid "The account has been unlinked." msgstr "Het account is ontkoppeld." -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "This section contains all your interactions." msgstr "Deze sectie bevat al uw interacties." @@ -1408,12 +1418,12 @@ msgstr "Deze sectie bevat al uw interacties." msgid "Unlink" msgstr "Losmaken" -#: lib/claper_web/live/event_live/manage.html.heex:716 +#: lib/claper_web/live/event_live/manage.html.heex:707 #, elixir-autogen, elixir-format msgid "You can add interactions to your presentation slides." msgstr "U kunt interacties toevoegen aan uw presentatiedia's." -#: lib/claper_web/live/event_live/manage.html.heex:715 +#: lib/claper_web/live/event_live/manage.html.heex:706 #, elixir-autogen, elixir-format msgid "Your interactions" msgstr "Uw interacties" @@ -1438,12 +1448,12 @@ msgstr "Stel een nieuw wachtwoord in voor uw account voordat u het ontkoppelt." msgid "Your password has been set, you can now unlink your account." msgstr "Uw wachtwoord is ingesteld, u kunt nu uw account ontkoppelen." -#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#: lib/claper_web/live/embed_live/form_component.html.heex:34 #, elixir-autogen, elixir-format msgid "Iframe code" msgstr "Iframe-code" -#: lib/claper_web/live/embed_live/form_component.html.heex:39 +#: lib/claper_web/live/embed_live/form_component.html.heex:35 #, elixir-autogen, elixir-format msgid "Link to the content" msgstr "Link naar de inhoud" @@ -1469,24 +1479,24 @@ msgstr "Voer een geldige link in die begint met http:// of https://" msgid "Please enter valid HTML content with an iframe tag" msgstr "Voer geldige HTML-inhoud in met een iframe-tag" -#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#: lib/claper_web/live/embed_live/form_component.html.heex:23 #, elixir-autogen, elixir-format msgid "Provider" msgstr "Aanbieder" -#: lib/claper_web/live/poll_live/form_component.html.heex:89 +#: lib/claper_web/live/poll_live/form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Attendees can see the results on their device" msgstr "Deelnemers kunnen de resultaten op hun apparaat zien" -#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/embed_live/form_component.html.heex:50 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees can view the web content on their device" msgstr "Deelnemers kunnen de webinhoud op hun apparaat bekijken" -#: lib/claper_web/live/embed_live/form_component.html.heex:49 -#: lib/claper_web/live/poll_live/form_component.html.heex:82 -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:172 +#: lib/claper_web/live/embed_live/form_component.html.heex:43 +#: lib/claper_web/live/poll_live/form_component.html.heex:78 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:166 #, elixir-autogen, elixir-format msgid "Options" msgstr "Opties" @@ -1554,12 +1564,12 @@ msgstr "Beëindigen" msgid "More options" msgstr "Meer opties" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "No" msgstr "Nee" -#: lib/claper_web/live/event_live/manage.ex:796 +#: lib/claper_web/live/event_live/manage.ex:818 #, elixir-autogen, elixir-format msgid "Yes" msgstr "Ja" @@ -1609,32 +1619,32 @@ msgstr "Je kunt je wachtwoord opnieuw instellen door de onderstaande URL te bezo msgid "back to the home page" msgstr "terug naar de startpagina" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:46 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:44 #, elixir-autogen, elixir-format, fuzzy msgid "Add Question" msgstr "Vraag toevoegen" -#: lib/claper_web/live/event_live/manage.html.heex:294 +#: lib/claper_web/live/event_live/manage.html.heex:293 #, elixir-autogen, elixir-format msgid "Add a quiz to test knowledge." msgstr "Voeg een quiz toe om kennis te testen." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:146 #, elixir-autogen, elixir-format msgid "Add answer" msgstr "Antwoord toevoegen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:482 +#: lib/claper_web/live/event_live/manager_settings_component.ex:538 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous messages" msgstr "Anonieme berichten toestaan" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:84 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:78 #, elixir-autogen, elixir-format msgid "Answer %{index}" msgstr "Antwoord %{index}" -#: lib/claper_web/live/event_live/manager_settings_component.ex:390 +#: lib/claper_web/live/event_live/manager_settings_component.ex:446 #, elixir-autogen, elixir-format, fuzzy msgid "Attendees" msgstr "Deelnemers" @@ -1650,32 +1660,32 @@ msgstr "Gemiddelde score" msgid "Current quiz" msgstr "Huidige quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:485 +#: lib/claper_web/live/event_live/manager_settings_component.ex:541 #, elixir-autogen, elixir-format, fuzzy msgid "Deny anonymous messages" msgstr "Anonieme berichten weigeren" -#: lib/claper_web/live/event_live/manager_settings_component.ex:427 +#: lib/claper_web/live/event_live/manager_settings_component.ex:483 #, elixir-autogen, elixir-format, fuzzy msgid "Disable messages" msgstr "Berichten uitschakelen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:536 +#: lib/claper_web/live/event_live/manager_settings_component.ex:592 #, elixir-autogen, elixir-format, fuzzy msgid "Disable reactions" msgstr "Reacties uitschakelen" -#: lib/claper_web/live/event_live/manage.html.heex:369 +#: lib/claper_web/live/event_live/manage.html.heex:368 #, elixir-autogen, elixir-format, fuzzy msgid "Edit quiz" msgstr "Quiz bewerken" -#: lib/claper_web/live/event_live/manager_settings_component.ex:258 +#: lib/claper_web/live/event_live/manager_settings_component.ex:259 #, elixir-autogen, elixir-format msgid "Hide instructions to join" msgstr "Instructies om deel te nemen verbergen" -#: lib/claper_web/live/event_live/manager_settings_component.ex:305 +#: lib/claper_web/live/event_live/manager_settings_component.ex:306 #, elixir-autogen, elixir-format, fuzzy msgid "Hide messages" msgstr "Berichten verbergen" @@ -1698,12 +1708,12 @@ msgstr "Hoe werkt het?" msgid "Interaction" msgstr "Interactie" -#: lib/claper_web/live/event_live/manage.html.heex:368 +#: lib/claper_web/live/event_live/manage.html.heex:367 #, elixir-autogen, elixir-format msgid "New quiz" msgstr "Nieuwe quiz" -#: lib/claper_web/live/event_live/manager_settings_component.ex:217 +#: lib/claper_web/live/event_live/manager_settings_component.ex:218 #, elixir-autogen, elixir-format, fuzzy msgid "Presentation" msgstr "Presentatie" @@ -1713,13 +1723,13 @@ msgstr "Presentatie" msgid "Previous" msgstr "Vorige" -#: lib/claper_web/live/event_live/manage.html.heex:292 -#: lib/claper_web/live/event_live/manage.html.heex:920 +#: lib/claper_web/live/event_live/manage.html.heex:291 +#: lib/claper_web/live/event_live/manage.html.heex:912 #, elixir-autogen, elixir-format msgid "Quiz" msgstr "Quiz" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:158 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:152 #, elixir-autogen, elixir-format msgid "Remove question" msgstr "Vraag verwijderen" @@ -1734,17 +1744,17 @@ msgstr "Neem de vragen door" msgid "See current quiz" msgstr "Bekijk huidige quiz" -#: lib/claper_web/live/event_live/manage.html.heex:388 +#: lib/claper_web/live/event_live/manage.html.heex:387 #, elixir-autogen, elixir-format, fuzzy msgid "Select presentation" msgstr "Selecteer presentatie" -#: lib/claper_web/live/event_live/manager_settings_component.ex:361 +#: lib/claper_web/live/event_live/manager_settings_component.ex:362 #, elixir-autogen, elixir-format, fuzzy msgid "Show all messages" msgstr "Toon alle berichten" -#: lib/claper_web/live/event_live/manager_settings_component.ex:255 +#: lib/claper_web/live/event_live/manager_settings_component.ex:256 #, elixir-autogen, elixir-format, fuzzy msgid "Show instructions to join" msgstr "Toon instructies om deel te nemen" @@ -1760,7 +1770,7 @@ msgstr "Toon resultaten" msgid "Show results on presentation" msgstr "Toon resultaten in presentatie" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:206 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:200 #, elixir-autogen, elixir-format, fuzzy msgid "This will delete all responses associated and the quiz itself, are you sure?" msgstr "Dit zal alle bijbehorende antwoorden en de quiz zelf verwijderen. Weet je het zeker?" @@ -1770,7 +1780,7 @@ msgstr "Dit zal alle bijbehorende antwoorden en de quiz zelf verwijderen. Weet j msgid "Waiting for results..." msgstr "Wachten op resultaten..." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:62 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:58 #, elixir-autogen, elixir-format msgid "Your question" msgstr "Jouw vraag" @@ -1788,7 +1798,7 @@ msgstr "Jouw score" msgid "Export" msgstr "Exporteren" -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:218 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:212 #, elixir-autogen, elixir-format msgid "Export to QTI (XML)" msgstr "Exporteren naar QTI (XML)" @@ -1848,17 +1858,21 @@ msgstr "Unieke deelnemers" msgid "Web Content" msgstr "Webinhoud" -#: lib/claper_web/live/event_live/index.html.heex:178 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:127 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:131 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:286 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:135 +#: lib/claper_web/live/event_live/index.html.heex:179 #, elixir-autogen, elixir-format msgid "Active" msgstr "Actief" -#: lib/claper_web/live/event_live/index.html.heex:217 +#: lib/claper_web/live/event_live/index.html.heex:218 #, elixir-autogen, elixir-format msgid "Load more" msgstr "Meer laden" -#: lib/claper_web/live/event_live/index.html.heex:194 +#: lib/claper_web/live/event_live/index.html.heex:195 #, elixir-autogen, elixir-format msgid "Shared with you" msgstr "Gedeeld met jou" @@ -1868,17 +1882,17 @@ msgstr "Gedeeld met jou" msgid "You must login to continue" msgstr "Je moet inloggen om door te gaan" -#: lib/claper/quizzes/quiz_question.ex:41 +#: lib/claper/quizzes/quiz_question.ex:51 #, elixir-autogen, elixir-format msgid "must have at least one correct answer" msgstr "moet minimaal een correcte antwoord hebben" -#: lib/claper_web/live/event_live/manage.html.heex:548 +#: lib/claper_web/live/event_live/manage.html.heex:547 #, elixir-autogen, elixir-format msgid "Click here to open the presentation window. Press F in the presentation window to enable fullscreen." msgstr "Klik hier om de presentatievenster te openen. Druk F in de presentatievenster om de volledig schermmodus te activeren." -#: lib/claper_web/live/quiz_live/quiz_component.html.heex:179 +#: lib/claper_web/live/quiz_live/quiz_component.html.heex:173 #, elixir-autogen, elixir-format, fuzzy msgid "Allow anonymous submissions" msgstr "Anonieme inzendingen toestaan" @@ -1897,3 +1911,771 @@ msgstr "Inloggen" #, elixir-autogen, elixir-format msgid "Total submissions" msgstr "Totaal aantal inzendingen" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "A unique code for participants to join this event" +msgstr "Een unieke code voor deelnemers om aan dit evenement deel te nemen" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:23 +#, elixir-autogen, elixir-format +msgid "A unique name for this event" +msgstr "Een unieke naam voor dit evenement" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:28 +#, elixir-autogen, elixir-format +msgid "A unique name to identify this OIDC provider" +msgstr "Een unieke naam om deze OIDC-aanbieder te identificeren" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Account is confirmed and active" +msgstr "Account is bevestigd en actief" + +#: lib/claper_web/live/admin_live/event_live.html.heex:126 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:108 +#: lib/claper_web/live/admin_live/user_live.html.heex:111 +#, elixir-autogen, elixir-format, fuzzy +msgid "Actions" +msgstr "Opties" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Active Events" +msgstr "Actieve evenementen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:216 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this event?" +msgstr "Weet u zeker dat u dit evenement wilt verwijderen?" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this provider?" +msgstr "Weet u zeker dat u deze aanbieder wilt verwijderen?" + +#: lib/claper_web/live/admin_live/user_live.html.heex:197 +#, elixir-autogen, elixir-format, fuzzy +msgid "Are you sure you want to delete this user?" +msgstr "Weet u zeker dat u deze gebruiker wilt verwijderen?" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:68 +#, elixir-autogen, elixir-format +msgid "Assigned User" +msgstr "Toegewezen gebruiker" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:110 +#: lib/claper_web/live/admin_live/event_live.html.heex:119 +#: lib/claper_web/live/admin_live/event_live.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Audience Peak" +msgstr "Publiekspiek" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:103 +#, elixir-autogen, elixir-format +msgid "Authorization Code" +msgstr "Autorisatiecode" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:80 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:147 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:72 +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "Annuleren" + +#: lib/claper_web/live/admin_live/form_field_component.ex:112 +#, elixir-autogen, elixir-format, fuzzy +msgid "Choose file" +msgstr "Bestand kiezen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:264 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Client ID" +msgstr "Client-ID" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:62 +#, elixir-autogen, elixir-format +msgid "Client Secret" +msgstr "Client-geheim" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:121 +#, elixir-autogen, elixir-format +msgid "Completed" +msgstr "Voltooid" + +#: lib/claper_web/live/admin_live/user_live.html.heex:134 +#: lib/claper_web/live/admin_live/user_live.html.heex:268 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirmed" +msgstr "Bevestigd" + +#: lib/claper_web/live/admin_live/user_live.html.heex:291 +#, elixir-autogen, elixir-format +msgid "Confirmed At" +msgstr "Bevestigd op" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create Event" +msgstr "Evenement aanmaken" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Create Provider" +msgstr "Aanbieder aanmaken" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create User" +msgstr "Gebruiker aanmaken" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:101 +#: lib/claper_web/live/admin_live/user_live.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created" +msgstr "Aangemaakt" + +#: lib/claper_web/live/admin_live/event_live.html.heex:305 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:296 +#: lib/claper_web/live/admin_live/user_live.html.heex:278 +#, elixir-autogen, elixir-format, fuzzy +msgid "Created At" +msgstr "Aangemaakt op" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Currently running" +msgstr "Momenteel actief" + +#: lib/claper_web/live/admin_live/event_live.html.heex:219 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete event" +msgstr "Evenement verwijderen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:197 +#, elixir-autogen, elixir-format +msgid "Delete provider" +msgstr "Aanbieder verwijderen" + +#: lib/claper_web/live/admin_live/user_live.html.heex:200 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete user" +msgstr "Gebruiker verwijderen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:339 +#, elixir-autogen, elixir-format +msgid "Edit OIDC Provider" +msgstr "OIDC-aanbieder bewerken" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:176 +#: lib/claper_web/live/admin_live/event_live.ex:41 +#: lib/claper_web/live/admin_live/event_live.html.heex:194 +#: lib/claper_web/live/admin_live/event_live.html.heex:348 +#: lib/claper_web/live/admin_live/event_live.html.heex:358 +#, elixir-autogen, elixir-format +msgid "Edit event" +msgstr "Evenement bewerken" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:46 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:172 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:349 +#, elixir-autogen, elixir-format +msgid "Edit provider" +msgstr "Aanbieder bewerken" + +#: lib/claper_web/live/admin_live/user_live.ex:42 +#: lib/claper_web/live/admin_live/user_live.html.heex:175 +#: lib/claper_web/live/admin_live/user_live.html.heex:329 +#: lib/claper_web/live/admin_live/user_live.html.heex:339 +#, elixir-autogen, elixir-format, fuzzy +msgid "Edit user" +msgstr "Gebruiker bewerken" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:136 +#, elixir-autogen, elixir-format +msgid "Enable this OIDC provider" +msgstr "Deze OIDC-aanbieder inschakelen" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Enter client ID" +msgstr "Voer client-ID in" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:63 +#, elixir-autogen, elixir-format +msgid "Enter client secret" +msgstr "Voer client-geheim in" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:33 +#, elixir-autogen, elixir-format +msgid "Enter event code" +msgstr "Voer evenementcode in" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:20 +#, elixir-autogen, elixir-format +msgid "Enter event name" +msgstr "Voer evenementnaam in" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:33 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enter password" +msgstr "Voer wachtwoord in" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:25 +#, elixir-autogen, elixir-format +msgid "Enter provider name" +msgstr "Voer aanbieder naam in" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:19 +#, elixir-autogen, elixir-format +msgid "Enter user email" +msgstr "Voer gebruiker e-mail in" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:81 +#, elixir-autogen, elixir-format +msgid "Event Creation" +msgstr "Evenement aanmaken" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:147 +#, elixir-autogen, elixir-format +msgid "Event created successfully" +msgstr "Evenement succesvol aangemaakt" + +#: lib/claper_web/live/admin_live/event_live.ex:58 +#: lib/claper_web/live/admin_live/event_live.ex:110 +#, elixir-autogen, elixir-format +msgid "Event deleted successfully" +msgstr "Evenement succesvol verwijderd" + +#: lib/claper_web/live/admin_live/event_live.ex:47 +#: lib/claper_web/live/admin_live/event_live.html.heex:253 +#, elixir-autogen, elixir-format +msgid "Event details" +msgstr "Evenement details" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:132 +#, elixir-autogen, elixir-format +msgid "Event updated successfully" +msgstr "Evenement succesvol bijgewerkt" + +#: lib/claper_web/live/admin_live/event_live.ex:16 +#: lib/claper_web/live/admin_live/event_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:214 +#, elixir-autogen, elixir-format, fuzzy +msgid "Events" +msgstr "Evenementen" + +#: lib/claper_web/live/admin_live/event_live.ex:92 +#, elixir-autogen, elixir-format +msgid "Events exported successfully" +msgstr "Evenementen succesvol geëxporteerd" + +#: lib/claper_web/live/admin_live/event_live.html.heex:107 +#: lib/claper_web/live/admin_live/event_live.html.heex:291 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:57 +#, elixir-autogen, elixir-format +msgid "Expired At" +msgstr "Verloopt op" + +#: lib/claper_web/live/admin_live/form_field_component.ex:177 +#, elixir-autogen, elixir-format +msgid "File selected" +msgstr "Bestand geselecteerd" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:121 +#, elixir-autogen, elixir-format, fuzzy +msgid "Form Post" +msgstr "Form Post" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:120 +#, elixir-autogen, elixir-format +msgid "Fragment" +msgstr "Fragment" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:125 +#, elixir-autogen, elixir-format +msgid "How the authorization response should be returned (defaults to 'query')" +msgstr "Hoe de autorisatie reactie moet worden geretourneerd (standaard 'query')" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:105 +#, elixir-autogen, elixir-format +msgid "Hybrid" +msgstr "Hybride" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:104 +#, elixir-autogen, elixir-format +msgid "Implicit" +msgstr "Impliciet" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:135 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:290 +#, elixir-autogen, elixir-format, fuzzy +msgid "Inactive" +msgstr "Inactief" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:36 +#, elixir-autogen, elixir-format +msgid "Initial password for the user" +msgstr "Initieel wachtwoord voor de gebruiker" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:83 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:258 +#, elixir-autogen, elixir-format +msgid "Issuer" +msgstr "Uitgever" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:37 +#, elixir-autogen, elixir-format +msgid "Issuer URL" +msgstr "Uitgever URL" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:66 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:82 +#, elixir-autogen, elixir-format +msgid "Last 30 days" +msgstr "Laatste 30 dagen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:311 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:302 +#: lib/claper_web/live/admin_live/user_live.html.heex:284 +#, elixir-autogen, elixir-format +msgid "Last Updated" +msgstr "Laatst bijgewerkt" + +#: lib/claper_web/live/admin_live/event_live.ex:35 +#: lib/claper_web/live/admin_live/event_live.html.heex:325 +#: lib/claper_web/live/admin_live/event_live.html.heex:335 +#, elixir-autogen, elixir-format +msgid "New event" +msgstr "Nieuw evenement" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:201 +#: lib/claper_web/live/admin_live/event_live.html.heex:134 +#, elixir-autogen, elixir-format +msgid "No events found" +msgstr "Geen evenementen gevonden" + +#: lib/claper_web/live/admin_live/form_field_component.ex:125 +#, elixir-autogen, elixir-format +msgid "No file chosen" +msgstr "Geen bestand gekozen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:147 +#: lib/claper_web/live/admin_live/event_live.html.heex:279 +#, elixir-autogen, elixir-format +msgid "No owner" +msgstr "Geen eigenaar" + +#: lib/claper_web/live/admin_live/user_live.html.heex:129 +#: lib/claper_web/live/admin_live/user_live.html.heex:260 +#, elixir-autogen, elixir-format +msgid "No role" +msgstr "Geen rol" + +#: lib/claper_web/live/admin_live/user_live.html.heex:119 +#, elixir-autogen, elixir-format +msgid "No users found" +msgstr "Geen gebruikers gevonden" + +#: lib/claper_web/live/admin_live/event_live.html.heex:157 +#: lib/claper_web/live/admin_live/event_live.html.heex:295 +#, elixir-autogen, elixir-format +msgid "Not expired" +msgstr "Niet verlopen" + +#: lib/claper_web/live/admin_live/event_live.html.heex:152 +#: lib/claper_web/live/admin_live/event_live.html.heex:287 +#, elixir-autogen, elixir-format +msgid "Not started" +msgstr "Niet gestart" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:108 +#, elixir-autogen, elixir-format +msgid "OAuth 2.0 response type (defaults to 'code')" +msgstr "OAuth 2.0 reactie type (standaard 'code')" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:250 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Provider" +msgstr "OIDC-aanbieder" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:231 +#, elixir-autogen, elixir-format +msgid "OIDC Provider details" +msgstr "OIDC-aanbieder details" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:15 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:6 +#, elixir-autogen, elixir-format, fuzzy +msgid "OIDC Providers" +msgstr "OIDC-aanbieders" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:92 +#, elixir-autogen, elixir-format +msgid "OIDC scopes to request (defaults to 'openid email profile')" +msgstr "OIDC scopes om aan te vragen (standaard 'openid email profile')" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:108 +#: lib/claper_web/live/admin_live/event_live.html.heex:87 +#: lib/claper_web/live/admin_live/event_live.html.heex:277 +#, elixir-autogen, elixir-format +msgid "Owner" +msgstr "Eigenaar" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:209 +#, elixir-autogen, elixir-format +msgid "Provider created successfully" +msgstr "Aanbieder succesvol aangemaakt" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:194 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider updated successfully" +msgstr "Aanbieder succesvol bijgewerkt" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:119 +#, elixir-autogen, elixir-format +msgid "Query" +msgstr "Query" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:100 +#, elixir-autogen, elixir-format +msgid "Recent Events" +msgstr "Recente evenementen" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Redirect URI" +msgstr "Redirect URI" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:117 +#, elixir-autogen, elixir-format +msgid "Response Mode" +msgstr "Reactiemodus" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:270 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:101 +#, elixir-autogen, elixir-format +msgid "Response Type" +msgstr "Reactietype" + +#: lib/claper_web/live/admin_live/user_live.html.heex:83 +#: lib/claper_web/live/admin_live/user_live.html.heex:258 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Role" +msgstr "Rol" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:82 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:149 +#: lib/claper_web/live/admin_live/user_live/form_component.ex:74 +#, elixir-autogen, elixir-format +msgid "Saving..." +msgstr "Opslaan..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:124 +#, elixir-autogen, elixir-format +msgid "Scheduled" +msgstr "Gepland" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:276 +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:89 +#, elixir-autogen, elixir-format +msgid "Scope" +msgstr "Scope" + +#: lib/claper_web/live/admin_live/event_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search events..." +msgstr "Zoek evenementen..." + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:70 +#, elixir-autogen, elixir-format +msgid "Search for a user..." +msgstr "Zoek naar een gebruiker..." + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search providers..." +msgstr "Zoek aanbieders..." + +#: lib/claper_web/live/admin_live/user_live.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Search users..." +msgstr "Zoek gebruikers..." + +#: lib/claper_web/live/admin_live/form_field_component.ex:71 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select an option" +msgstr "Selecteer een optie" + +#: lib/claper_web/live/admin_live/searchable_select_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Select..." +msgstr "Selecteer..." + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:109 +#, elixir-autogen, elixir-format +msgid "Start Date" +msgstr "Startdatum" + +#: lib/claper_web/live/admin_live/event_live.html.heex:95 +#: lib/claper_web/live/admin_live/event_live.html.heex:283 +#: lib/claper_web/live/admin_live/event_live/form_component.ex:46 +#, elixir-autogen, elixir-format +msgid "Started At" +msgstr "Gestart op" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:111 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:92 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:282 +#: lib/claper_web/live/admin_live/user_live.html.heex:92 +#: lib/claper_web/live/admin_live/user_live.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Status" +msgstr "Status" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:41 +#, elixir-autogen, elixir-format +msgid "The OIDC issuer URL (must start with http:// or https://)" +msgstr "De OIDC-uitgever URL (moet beginnen met http:// of https://)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:79 +#, elixir-autogen, elixir-format +msgid "The callback URL for your application (must start with http:// or https://)" +msgstr "De callback URL voor uw applicatie (moet beginnen met http:// of https://)" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:73 +#, elixir-autogen, elixir-format +msgid "The user who owns this event (required)" +msgstr "De gebruiker die eigenaar is van dit evenement (verplicht)" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:33 +#, elixir-autogen, elixir-format +msgid "Total Events" +msgstr "Totaal evenementen" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:11 +#, elixir-autogen, elixir-format +msgid "Total Users" +msgstr "Totaal gebruikers" + +#: lib/claper_web/live/admin_live/user_live.html.heex:138 +#: lib/claper_web/live/admin_live/user_live.html.heex:272 +#, elixir-autogen, elixir-format +msgid "Unconfirmed" +msgstr "Niet bevestigd" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:83 +#, elixir-autogen, elixir-format +msgid "Update Event" +msgstr "Evenement bijwerken" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:150 +#, elixir-autogen, elixir-format +msgid "Update Provider" +msgstr "Aanbieder bijwerken" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "Update User" +msgstr "Gebruiker bijwerken" + +#: lib/claper_web/live/admin_live/user_live.html.heex:250 +#, elixir-autogen, elixir-format +msgid "User Account" +msgstr "Gebruikersaccount" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:65 +#, elixir-autogen, elixir-format +msgid "User Growth" +msgstr "Gebruikersgroei" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:165 +#, elixir-autogen, elixir-format +msgid "User created successfully" +msgstr "Gebruiker succesvol aangemaakt" + +#: lib/claper_web/live/admin_live/user_live.ex:59 +#: lib/claper_web/live/admin_live/user_live.ex:127 +#, elixir-autogen, elixir-format +msgid "User deleted successfully" +msgstr "Gebruiker succesvol verwijderd" + +#: lib/claper_web/live/admin_live/user_live.ex:48 +#: lib/claper_web/live/admin_live/user_live.html.heex:234 +#, elixir-autogen, elixir-format +msgid "User details" +msgstr "Gebruiker details" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:150 +#, elixir-autogen, elixir-format, fuzzy +msgid "User updated successfully" +msgstr "Gebruiker succesvol bijgewerkt" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:50 +#, elixir-autogen, elixir-format +msgid "User's access level" +msgstr "Toegangsniveau van gebruiker" + +#: lib/claper_web/live/admin_live/user_live/form_component.ex:22 +#, elixir-autogen, elixir-format +msgid "User's email address (must be unique)" +msgstr "E-mailadres van gebruiker (moet uniek zijn)" + +#: lib/claper_web/live/admin_live/user_live.ex:17 +#: lib/claper_web/live/admin_live/user_live.html.heex:6 +#: lib/claper_web/templates/layout/admin.html.heex:230 +#, elixir-autogen, elixir-format +msgid "Users" +msgstr "Gebruikers" + +#: lib/claper_web/live/admin_live/user_live.ex:97 +#, elixir-autogen, elixir-format +msgid "Users exported successfully" +msgstr "Gebruikers succesvol geëxporteerd" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:151 +#: lib/claper_web/live/admin_live/event_live.html.heex:169 +#, elixir-autogen, elixir-format +msgid "View event" +msgstr "Evenement bekijken" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:147 +#, elixir-autogen, elixir-format, fuzzy +msgid "View provider" +msgstr "Aanbieder bekijken" + +#: lib/claper_web/live/admin_live/user_live.html.heex:150 +#, elixir-autogen, elixir-format +msgid "View user" +msgstr "Gebruiker bekijken" + +#: lib/claper_web/live/admin_live/event_live/form_component.ex:60 +#, elixir-autogen, elixir-format +msgid "When this event expires (optional)" +msgstr "Wanneer dit evenement verloopt (optioneel)" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:139 +#, elixir-autogen, elixir-format +msgid "Whether this provider is currently active and available for authentication" +msgstr "Of deze aanbieder momenteel actief is en beschikbaar voor authenticatie" + +#: lib/claper_web/live/admin_live/event_live.html.heex:301 +#, elixir-autogen, elixir-format, fuzzy +msgid "attendees" +msgstr "deelnemers" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:38 +#, elixir-autogen, elixir-format +msgid "https://example.com" +msgstr "https://example.com" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:75 +#, elixir-autogen, elixir-format +msgid "https://yourapp.com/auth/callback" +msgstr "https://yourapp.com/auth/callback" + +#: lib/claper_web/live/admin_live/oidc_provider_live/form_component.ex:90 +#, elixir-autogen, elixir-format +msgid "openid email profile" +msgstr "openid email profile" + +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:28 +#: lib/claper_web/live/admin_live/dashboard_live.html.heex:50 +#, elixir-autogen, elixir-format +msgid "vs last month" +msgstr "vs vorige maand" + +#: lib/claper_web/live/admin_live/event_live.html.heex:256 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to events" +msgstr "Terug naar evenementen" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:234 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to providers" +msgstr "Terug naar aanbieders" + +#: lib/claper_web/live/admin_live/user_live.html.heex:237 +#, elixir-autogen, elixir-format, fuzzy +msgid "Back to users" +msgstr "Terug naar gebruikers" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:40 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:23 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:316 +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "New provider" +msgstr "Nieuwe aanbieder" + +#: lib/claper_web/live/admin_live/user_live.ex:36 +#: lib/claper_web/live/admin_live/user_live.html.heex:306 +#: lib/claper_web/live/admin_live/user_live.html.heex:316 +#, elixir-autogen, elixir-format, fuzzy +msgid "New user" +msgstr "Nieuwe gebruiker" + +#: lib/claper_web/live/admin_live/oidc_provider_live.html.heex:116 +#, elixir-autogen, elixir-format, fuzzy +msgid "No providers found" +msgstr "Geen aanbieders gevonden" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider deleted successfully" +msgstr "Aanbieder succesvol verwijderd" + +#: lib/claper_web/live/admin_live/oidc_provider_live.ex:34 +#, elixir-autogen, elixir-format, fuzzy +msgid "Provider details" +msgstr "Aanbieder details" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:13 +#: lib/claper_web/templates/layout/admin.html.heex:44 +#: lib/claper_web/templates/layout/admin.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Admin" +msgstr "Admin" + +#: lib/claper_web/templates/layout/admin.html.heex:285 +#, elixir-autogen, elixir-format +msgid "Back to app" +msgstr "Terug naar app" + +#: lib/claper_web/templates/user_notifier/change.html.heex:17 +#, elixir-autogen, elixir-format, fuzzy +msgid "Confirm email change" +msgstr "Bevestig e-mail" + +#: lib/claper_web/templates/user_notifier/change.html.heex:32 +#, elixir-autogen, elixir-format, fuzzy +msgid "If you didn't request an email change, please ignore this." +msgstr "Als je geen account bij ons hebt aangemaakt, kun je dit negeren." + +#: lib/claper_web/templates/user_notifier/change.html.heex:22 +#, elixir-autogen, elixir-format, fuzzy +msgid "You can confirm your email change by visiting the URL below" +msgstr "Je kunt het e-mailadres wijzigen door naar de onderstaande URL te gaan" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:416 +#, elixir-autogen, elixir-format +msgid "Hide attendee count" +msgstr "Aantal deelnemers verbergen" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:413 +#, elixir-autogen, elixir-format, fuzzy +msgid "Show attendee count" +msgstr "Aantal deelnemers weergeven" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Required" +msgstr "Verplicht" + +#: lib/claper_web/views/components/input_component.ex:16 +#: lib/claper_web/views/components/input_component.ex:295 +#, elixir-autogen, elixir-format +msgid "(optional)" +msgstr "(optioneel)" diff --git a/priv/repo/migrations/20250711135508_create_roles.exs b/priv/repo/migrations/20250711135508_create_roles.exs new file mode 100644 index 0000000..c71b1be --- /dev/null +++ b/priv/repo/migrations/20250711135508_create_roles.exs @@ -0,0 +1,14 @@ +defmodule Claper.Repo.Migrations.CreateRoles do + use Ecto.Migration + + def change do + create table(:roles) do + add :name, :string, null: false + add :permissions, :map, default: %{} + + timestamps() + end + + create unique_index(:roles, [:name]) + end +end diff --git a/priv/repo/migrations/20250711135909_add_role_id_to_users.exs b/priv/repo/migrations/20250711135909_add_role_id_to_users.exs new file mode 100644 index 0000000..cdc490f --- /dev/null +++ b/priv/repo/migrations/20250711135909_add_role_id_to_users.exs @@ -0,0 +1,11 @@ +defmodule Claper.Repo.Migrations.AddRoleIdToUsers do + use Ecto.Migration + + def change do + alter table(:users) do + add :role_id, references(:roles, on_delete: :nilify_all), null: true + end + + create index(:users, [:role_id]) + end +end diff --git a/priv/repo/migrations/20250711164053_create_oidc_providers.exs b/priv/repo/migrations/20250711164053_create_oidc_providers.exs new file mode 100644 index 0000000..ac78786 --- /dev/null +++ b/priv/repo/migrations/20250711164053_create_oidc_providers.exs @@ -0,0 +1,22 @@ +defmodule Claper.Repo.Migrations.CreateOidcProviders do + use Ecto.Migration + + def change do + create table(:oidc_providers) do + add :name, :string, null: false + add :issuer, :string, null: false + add :client_id, :string, null: false + add :client_secret, :string, null: false + add :redirect_uri, :string, null: false + add :response_type, :string, default: "code" + add :response_mode, :string + add :scope, :string, default: "openid email profile" + add :active, :boolean, default: true + + timestamps() + end + + create index(:oidc_providers, [:name]) + create unique_index(:oidc_providers, [:issuer]) + end +end diff --git a/priv/repo/migrations/20251020162958_add_show_attendee_count_presentation_state.exs b/priv/repo/migrations/20251020162958_add_show_attendee_count_presentation_state.exs new file mode 100644 index 0000000..d170ea9 --- /dev/null +++ b/priv/repo/migrations/20251020162958_add_show_attendee_count_presentation_state.exs @@ -0,0 +1,9 @@ +defmodule Claper.Repo.Migrations.AddShowAttendeeCountPresentationState do + use Ecto.Migration + + def change do + alter table(:presentation_states) do + add :show_attendee_count, :boolean, default: true + end + end +end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 6f5248c..fb29d07 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -10,6 +10,26 @@ # We recommend using the bang functions (`insert!`, `update!` # and so on) as they will fail if something goes wrong. +# Create roles if they don't exist +alias Claper.Accounts.Role +alias Claper.Repo + +# Create admin role if it doesn't exist +if !Repo.get_by(Role, name: "admin") do + %Role{name: "admin", permissions: %{"all" => true}} + |> Repo.insert!() + + IO.puts("Created admin role") +end + +# Create user role if it doesn't exist +if !Repo.get_by(Role, name: "user") do + %Role{name: "user", permissions: %{}} + |> Repo.insert!() + + IO.puts("Created user role") +end + # create a default active lti_1p3 jwk if !Claper.Repo.get_by(Lti13.Jwks.Jwk, id: 1) do %{private_key: private_key} = Lti13.Jwks.Utils.KeyGenerator.generate_key_pair() @@ -22,3 +42,29 @@ if !Claper.Repo.get_by(Lti13.Jwks.Jwk, id: 1) do active: true }) end + +# Create default admin user if no users exist +alias Claper.Accounts +alias Claper.Accounts.User + +if Repo.aggregate(User, :count, :id) == 0 do + admin_role = Repo.get_by(Role, name: "admin") + + if admin_role do + {:ok, admin_user} = + Accounts.register_user(%{ + email: "admin@claper.co", + password: "claper", + confirmed_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) + }) + + Accounts.assign_role(admin_user, admin_role) + + IO.puts("Created default admin user:") + IO.puts(" Email: admin@claper.co") + IO.puts(" Password: claper") + IO.puts(" IMPORTANT: Please change this password after first login!") + else + IO.puts("Warning: Admin role not found, skipping default admin user creation") + end +end diff --git a/priv/static/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf b/priv/static/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf new file mode 100644 index 0000000..9f89c9d Binary files /dev/null and b/priv/static/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf differ diff --git a/priv/static/fonts/Montserrat/Montserrat-VariableFont_wght.ttf b/priv/static/fonts/Montserrat/Montserrat-VariableFont_wght.ttf new file mode 100644 index 0000000..df7379c Binary files /dev/null and b/priv/static/fonts/Montserrat/Montserrat-VariableFont_wght.ttf differ diff --git a/reset-db.sh b/reset-db.sh deleted file mode 100755 index b7cba8e..0000000 --- a/reset-db.sh +++ /dev/null @@ -1,6 +0,0 @@ -docker stop claper-db -docker rm claper-db -docker run -p 5432:5432 -e POSTGRES_PASSWORD=claper -e POSTGRES_USER=claper -e POSTGRES_DB=claper --name claper-db -d postgres:15 -sleep 5 -mix ecto.migrate -mix run priv/repo/seeds.exs \ No newline at end of file diff --git a/test/claper/accounts/role_test.exs b/test/claper/accounts/role_test.exs new file mode 100644 index 0000000..ccda407 --- /dev/null +++ b/test/claper/accounts/role_test.exs @@ -0,0 +1,133 @@ +defmodule Claper.Accounts.RoleTest do + use Claper.DataCase + + alias Claper.Accounts + alias Claper.Accounts.{User, Role} + alias Claper.Repo + + describe "roles" do + setup do + # Ensure admin and user roles exist + {:ok, _admin_role} = Accounts.create_role(%{name: "admin"}) + {:ok, _user_role} = Accounts.create_role(%{name: "user"}) + :ok + end + + test "list_roles/0 returns all roles" do + roles = Accounts.list_roles() + assert length(roles) == 2 + assert Enum.any?(roles, fn r -> r.name == "admin" end) + assert Enum.any?(roles, fn r -> r.name == "user" end) + end + + test "get_role!/1 returns the role with given id" do + role = Repo.get_by(Role, name: "admin") + assert Accounts.get_role!(role.id).name == "admin" + end + + test "get_role_by_name/1 returns the role with given name" do + assert Accounts.get_role_by_name("admin").name == "admin" + assert Accounts.get_role_by_name("user").name == "user" + assert Accounts.get_role_by_name("nonexistent") == nil + end + + test "create_role/1 with valid data creates a role" do + assert {:ok, %Role{} = role} = Accounts.create_role(%{name: "moderator"}) + assert role.name == "moderator" + end + + test "create_role/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Accounts.create_role(%{name: nil}) + end + end + + describe "user role management" do + setup do + # Ensure admin and user roles exist + {:ok, admin_role} = Accounts.create_role(%{name: "admin"}) + {:ok, user_role} = Accounts.create_role(%{name: "user"}) + + # Create a test user + {:ok, user} = Accounts.create_user(%{email: "test@example.com", password: "Password123!"}) + + %{user: user, admin_role: admin_role, user_role: user_role} + end + + test "assign_role/2 assigns a role to a user", %{user: user, admin_role: admin_role} do + assert {:ok, updated_user} = Accounts.assign_role(user, admin_role) + assert updated_user.role_id == admin_role.id + + # Verify through a fresh database query + fresh_user = Repo.get(User, user.id) |> Repo.preload(:role) + assert fresh_user.role.name == "admin" + end + + test "get_user_role/1 returns the role of a user", %{user: user, user_role: user_role} do + # Assign a role first + {:ok, user} = Accounts.assign_role(user, user_role) + + # Test getting the role + role = Accounts.get_user_role(user) + assert role.id == user_role.id + assert role.name == "user" + end + + test "list_users_by_role/1 returns users with a specific role", %{ + user: user, + admin_role: admin_role + } do + # Create another user with a different role + {:ok, user2} = + Accounts.create_user(%{email: "another@example.com", password: "Password123!"}) + + {:ok, _} = Accounts.assign_role(user, admin_role) + + # Get users with admin role + admin_users = Accounts.list_users_by_role("admin") + assert length(admin_users) == 1 + assert hd(admin_users).id == user.id + + # Verify user2 is not in the list + assert user2.id not in Enum.map(admin_users, & &1.id) + end + + test "user_has_role?/2 checks if a user has a specific role", %{ + user: user, + admin_role: admin_role + } do + # Initially user has no role + refute Accounts.user_has_role?(user, "admin") + + # Assign admin role + {:ok, user} = Accounts.assign_role(user, admin_role) + + # Now user should have admin role + assert Accounts.user_has_role?(user, "admin") + refute Accounts.user_has_role?(user, "user") + end + + test "promote_to_admin/1 promotes a user to admin", %{user: user} do + # Initially user should not be admin + refute Accounts.user_has_role?(user, "admin") + + # Promote to admin + {:ok, user} = Accounts.promote_to_admin(user) + + # Verify promotion + assert Accounts.user_has_role?(user, "admin") + end + + test "demote_from_admin/1 demotes a user from admin", %{user: user} do + # First promote to admin + {:ok, user} = Accounts.promote_to_admin(user) + assert Accounts.user_has_role?(user, "admin") + + # Then demote + {:ok, user} = Accounts.demote_from_admin(user) + + # Verify demotion + refute Accounts.user_has_role?(user, "admin") + assert Accounts.user_has_role?(user, "user") + end + end +end diff --git a/test/claper/embeds_test.exs b/test/claper/embeds_test.exs index d6fde8c..c026bf7 100644 --- a/test/claper/embeds_test.exs +++ b/test/claper/embeds_test.exs @@ -75,15 +75,17 @@ defmodule Claper.EmbedsTest do "https://youtu.be/dQw4w9WgXcQ?si=g1A6ZegIXzcrisSw" end - test "create_embed/1 with invalid data creates a youtube embed" do + test "create_embed/1 with invalid youtube URL returns error" do presentation_file = presentation_file_fixture() attrs = %{ title: "some title", - content: "https://youtube.com/dQw4w9WgXcQ?si=g1A6ZegIXzcrisSw", + # Wrong provider URL for youtube + content: "https://vimeo.com/123456", provider: "youtube", presentation_file_id: presentation_file.id, - position: 0 + position: 0, + attendee_visibility: false } assert {:error, %Ecto.Changeset{}} = Embeds.create_embed(attrs) diff --git a/test/claper/events_test.exs b/test/claper/events_test.exs index a8c19f4..736053c 100644 --- a/test/claper/events_test.exs +++ b/test/claper/events_test.exs @@ -2,6 +2,7 @@ defmodule Claper.EventsTest do use Claper.DataCase alias Claper.Events + alias Claper.Events.{Event, ActivityLeader} import Claper.{ EventsFixtures, @@ -12,70 +13,423 @@ defmodule Claper.EventsTest do EmbedsFixtures } - describe "events" do - alias Claper.Events.Event + setup_all do + sandbox_owner_pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Claper.Repo, shared: true) + on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(sandbox_owner_pid) end) - @invalid_attrs %{name: nil, code: nil} + alice = user_fixture(%{email: "alice@example.com"}) + bob = user_fixture(%{email: "bob@example.com"}) + carol = user_fixture(%{email: "carol@example.com"}) - test "list_events/1 returns all events of a user" do - event = event_fixture() - assert Events.list_events(event.user_id) == [event] + now = NaiveDateTime.utc_now() + + alice_active_events = + for _ <- 1..12 do + event_fixture(%{user: alice}) + end + + alice_expired_events = [] + + bob_active_events = [] + + bob_expired_events = + for i <- 1..12 do + event_fixture(%{user: bob, expired_at: NaiveDateTime.add(now, i - 1, :hour)}) + end + + carol_active_events = + for _ <- 1..6 do + event = + event_fixture(%{user: carol}) + + activity_leader_fixture(%{event: event, user: alice}) + event + end + + carol_expired_events = + for i <- 1..6 do + event = + event_fixture(%{user: carol, expired_at: NaiveDateTime.add(now, i - 1, :hour)}) + + activity_leader_fixture(%{event: event, user: bob}) + event + end + + [ + sandbox_owner_pid: sandbox_owner_pid, + alice: alice, + alice_active_events: alice_active_events, + alice_expired_events: alice_expired_events, + alice_events: alice_active_events ++ alice_expired_events, + bob: bob, + bob_active_events: bob_active_events, + bob_expired_events: bob_expired_events, + bob_events: bob_active_events ++ bob_expired_events, + carol: carol, + carol_active_events: carol_active_events, + carol_expired_events: carol_expired_events, + carol_events: carol_active_events ++ carol_expired_events + ] + end + + describe "listing events" do + test "list_events/2 lists all events of a user but not others", context do + assert Events.list_events(context.alice.id) == list(context.alice_events) + assert Events.list_events(context.bob.id) == list(context.bob_events) + assert Events.list_events(context.carol.id) == list(context.carol_events) end - test "list_events/1 doesn't returns events of other users" do - event = event_fixture() + test "paginate_events/3 paginates all events of a user but not others", context do + assert Events.paginate_events(context.alice.id) == + paginate(context.alice_events) - event2 = event_fixture() + params = %{"page" => 2} - assert Events.list_events(event.user_id) == [event] - assert Events.list_events(event.user_id) != [event2] + assert Events.paginate_events(context.alice.id, params) == + paginate(context.alice_events, params) + + assert Events.paginate_events(context.bob.id) == + paginate(context.bob_events) + + params = %{"page" => 2, "page_size" => 12} + + assert Events.paginate_events(context.bob.id, params) == + paginate(context.bob_events, params) end - test "get_event!/2 returns the event with given id" do + test "list_not_expired_events/2 lists all active events for a user but not others", + context do + assert Events.list_not_expired_events(context.alice.id) == + list(context.alice_active_events) + + assert Events.list_not_expired_events(context.bob.id) == + list(context.bob_active_events) + + assert Events.list_not_expired_events(context.carol.id) == + list(context.carol_active_events) + end + + test "paginate_not_expired_events/3 paginates all active events for a user but not others", + context do + assert Events.paginate_not_expired_events(context.alice.id) == + paginate(context.alice_active_events) + + assert Events.paginate_not_expired_events(context.bob.id) == + paginate(context.bob_active_events) + + params = %{"page" => 2, "page_size" => 10} + + assert Events.paginate_not_expired_events(context.carol.id, params) == + paginate(context.carol_active_events, params) + end + + test "list_expired_events/2 lists all expired events for a user but not others", context do + assert Events.list_expired_events(context.alice.id) == + Enum.reverse(context.alice_expired_events) + + assert Events.list_expired_events(context.bob.id) == + Enum.reverse(context.bob_expired_events) + + assert Events.list_expired_events(context.carol.id) == + Enum.reverse(context.carol_expired_events) + end + + test "paginate_expired_events/3 lists all expired events for a user but not others", + context do + assert Events.paginate_expired_events(context.alice.id) == + paginate(context.alice_expired_events) + + assert Events.paginate_expired_events(context.bob.id) == + paginate(context.bob_expired_events) + + params = %{"page" => 2, "page_size" => 10} + + assert Events.paginate_expired_events(context.bob.id, params) == + paginate(context.bob_expired_events, params) + + assert Events.paginate_expired_events(context.carol.id) == + paginate(context.carol_expired_events) + end + + test "list_managed_events_by/2 lists all managed events by user but not others", context do + assert Events.list_managed_events_by(context.alice.email) == + list(context.carol_active_events) + + assert Events.list_managed_events_by(context.bob.email) == + list(context.carol_expired_events) + + assert Events.list_managed_events_by(context.carol.email) == [] + end + + test "paginate_managed_events_by/3 paginates all managed events by user but not others", + context do + assert Events.paginate_managed_events_by(context.alice.email) == + paginate(context.carol_active_events) + + assert Events.paginate_managed_events_by(context.bob.email) == + paginate(context.carol_expired_events) + + assert Events.paginate_managed_events_by(context.carol.email) == {[], 0, 0} + end + end + + describe "counting events" do + test "count_managed_events_by/1 counts all managed events by user", context do + assert Events.count_managed_events_by(context.alice.email) == + Enum.count(context.carol_active_events) + + assert Events.count_managed_events_by(context.bob.email) == + Enum.count(context.carol_expired_events) + + assert Events.count_managed_events_by(context.carol.email) == 0 + end + + test "count_expired_events/1 counts all expired events for user", context do + assert Events.count_expired_events(context.alice.id) == + Enum.count(context.alice_expired_events) + + assert Events.count_expired_events(context.bob.id) == Enum.count(context.bob_expired_events) + + assert Events.count_expired_events(context.carol.id) == + Enum.count(context.carol_expired_events) + end + + test "count_events_month/1 counts all events for user created in the last 30 days", + context do + assert Events.count_events_month(context.alice.id) == + Enum.count(context.alice_active_events) + Enum.count(context.alice_expired_events) + + assert Events.count_events_month(context.bob.id) == + Enum.count(context.bob_active_events) + Enum.count(context.bob_expired_events) + + assert Events.count_events_month(context.carol.id) == + Enum.count(context.carol_active_events) + Enum.count(context.carol_expired_events) + end + end + + describe "getting events" do + test "get_event!/2 gets event by serial ID and UUID" do event = event_fixture() + assert Events.get_event!(event.id) == event + assert Events.get_event!(to_string(event.id)) == event assert Events.get_event!(event.uuid) == event end - test "get_user_event!/3 with invalid user raises exception" do - event = event_fixture() - event2 = event_fixture() + test "get_managed_event!/3 gets event managed by owner and leader, raises if neither", + context do + event = Enum.at(context.carol_active_events, 0) + assert Events.get_managed_event!(context.alice, event.uuid) == event + assert Events.get_managed_event!(context.carol, event.uuid) == event assert_raise Ecto.NoResultsError, fn -> - Events.get_user_event!(event.user_id, event2.uuid) == event + Events.get_managed_event!(context.bob, event.uuid) end end + test "get_managed_event!/3 works for the owner of an event with no leaders", + context do + event = Enum.at(context.alice_active_events, 0) + assert Events.get_managed_event!(context.alice, event.uuid) == event + end + + test "get_user_event!/3 gets event by owner, raises if not", context do + event = Enum.at(context.alice_active_events, 0) + assert Events.get_user_event!(context.alice.id, event.uuid) == event + + assert_raise Ecto.NoResultsError, fn -> + Events.get_user_event!(context.bob.id, event.uuid) + end + end + + test "get_event_with_code!/2 gets non-expired event by code, raises if not found", context do + active_event = Enum.at(context.carol_active_events, 0) + expired_event = Enum.at(context.carol_expired_events, 0) + + assert Events.get_event_with_code!(active_event.code) == active_event + + assert_raise Ecto.NoResultsError, fn -> + Events.get_event_with_code!(expired_event.code) + end + + assert_raise Ecto.NoResultsError, fn -> + Events.get_event_with_code!("ABC123") + end + end + + test "get_event_with_code/2 gets non-expired event by code, returns nil if not found", + context do + active_event = Enum.at(context.carol_active_events, 0) + expired_event = Enum.at(context.carol_expired_events, 0) + + assert Events.get_event_with_code(active_event.code) == active_event + assert Events.get_event_with_code(expired_event.code) == nil + assert Events.get_event_with_code("ABC123") == nil + end + end + + describe "writing events" do test "create_event/1 with valid data creates a event" do user = user_fixture() - valid_attrs = %{ + attrs = %{ name: "some name", code: "12345", user_id: user.id, - started_at: NaiveDateTime.utc_now(), - expired_at: NaiveDateTime.add(NaiveDateTime.utc_now(), 7200, :second) + started_at: + NaiveDateTime.utc_now(:second) + |> NaiveDateTime.truncate(:second), + expired_at: + NaiveDateTime.add(NaiveDateTime.utc_now(), 2, :hour) + |> NaiveDateTime.truncate(:second) } - assert {:ok, %Event{} = event} = Events.create_event(valid_attrs) - assert event.name == "some name" - end + assert {:ok, %Event{} = event} = Events.create_event(attrs) - test "create_event/1 with too short code returns error changeset" do - user = user_fixture() - - valid_attrs = %{ - name: "some name", - code: "code", - user_id: user.id, - started_at: NaiveDateTime.utc_now(), - expired_at: NaiveDateTime.add(NaiveDateTime.utc_now(), 7200, :second) - } - - assert {:error, %Ecto.Changeset{}} = Events.create_event(valid_attrs) + assert event.name == attrs.name + assert event.code == attrs.code + assert event.user_id == attrs.user_id + assert event.started_at == attrs.started_at + assert attrs.expired_at == event.expired_at end test "create_event/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Events.create_event(@invalid_attrs) + user = user_fixture() + + attrs = %{ + name: "some name", + code: "12345", + user_id: user.id, + started_at: + NaiveDateTime.utc_now(:second) + |> NaiveDateTime.truncate(:second), + expired_at: + NaiveDateTime.add(NaiveDateTime.utc_now(), 2, :hour) + |> NaiveDateTime.truncate(:second) + } + + too_short_code = "tiny" + + assert {:error, %Ecto.Changeset{}} = Events.create_event(Map.delete(attrs, :name)) + assert {:error, %Ecto.Changeset{}} = Events.create_event(Map.delete(attrs, :code)) + assert {:error, %Ecto.Changeset{}} = Events.create_event(Map.delete(attrs, :user_id)) + assert {:error, %Ecto.Changeset{}} = Events.create_event(Map.delete(attrs, :started_at)) + + assert {:error, %Ecto.Changeset{}} = + Events.create_event(Map.merge(attrs, %{code: too_short_code})) + end + + test "duplicate_event/2 duplicates an event without presentation association" do + original = event_fixture() + {:ok, duplicate} = Events.duplicate_event(original.user_id, original.uuid) + + assert duplicate.name == "#{original.name} (Copy)" + assert duplicate.id != original.id + assert duplicate.code != original.code + end + + test "duplicate_event/2 duplicates an event with presentation associations" do + original = event_fixture() + presentation_file = presentation_file_fixture(%{event: original}) + presentation_state = presentation_state_fixture(%{presentation_file: presentation_file}) + + poll = + poll_fixture(%{ + presentation_file_id: presentation_file.id, + poll_opts: [ + %{content: "some option 1", vote_count: 1}, + %{content: "some option 2", vote_count: 2} + ] + }) + + poll_fixture(%{presentation_file_id: presentation_file.id}) + + form = form_fixture(%{presentation_file_id: presentation_file.id}) + form_fixture(%{presentation_file_id: presentation_file.id}) + embed = embed_fixture(%{presentation_file_id: presentation_file.id}) + embed_fixture(%{presentation_file_id: presentation_file.id}) + + duplicate = + Events.duplicate_event(original.user_id, original.uuid) + |> then(fn {:ok, duplicate} -> + duplicate + |> Repo.preload( + presentation_file: [:embeds, :forms, :presentation_state, polls: [:poll_opts]] + ) + end) + + # Event + assert duplicate.id != original.id + assert duplicate.uuid != original.uuid + assert duplicate.code != original.code + assert duplicate.name == "#{original.name} (Copy)" + assert duplicate.user_id == original.user_id + + # Presentation file + assert duplicate.presentation_file.id != presentation_file.id + assert duplicate.presentation_file.hash == presentation_file.hash + assert duplicate.presentation_file.length == presentation_file.length + assert duplicate.presentation_file.event_id != presentation_file.event_id + assert duplicate.presentation_file.event_id == duplicate.id + + # Presentation state + duplicate_state = duplicate.presentation_file.presentation_state + assert duplicate_state.id != presentation_state.id + assert duplicate_state.presentation_file_id != presentation_state.presentation_file_id + assert duplicate_state.presentation_file_id == duplicate.presentation_file.id + + # Polls + [duplicate_poll, _] = duplicate.presentation_file.polls + assert duplicate_poll.id != poll.id + assert duplicate_poll.presentation_file_id != poll.presentation_file_id + assert duplicate_poll.presentation_file_id == duplicate.presentation_file.id + assert duplicate_poll.title == poll.title + assert duplicate_poll.position == poll.position + + # Poll options + [o1, o2] = poll.poll_opts + [do1, do2] = duplicate_poll.poll_opts + + assert do1.id != o1.id + assert do1.poll_id != o1.poll_id + assert do1.poll_id == duplicate_poll.id + assert do1.content == o1.content + assert do1.vote_count == 0 + + assert do2.id != o2.id + assert do2.poll_id != o2.poll_id + assert do2.poll_id == duplicate_poll.id + assert do2.content == o2.content + assert do2.vote_count == 0 + + # Forms + [duplicate_form, _] = duplicate.presentation_file.forms + assert duplicate_form.id != form.id + assert duplicate_form.presentation_file_id != form.presentation_file_id + assert duplicate_form.presentation_file_id == duplicate.presentation_file.id + assert duplicate_form.enabled == form.enabled + assert duplicate_form.fields == form.fields + assert duplicate_form.position == form.position + assert duplicate_form.title == form.title + + # Embeds + [duplicate_embed, _] = duplicate.presentation_file.embeds + assert duplicate_embed.id != embed.id + assert duplicate_embed.presentation_file_id != embed.presentation_file_id + assert duplicate_embed.presentation_file_id == duplicate.presentation_file.id + assert(duplicate_embed.attendee_visibility == embed.attendee_visibility) + assert duplicate_embed.content == embed.content + assert duplicate_embed.enabled == embed.enabled + assert duplicate_embed.position == embed.position + assert duplicate_embed.provider == embed.provider + assert duplicate_embed.title == embed.title + end + + test "duplicate_event/2 raises when an invalid user-event is supplied", context do + original = Enum.at(context.alice_active_events, 0) + + assert_raise Ecto.NoResultsError, fn -> + Events.duplicate_event(context.bob.id, original.uuid) + end end test "update_event/2 with valid data updates the event" do @@ -88,10 +442,102 @@ defmodule Claper.EventsTest do test "update_event/2 with invalid data returns error changeset" do event = event_fixture() - assert {:error, %Ecto.Changeset{}} = Events.update_event(event, @invalid_attrs) + + assert {:error, %Ecto.Changeset{}} = Events.update_event(event, %{name: nil}) + assert {:error, %Ecto.Changeset{}} = Events.update_event(event, %{code: nil}) + assert {:error, %Ecto.Changeset{}} = Events.update_event(event, %{code: "tiny"}) + assert {:error, %Ecto.Changeset{}} = Events.update_event(event, %{user_id: nil}) + assert {:error, %Ecto.Changeset{}} = Events.update_event(event, %{started_at: nil}) + assert event == Events.get_event!(event.uuid) end + test "change_event/1 returns a event changeset" do + event = event_fixture() + assert %Ecto.Changeset{} = Events.change_event(event) + end + + test "terminate_event/1 terminates an event and broadcasts it" do + event = event_fixture() + assert event.expired_at == nil + + Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event.uuid}") + {:ok, event} = Events.terminate_event(event) + + assert NaiveDateTime.diff(NaiveDateTime.utc_now(), event.expired_at) |> abs() < 1 + assert_received {:event_terminated, uuid} + assert uuid == event.uuid + end + + test "delete_event/1 deletes the event" do + event = event_fixture() + + assert {:ok, %Event{}} = Events.delete_event(event) + assert_raise Ecto.NoResultsError, fn -> Events.get_event!(event.uuid) end + end + end + + describe "leading events" do + test "led_by?/2", context do + assert Events.led_by?(context.alice.email, Enum.at(context.carol_active_events, 0)) == true + assert Events.led_by?(context.bob.email, Enum.at(context.carol_active_events, 0)) == false + end + + test "create_activity_leader/1 with valid data creates an activity leader" do + attrs = %{ + email: "dan@example.com" + } + + {:ok, leader = %ActivityLeader{}} = Events.create_activity_leader(attrs) + assert leader.email == attrs.email + + event = event_fixture() + + attrs = %{ + email: "dan@example.com", + event_id: event.id + } + + {:ok, leader = %ActivityLeader{}} = Events.create_activity_leader(attrs) + assert leader.email == attrs.email + assert leader.event_id == attrs.event_id + end + + test "create_activity_leader/1 with invalid data returns error changeset" do + {:error, %Ecto.Changeset{}} = Events.create_activity_leader(%{}) + end + + test "create_activity_leader/1 disallows event owner as leader" do + user = user_fixture() + event = event_fixture(%{user: user}) + + attrs = %{ + email: user.email, + event_id: event.id, + user_email: user.email + } + + {:error, %Ecto.Changeset{}} = Events.create_activity_leader(attrs) + end + + test "get_activity_leader!/1 gets activity leader by ID" do + leader = activity_leader_fixture() + assert Events.get_activity_leader!(leader.id) == leader + end + + test "get_activity_leaders_for_event/1 gets activity leaders for event by ID", context do + event = Enum.at(context.carol_active_events, 0) + [leader] = Events.get_activity_leaders_for_event(event.id) + assert leader.user_id == context.alice.id + end + + test "change_activity_leader/2 returns an activity leader changeset" do + leader = activity_leader_fixture() + assert %Ecto.Changeset{} = Events.change_activity_leader(leader) + end + end + + describe "importing events" do test "import/3 transfer all interactions from an event to another" do user = user_fixture() from_event = event_fixture(%{user: user, name: "from event"}) @@ -121,48 +567,20 @@ defmodule Claper.EventsTest do Events.import(user.id, from_event.uuid, to_event.uuid) end end + end - test "duplicate_event/2 duplicates an event" do - user = user_fixture() - original_event = event_fixture(%{user: user, name: "Original Event"}) - presentation_file = presentation_file_fixture(%{event: original_event}) - presentation_state_fixture(%{presentation_file: presentation_file}) - poll_fixture(%{presentation_file_id: presentation_file.id}) - form_fixture(%{presentation_file_id: presentation_file.id}) - embed_fixture(%{presentation_file_id: presentation_file.id}) + defp list(events), do: Enum.reverse(events) - assert {:ok, duplicated_event} = Events.duplicate_event(user.id, original_event.uuid) + defp paginate(events, params \\ %{}) do + page = Map.get(params, "page", 1) + page_size = Map.get(params, "page_size", 5) + start_index = (page - 1) * page_size + event_count = length(events) - assert duplicated_event.id != original_event.id - assert duplicated_event.user_id == original_event.user_id - assert duplicated_event.name == "Original Event (Copy)" - assert duplicated_event.code != original_event.code - assert duplicated_event.uuid != original_event.uuid - - # Check if the presentation file was duplicated - duplicated_presentation_file = - Claper.Events.get_event!(duplicated_event.uuid, [:presentation_file]).presentation_file - - assert duplicated_presentation_file.id != presentation_file.id - assert duplicated_presentation_file.hash == presentation_file.hash - assert duplicated_presentation_file.length == presentation_file.length - - # Check if polls, forms, and embeds were duplicated - assert length(Claper.Polls.list_polls(duplicated_presentation_file.id)) == 1 - assert length(Claper.Forms.list_forms(duplicated_presentation_file.id)) == 1 - assert length(Claper.Embeds.list_embeds(duplicated_presentation_file.id)) == 1 - end - - test "delete_event/1 deletes the event" do - event = event_fixture() - - assert {:ok, %Event{}} = Events.delete_event(event) - assert_raise Ecto.NoResultsError, fn -> Events.get_event!(event.uuid) end - end - - test "change_event/1 returns a event changeset" do - event = event_fixture() - assert %Ecto.Changeset{} = Events.change_event(event) - end + { + events |> Enum.reverse() |> Enum.slice(start_index, page_size), + event_count, + ceil(event_count / page_size) + } end end diff --git a/test/claper/forms_test.exs b/test/claper/forms_test.exs index abbb41b..5a299b2 100644 --- a/test/claper/forms_test.exs +++ b/test/claper/forms_test.exs @@ -51,13 +51,15 @@ defmodule Claper.FormsTest do presentation_file_id: presentation_file.id, position: 0, fields: [ - %{name: "some option 1", type: "text"}, + %{name: "some option 1", type: "text", required: false}, %{name: "some option 2", type: "email"} ] } assert {:ok, %Form{} = form} = Forms.create_form(valid_attrs) assert form.title == "some title" + assert Enum.at(form.fields, 0) |> Map.fetch!(:required) == false + assert Enum.at(form.fields, 1) |> Map.fetch!(:required) == true end test "create_form/1 with invalid data returns error changeset" do diff --git a/test/claper/quizzes_test.exs b/test/claper/quizzes_test.exs index 6a8300c..0ee044b 100644 --- a/test/claper/quizzes_test.exs +++ b/test/claper/quizzes_test.exs @@ -113,14 +113,14 @@ defmodule Claper.QuizzesTest do assert length(new_question.quiz_question_opts) == 2 end - test "submit_quiz/3 with user_id records responses and updates counts" do + test "submit_quiz/3 with user records responses and updates counts" do quiz = quiz_fixture() user = user_fixture() question = List.first(quiz.quiz_questions) option = List.first(question.quiz_question_opts) assert {:ok, updated_quiz} = - Quizzes.submit_quiz(user.id, [option], quiz.id) + Quizzes.submit_quiz(user, [option], quiz.id) updated_option = updated_quiz.quiz_questions @@ -151,7 +151,7 @@ defmodule Claper.QuizzesTest do correct_option = Enum.find(question.quiz_question_opts, & &1.is_correct) # Submit correct answer - {:ok, _} = Quizzes.submit_quiz(user.id, [correct_option], quiz.id) + {:ok, _} = Quizzes.submit_quiz(user, [correct_option], quiz.id) assert {1, 1} = Quizzes.calculate_user_score(user.id, quiz.id) end diff --git a/test/claper_web/helpers/csv_exporter_test.exs b/test/claper_web/helpers/csv_exporter_test.exs new file mode 100644 index 0000000..25e9191 --- /dev/null +++ b/test/claper_web/helpers/csv_exporter_test.exs @@ -0,0 +1,219 @@ +defmodule ClaperWeb.Helpers.CSVExporterTest do + use Claper.DataCase + + alias ClaperWeb.Helpers.CSVExporter + alias Claper.Accounts.User + alias Claper.Events.Event + alias Claper.Accounts.Oidc.Provider + alias Claper.Accounts.Role + alias Claper.Repo + + describe "export_users_to_csv/1" do + setup do + # Create roles + {:ok, user_role} = Repo.insert(%Role{name: "user"}) + {:ok, admin_role} = Repo.insert(%Role{name: "admin"}) + + # Create users + {:ok, user1} = + Repo.insert(%User{ + email: "user1@example.com", + uuid: Ecto.UUID.generate(), + role_id: user_role.id, + inserted_at: ~N[2023-01-01 10:00:00], + hashed_password: "hashed_password", + is_randomized_password: false + }) + + {:ok, user2} = + Repo.insert(%User{ + email: "admin@example.com", + uuid: Ecto.UUID.generate(), + role_id: admin_role.id, + inserted_at: ~N[2023-01-02 10:00:00], + hashed_password: "hashed_password", + is_randomized_password: false + }) + + %{users: [user1, user2], user_role: user_role, admin_role: admin_role} + end + + test "exports users to CSV format", %{users: users} do + users = Repo.preload(users, :role) + csv = CSVExporter.export_users_to_csv(users) + + # CSV should have a header row and two data rows + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 3 + + # Check header + header = List.first(lines) + assert header =~ "Email" + assert header =~ "Name" + assert header =~ "Role" + assert header =~ "Created At" + + # Check data rows + assert Enum.at(lines, 1) =~ "user1@example.com" + assert Enum.at(lines, 1) =~ "user" + + assert Enum.at(lines, 2) =~ "admin@example.com" + assert Enum.at(lines, 2) =~ "admin" + end + + test "handles empty user list" do + csv = CSVExporter.export_users_to_csv([]) + + # CSV should only have a header row + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 1 + + # Check header + header = List.first(lines) + assert header =~ "Email" + assert header =~ "Name" + assert header =~ "Role" + end + end + + describe "export_events_to_csv/1" do + setup do + # Create events + {:ok, event1} = + Repo.insert(%Event{ + name: "Event One", + uuid: Ecto.UUID.generate(), + code: "event1", + started_at: ~N[2023-01-01 10:00:00], + expired_at: ~N[2023-01-01 12:00:00], + audience_peak: 10, + inserted_at: ~N[2023-01-01 09:00:00] + }) + + {:ok, event2} = + Repo.insert(%Event{ + name: "Event Two", + uuid: Ecto.UUID.generate(), + code: "event2", + started_at: ~N[2023-01-02 10:00:00], + expired_at: ~N[2023-01-02 12:00:00], + audience_peak: 20, + inserted_at: ~N[2023-01-01 09:30:00] + }) + + %{events: [event1, event2]} + end + + test "exports events to CSV format", %{events: events} do + csv = CSVExporter.export_events_to_csv(events) + + # CSV should have a header row and two data rows + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 3 + + # Check header + header = List.first(lines) + assert header =~ "Name" + assert header =~ "Description" + assert header =~ "Start Date" + assert header =~ "End Date" + assert header =~ "Status" + + # Check data rows contain event names + assert Enum.at(lines, 1) =~ "Event One" + assert Enum.at(lines, 2) =~ "Event Two" + end + + test "handles empty event list" do + csv = CSVExporter.export_events_to_csv([]) + + # CSV should only have a header row + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 1 + + # Check header + header = List.first(lines) + assert header =~ "Name" + assert header =~ "Description" + assert header =~ "Start Date" + end + end + + describe "export_oidc_providers_to_csv/1" do + setup do + # Create providers + {:ok, provider1} = + Repo.insert(%Provider{ + name: "Provider One", + issuer: "https://example1.com", + client_id: "client1", + client_secret: "secret1", + redirect_uri: "https://app.example.com/callback1", + scope: "openid email", + active: true, + inserted_at: ~N[2023-01-01 09:00:00] + }) + + {:ok, provider2} = + Repo.insert(%Provider{ + name: "Provider Two", + issuer: "https://example2.com", + client_id: "client2", + client_secret: "secret2", + redirect_uri: "https://app.example.com/callback2", + scope: "openid profile", + active: false, + inserted_at: ~N[2023-01-01 09:30:00] + }) + + %{providers: [provider1, provider2]} + end + + test "exports providers to CSV format", %{providers: providers} do + csv = CSVExporter.export_oidc_providers_to_csv(providers) + + # CSV should have a header row and two data rows + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 3 + + # Check header + header = List.first(lines) + assert header =~ "Name" + assert header =~ "Issuer" + assert header =~ "Client ID" + assert header =~ "Active" + + # Client secret should not be included for security + refute header =~ "Client Secret" + + # Check data rows + assert Enum.at(lines, 1) =~ "Provider One" + assert Enum.at(lines, 1) =~ "https://example1.com" + assert Enum.at(lines, 1) =~ "client1" + assert Enum.at(lines, 1) =~ "Yes" + + assert Enum.at(lines, 2) =~ "Provider Two" + assert Enum.at(lines, 2) =~ "https://example2.com" + assert Enum.at(lines, 2) =~ "client2" + assert Enum.at(lines, 2) =~ "No" + + # Client secrets should not be included in the CSV + refute csv =~ "secret1" + refute csv =~ "secret2" + end + + test "handles empty provider list" do + csv = CSVExporter.export_oidc_providers_to_csv([]) + + # CSV should only have a header row + lines = String.split(csv, "\r\n", trim: true) + assert length(lines) == 1 + + # Check header + header = List.first(lines) + assert header =~ "Name" + assert header =~ "Issuer" + assert header =~ "Client ID" + end + end +end diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 433d6c5..dad6a9b 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -28,9 +28,13 @@ defmodule Claper.DataCase do end end - setup tags do - pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Claper.Repo, shared: not tags[:async]) - on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) + setup context do + # Don't check out a connection if a setup_all did so already + if context[:sandbox_owner_pid] == nil do + pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Claper.Repo, shared: not context[:async]) + on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) + end + :ok end diff --git a/test/support/fixtures/events_fixtures.ex b/test/support/fixtures/events_fixtures.ex index b8deb2d..33a11a1 100644 --- a/test/support/fixtures/events_fixtures.ex +++ b/test/support/fixtures/events_fixtures.ex @@ -9,7 +9,27 @@ defmodule Claper.EventsFixtures do require Claper.UtilFixture @doc """ - Generate a event. + Generate an activity leader. + """ + def activity_leader_fixture(attrs \\ %{}, preload \\ []) do + assoc = %{ + event: attrs[:event] || event_fixture(), + user: attrs[:user] || user_fixture() + } + + {:ok, activity_leader} = + attrs + |> Enum.into(%{ + email: assoc.user.email, + event_id: assoc.event.id + }) + |> Claper.Events.create_activity_leader() + + Claper.UtilFixture.merge_preload(activity_leader, preload, assoc) + end + + @doc """ + Generate an event. """ def event_fixture(attrs \\ %{}, preload \\ []) do assoc = %{user: attrs[:user] || user_fixture()} diff --git a/with_env.sh b/with_env.sh new file mode 100755 index 0000000..5c6fd4a --- /dev/null +++ b/with_env.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -a + +# Default environment file +env_file=".env" + +# Parse command-line arguments +while [[ "$#" -gt 0 ]]; do + case "$1" in + --env) + env_file="$2" + shift 2 # Skip the next argument as it's the value for --env + ;; + *) + break # Exit the loop if an unrecognized option is found + ;; + esac +done + +source "$env_file" +set +a + +# Remaining arguments are treated as the command to run +args=("$@") + +# Check if no command is provided +if [ ${#args[@]} -eq 0 ]; then + echo "Usage: $0 [--env path/to/env] " + echo "Example: $0 mix phx.server" + echo "Example: $0 --env path/to/env mix phx.server" + exit 1 +fi + +# Execute the command +"${args[@]}"