diff --git a/.env.sample b/.env.sample index 230f180..db6c64e 100644 --- a/.env.sample +++ b/.env.sample @@ -1,25 +1,39 @@ +BASE_URL=http://localhost:4000 +# SAME_SITE_COOKIE=Lax +# SECURE_COOKIE=false + +DATABASE_URL=postgres://claper:claper@db:5432/claper +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 + PRESENTATION_STORAGE=local PRESENTATION_STORAGE_DIR=/app/uploads -MAX_FILE_SIZE_MB=15 +#MAX_FILE_SIZE_MB=15 -AWS_ACCESS_KEY_ID=xxx -AWS_SECRET_ACCESS_KEY=xxx -AWS_REGION=eu-west-3 -AWS_PRES_BUCKET=xxx +#AWS_ACCESS_KEY_ID=xxx +#AWS_SECRET_ACCESS_KEY=xxx +#AWS_REGION=eu-west-3 +#AWS_PRES_BUCKET=xxx -SMTP_RELAY=xx.example.com -SMTP_USERNAME=johndoe@example.com -SMTP_PASSWORD=xxx -SMTP_PORT=465 -SMTP_TLS=if_available +# Mail configuration MAIL_TRANSPORT=local MAIL_FROM=noreply@claper.co MAIL_FROM_NAME=Claper -ENABLE_ACCOUNT_CREATION=true -ENABLE_MAILBOX_ROUTE=false -MAILBOX_USER=admin -MAILBOX_PASSWORD=admin +#SMTP_RELAY=xx.example.com +#SMTP_USERNAME=johndoe@example.com +#SMTP_PASSWORD=xxx +#SMTP_PORT=465 +#SMTP_TLS=if_available + +#ENABLE_MAILBOX_ROUTE=false +#MAILBOX_USER=admin +#MAILBOX_PASSWORD=admin + +# Claper configuration -GS_JPG_RESOLUTION=300x300 +#ENABLE_ACCOUNT_CREATION=true +#GS_JPG_RESOLUTION=300x300 \ No newline at end of file diff --git a/.formatter.exs b/.formatter.exs index 1470d85..ef8840c 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,6 +1,6 @@ [ - import_deps: [:ecto, :phoenix], - inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"], + import_deps: [:ecto, :ecto_sql, :phoenix], subdirectories: ["priv/*/migrations"], - plugins: [Phoenix.LiveView.HTMLFormatter] + plugins: [Phoenix.LiveView.HTMLFormatter], + inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"] ] diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml deleted file mode 100644 index ebd3b1d..0000000 --- a/.github/workflows/doc.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Publish doc -on: - push: - branches: [ "main" ] - tags: ['v*'] -permissions: - contents: write -jobs: - build-and-deploy: - concurrency: ci-${{ github.ref }} # Recommended if you intend to make multiple deployments in quick succession. - runs-on: ubuntu-latest - env: - ImageOS: ubuntu20 - steps: - - uses: actions/checkout@v3 - - name: Set up Elixir - uses: erlef/setup-beam@988e02bfe678367a02564f65ca2e37726dc0268f - with: - elixir-version: '1.13.2' - otp-version: '24.1' - - name: Restore dependencies cache - uses: actions/cache@v3 - with: - path: deps - key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} - restore-keys: ${{ runner.os }}-mix- - - name: Install dependencies - run: mix deps.get - - - name: Build doc - run: mix docs - - - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4 - with: - folder: doc # The folder the action should deploy. diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a44c11f..ca4a89d 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -48,23 +48,12 @@ jobs: uses: docker/build-push-action@v2.10.0 with: context: . + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - - name: Build and push ARM Docker image - # You may pin to the exact commit or the version. - # uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a - uses: docker/build-push-action@v2.10.0 - with: - context: . - file: ./Dockerfile-arm - push: true - platforms: linux/arm64 - tags: ${{ steps.meta.outputs.tags }}-arm - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - - + build-args: | + BUILD_METADATA=${{ steps.meta.outputs.json }} + ERL_FLAGS=+JPperf true \ No newline at end of file diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 3fe1906..f02bc34 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -18,7 +18,7 @@ jobs: services: db: - image: postgres:9 + image: postgres:15 ports: ['5432:5432'] env: POSTGRES_PASSWORD: claper @@ -34,6 +34,7 @@ jobs: MIX_ENV: test DATABASE_URL: postgresql://claper:claper@localhost:5432/claper SECRET_KEY_BASE: QMQE4ypfy0IC1LZI/fygZNvXHPjLslnr49EE7ftcL1wgAC0MwMLdKCVJyrvXPu8z + BASE_URL: http://localhost:4000 steps: - uses: actions/checkout@v3 @@ -42,8 +43,8 @@ jobs: - name: Set up Elixir uses: erlef/setup-beam@988e02bfe678367a02564f65ca2e37726dc0268f with: - elixir-version: '1.13.2' - otp-version: '24.1' + elixir-version: '1.15.4' + otp-version: '26' - name: Restore dependencies cache uses: actions/cache@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index c8888f0..8d8edf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## v2.0.0 + +### Features + +- Add dynamic layout in the manager view +- Add quick event feature +- Add question feature +- Add toggle for message reactions in attendees room +- Add toggle for polls results in attendees room +- Add delete account button in user settings +- Add language switcher in user settings +- Add tour guide for new users +- Add headers to exported CSV in reports +- Add spanish locale (#84) (@eduproinf) + +### Fixes and improvements + +- Improve Docker image to support both ARM and AMD64 architecture +- Change date picker for a more user-friendly one +- Upgrade Ecto, Phoenix and LiveView +- Fix user avatars in reports +- Fix average voters stats +- Fix some UI/UX issues +- Remove end date for events +- Replace `ENDPOINT_PORT` and `ENDPOINT_HOST` with `BASE_URL` environment variable +- Add `SAME_SITE_COOKIE` and `SECURE_COOKIE` environment variables + ## v1.7.0 - Add keyboard shortcuts to control settings (#64) (@Dhanus3133) @@ -12,6 +39,7 @@ - Security updates ## v1.6.0 + - Improve QR code readability - Add ARM Docker image - Refactor all runtime configuration @@ -46,25 +74,21 @@ - Add MAX_FILE_SIZE_MB environment variable to limit file upload size - Add feature to deactivate messages during a presentation - ## v1.3.0 - Add Form feature to collect data from your public - Improve docs for Docker Compose - Improve Docker Compose file reference - ## v1.2.1 - Fix presenter url (400 error in production) - ## v1.2.0 - Added password change form in settings - Added more documentation on deployment in production - ## v1.1.1 _Security updates_ @@ -72,7 +96,6 @@ _Security updates_ - Added `ENABLE_MAILBOX_ROUTE`, `MAILBOX_USER` and `MAILBOX_PASSWORD` environment variables to enable/disable route to local mailbox (`/dev/mailbox`) and basic auth (optional) - Restricted `/users/register` route if `ENABLE_ACCOUNT_CREATION` is false - ## v1.1.0 - Added password authentication @@ -81,7 +104,6 @@ _Security updates_ - Added new `ENABLE_ACCOUNT_CREATION` environment variable to enable or disable user registration - Improved french localization - ## v1.0.0 This is the first version of the open-source project. Feel free to contribute! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6223f1e..6a0c50f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,4 +11,9 @@ Don't forget to give the project a star! Thanks again! ## Translations -You can contribute to the translations by editing or addind PO files in `/priv/gettext/` \ No newline at end of file +You can contribute to the translations by editing the files in `/priv/gettext/` +Each language has its own directory with the `.po` files. The country code is used as the directory name and following the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) nomenclature, for example, `en` for English, `fr` for French, `de` for German. You can find the list of country codes [here](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes). + +### Add new language + +To add a new language, you can copy the `en` directory and rename it with the country code of the new language. Then you can edit the `.po` files with the translations. diff --git a/Dockerfile b/Dockerfile index ff0b8c8..84d4534 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,30 +12,36 @@ # - 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.13.2-erlang-24.2.1-debian-bullseye-20210902-slim" -ARG RUNNER_IMAGE="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" 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 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 ENV NODE_VERSION 16.20.0 ENV PRESENTATION_STORAGE_DIR /app/uploads +# custom ERL_FLAGS are passed for (public) multi-platform builds +# to fix qemu segfault, more info: https://github.com/erlang/otp/pull/6340 +ARG ERL_FLAGS +ENV ERL_FLAGS=$ERL_FLAGS + # Install nvm with node and npm -RUN curl https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash \ - && . $HOME/.nvm/nvm.sh \ - && nvm install $NODE_VERSION \ - && nvm alias default $NODE_VERSION \ - && nvm use default +# 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 +# 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 +# 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 @@ -71,8 +77,12 @@ 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 + # compile assets -RUN mix assets.deploy +RUN mix assets.deploy.nosass # Changes to config/runtime.exs don't require recompiling the code COPY config/runtime.exs config/ @@ -84,34 +94,32 @@ RUN mix release # the compiled release and other runtime necessities FROM ${RUNNER_IMAGE} -RUN apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales ghostscript \ - && apt-get install -y libreoffice --no-install-recommends && apt-get clean && rm -f /var/lib/apt/lists/*_* +# 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 + +# 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/* -# Set the locale -RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen +# Install Microsoft Core Fonts +RUN apk --no-cache add msttcorefonts-installer fontconfig && \ + update-ms-fonts && \ + fc-cache -f && \ + rm -rf /var/cache/apk/* ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 -ENV HOME "/home/nobody" - -RUN mkdir /home/nobody && chown nobody /home/nobody +ENV MIX_ENV="prod" -WORKDIR "/app" -RUN mkdir /app/uploads -RUN chown -R nobody /app # Only copy the final release from the build stage -COPY --from=builder --chown=nobody:root /app/_build/prod/rel/claper ./ - -RUN chmod +x /app/bin/* - -USER nobody +COPY --from=builder --chmod=a+rX /app/_build/prod/rel/claper /app +RUN mkdir /app/uploads && chmod -R 777 /app/uploads EXPOSE 4000 - +WORKDIR "/app" +USER root CMD ["sh", "-c", "/app/bin/claper eval Claper.Release.migrate && /app/bin/claper start"] - -# Appended by flyctl -#ENV ECTO_IPV6 true -#ENV ERL_AFLAGS "-proto_dist inet6_tcp" diff --git a/Dockerfile-arm b/Dockerfile-arm deleted file mode 100644 index b29d845..0000000 --- a/Dockerfile-arm +++ /dev/null @@ -1,117 +0,0 @@ -# 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-arm64:1.13.2-erlang-24.2.1-debian-bullseye-20210902-slim" -ARG RUNNER_IMAGE="debian:bullseye-20210902-slim" - -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/*_* - -ENV NODE_VERSION 16.20.0 -ENV PRESENTATION_STORAGE_DIR /app/uploads - -# Install nvm with node and npm -RUN curl https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/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 - -# install hex + rebar -RUN mix local.hex --force && \ - mix local.rebar --force - -# set build ENV -ENV MIX_ENV="prod" - -# install mix dependencies -COPY mix.exs mix.lock ./ -RUN mix deps.get --only $MIX_ENV -RUN mkdir config - -# copy compile-time config files before we compile dependencies -# to ensure any relevant config change will trigger the dependencies -# to be re-compiled. -COPY config/config.exs config/${MIX_ENV}.exs config/ -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 - -# compile assets -RUN mix assets.deploy - -# Changes to config/runtime.exs don't require recompiling the code -COPY config/runtime.exs config/ - -COPY rel rel -RUN mix release - -# start a new build stage so that the final image will only contain -# the compiled release and other runtime necessities -FROM ${RUNNER_IMAGE} - -RUN apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales ghostscript \ - && apt-get install -y libreoffice --no-install-recommends && apt-get clean && rm -f /var/lib/apt/lists/*_* - -# Set the locale -RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen - -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 -ENV HOME "/home/nobody" - -RUN mkdir /home/nobody && chown nobody /home/nobody - -WORKDIR "/app" -RUN mkdir /app/uploads -RUN chown -R nobody /app -R - -# Only copy the final release from the build stage -COPY --from=builder --chown=nobody:root /app/_build/prod/rel/claper ./ - -RUN chmod +x /app/bin/* - -USER nobody - -EXPOSE 4000 - -CMD ["sh", "-c", "/app/bin/claper eval Claper.Release.migrate && /app/bin/claper start"] - -# Appended by flyctl -#ENV ECTO_IPV6 true -#ENV ERL_AFLAGS "-proto_dist inet6_tcp" diff --git a/README.md b/README.md index af7a754..54d99d2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - [![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] @@ -26,53 +25,40 @@

- - - [![Product Name Screen Shot][product-screenshot]](https://claper.co) Claper turns your presentations into an interactive, engaging and exciting experience. 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. +Supported languages: 🇬🇧 English, 🇫🇷 French, 🇩🇪 German, 🇪🇸 Spanish ### Built With Claper is proudly powered by Phoenix and Elixir. -* [![Phoenix][Phoenix]][Phoenix-url] -* [![Elixir][Elixir]][Elixir-url] -* [![Tailwind][Tailwind]][Tailwind-url] +[![Phoenix][Phoenix]][Phoenix-url] [![Elixir][Elixir]][Elixir-url] [![Tailwind][Tailwind]][Tailwind-url] +## Documentation - -## Getting Started +You can find all the instructions and configuration in [the documentation](https://docs.claper.co/configuration.html). -This is an example of how you may give instructions on setting up your project locally. -To get a local copy up and running follow these simple example steps. +## Development environment ### Prerequisites To run Claper on your local environment you need to have: -* Postgres >= 9 -* Elixir >= 1.13.2 -* Erlang >= 24 -* NPM >= 6.14.17 -* NodeJS >= 14.19.2 -* Ghostscript >= 9.5.0 (for PDF support) -* Libreoffice >= 6.4 (for PPT/PPTX support) - -You can also use Docker to easily run a Postgres instance: -```sh - docker run -p 5432:5432 -e POSTGRES_PASSWORD=claper -e POSTGRES_USER=claper -e POSTGRES_DB=claper --name claper-db -d postgres:9 - ``` -### Configuration - -You can find all configuration options in [the docs](https://docs.claper.co/configuration.html). +- Postgres >= 15 +- Elixir >= 1.16 +- Erlang >= 26 +- NPM >= 10 +- NodeJS >= 20 +- Ghostscript >= 9 (for PDF support) +- Libreoffice >= 24 (for PPT/PPTX support) ### Installation @@ -105,30 +91,6 @@ Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. If you have configured `MAIL` to `local`, you can access to the mailbox at [`localhost:4000/dev/mailbox`](http://localhost:4000/dev/mailbox). - -### Using Docker Compose - -A Docker Compose [reference file](https://github.com/ClaperCo/Claper/blob/main/docker-compose.yml) is provided in the repository. You can use it to run Claper with Docker Compose. - -```sh -git clone https://github.com/ClaperCo/Claper.git -cd Claper -docker compose up -``` - - -### Using Docker Compose for Dev - -To easy check new features, it is possible to directly build the Docker image from the source code and run the container with the [docker-compose-dev.yml](https://github.com/ClaperCo/Claper/blob/main/docker-compose-dev.yml) file. - -```sh -git clone https://github.com/ClaperCo/Claper.git -cd Claper -docker compose -f docker-compose-dev.yml up -``` - - - ## Contributing Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. @@ -142,23 +104,23 @@ Don't forget to give the project a star! Thanks again! 4. Push to the Branch (`git push origin feature/amazing_feature`) 5. Open a Pull Request - + ## License Distributed under the GPLv3 License. See `LICENSE.txt` for more information. + ## Contact [![](https://img.shields.io/badge/@alxlion__-000000?style=for-the-badge&logo=x&logoColor=white)](https://x.com/alxlion_) Project Link: [https://github.com/ClaperCo/Claper](https://github.com/ClaperCo/Claper) - - + [contributors-shield]: https://img.shields.io/github/contributors/ClaperCo/Claper.svg?style=for-the-badge [contributors-url]: https://github.com/ClaperCo/Claper/graphs/contributors [forks-shield]: https://img.shields.io/github/forks/ClaperCo/Claper.svg?style=for-the-badge diff --git a/assets/css/app.css b/assets/css/app.css index 565b018..88a6251 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -1,4 +1,4 @@ -@import url("flatpickr/dist/flatpickr.min.css"); +@import url('air-datepicker/air-datepicker.css'); @import url("animate.css/animate.min.css"); @tailwind base; @@ -427,4 +427,21 @@ -ms-transform:rotate(-20deg); -o-transform:rotate(-20deg); transform:rotate(-20deg); +} + +/* Air datepicker */ +.air-datepicker-body--day-name { + @apply text-primary-600; +} + +.air-datepicker-cell.-selected-, .air-datepicker-cell.-selected-.-current- { + @apply bg-primary-500 text-white hover:bg-primary-600; +} + +.air-datepicker-cell.-current- { + @apply text-secondary-500; +} + +.animate__slow_slow { + --animate-duration: 5s; } \ No newline at end of file diff --git a/assets/css/custom.scss b/assets/css/custom.scss index 6fc8cb3..218add2 100644 --- a/assets/css/custom.scss +++ b/assets/css/custom.scss @@ -2,6 +2,8 @@ @import "../node_modules/tiny-slider/src/tiny-slider.scss"; +@import "../node_modules/@sjmc11/tourguidejs/src/scss/tour.scss"; + $particleSize: 20vmin; $animationDuration: 6s; $amount: 20; diff --git a/assets/js/app.js b/assets/js/app.js index c9f68f2..1bea850 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,336 +1,437 @@ -// If you want to use Phoenix channels, run `mix help phx.gen.channel` -// to get started and then uncomment the line below. -// import "./user_socket.js" - -// You can include dependencies in two ways. -// -// The simplest option is to put them in assets/vendor and -// import them using relative paths: -// -// import "./vendor/some-package.js" -// -// Alternatively, you can `npm install some-package` and import -// them using a path starting with the package name: -// -// import "some-package" -// - // Include phoenix_html to handle method=PUT/DELETE in forms and buttons. -import "phoenix_html" +import "phoenix_html"; // Establish Phoenix Socket and LiveView configuration. -import {Socket, Presence} from "phoenix" -import {LiveSocket} from "phoenix_live_view" -import topbar from "../vendor/topbar" -import Alpine from 'alpinejs' -import flatpickr from "flatpickr" -import moment from "moment-timezone" -import 'moment/locale/de' -import 'moment/locale/fr' -import QRCodeStyling from "qr-code-styling" -import { Presenter } from "./presenter" -import { Manager } from "./manager" -window.moment = moment - -window.moment.locale("en") -window.moment.locale(navigator.language.split('-')[0]) -window.Alpine = Alpine -Alpine.start() - -let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") -let Hooks = {} +import { Socket, Presence } from "phoenix"; +import { LiveSocket } from "phoenix_live_view"; +import topbar from "../vendor/topbar"; +import Alpine from "alpinejs"; +import moment from "moment-timezone"; +import AirDatepicker from "air-datepicker"; +import airdatepickerLocaleEn from "air-datepicker/locale/en"; +import airdatepickerLocaleFr from "air-datepicker/locale/fr"; +import airdatepickerLocaleDe from "air-datepicker/locale/de"; +import airdatepickerLocaleEs from "air-datepicker/locale/es"; +import "moment/locale/de"; +import "moment/locale/fr"; +import "moment/locale/es"; +import QRCodeStyling from "qr-code-styling"; +import { Presenter } from "./presenter"; +import { Manager } from "./manager"; +import Split from "split-grid"; +import { TourGuideClient } from "@sjmc11/tourguidejs/src/Tour"; +window.moment = moment; + +const locale = + document.querySelector("html").getAttribute("lang") || + navigator.language.split("-")[0]; +window.moment.locale("en"); +window.moment.locale(locale); +window.Alpine = Alpine; +Alpine.start(); + +let airdatepickerLocale = { + en: airdatepickerLocaleEn, + fr: airdatepickerLocaleFr, + de: airdatepickerLocaleDe, + es: airdatepickerLocaleEs, +}; +let csrfToken = document + .querySelector("meta[name='csrf-token']") + .getAttribute("content"); +let Hooks = {}; + +Hooks.EmbeddedBanner = { + mounted() { + if (window !== window.parent) { + this.el.classList.remove("hidden"); + } + }, + updated() { + if (window !== window.parent) { + this.el.classList.remove("hidden"); + } + }, +}; + +Hooks.TourGuide = { + mounted() { + this.tour = new TourGuideClient({ + nextLabel: this.el.dataset.nextLabel, + prevLabel: this.el.dataset.prevLabel, + finishLabel: this.el.dataset.finishLabel, + completeOnFinish: true, + rememberStep: true, + }); + + if (!this.tour.isFinished(this.el.dataset.group)) { + this.tour.start(this.el.dataset.group); + } + + this.tour.onBeforeExit(() => { + this.tour.finishTour(true, this.el.dataset.group); + }); + }, +}; + +Hooks.Split = { + mounted() { + const type = this.el.dataset.type; + const gutter = this.el.dataset.gutter; + const columnSlitValue = + localStorage.getItem("column-split") || "1fr 10px 1fr"; + const rowSlitValue = localStorage.getItem("row-split") || "1fr 10px 1fr"; + + if (type === "column") { + this.columnSplit = Split({ + columnGutters: [ + { + track: 1, + element: this.el.querySelector(gutter), + }, + ], + onDragEnd: () => { + const currentPosition = this.el.style["grid-template-columns"]; + localStorage.setItem("column-split", currentPosition); + }, + }); + this.el.style["grid-template-columns"] = columnSlitValue; + } else { + this.rowSplit = Split({ + rowGutters: [ + { + track: 1, + element: this.el.querySelector(gutter), + }, + ], + onDragEnd: () => { + const value = this.el.style["grid-template-rows"]; + localStorage.setItem("row-split", value); + }, + }); + this.el.style["grid-template-rows"] = rowSlitValue; + } + }, + updated() { + if (this.columnSplit) { + const value = localStorage.getItem("column-split") || "1fr 10px 1fr"; + this.el.style["grid-template-columns"] = value; + } + if (this.rowSplit) { + const value = localStorage.getItem("row-split") || "1fr 10px 1fr"; + this.el.style["grid-template-rows"] = value; + } + }, + destroyed() { + if (this.columnSplit) { + this.columnSplit.destroy(); + } + if (this.rowSplit) { + this.rowSplit.destroy(); + } + }, +}; Hooks.Scroll = { mounted() { - if (this.el.dataset.postsNb > 4) window.scrollTo({top: document.querySelector(this.el.dataset.target).scrollHeight, behavior: 'smooth'}); - this.handleEvent("scroll", () => { - let t = document.querySelector(this.el.dataset.target) - if (this.el.childElementCount > 4 && (window.scrollY + window.innerHeight >= t.offsetHeight - 100)) { - window.scrollTo({top: t.scrollHeight, behavior: 'smooth'}); - } - }) - } -} + if (this.el.dataset.postsNb > 4) + window.scrollTo({ + top: document.querySelector(this.el.dataset.target).scrollHeight, + behavior: "smooth", + }); + this.handleEvent("scroll", () => {}); + }, + updated() { + let t = document.querySelector(this.el.dataset.target); + if ( + this.el.childElementCount > 4 && + window.scrollY + window.innerHeight >= t.offsetHeight - 300 + ) { + window.scrollTo({ top: t.scrollHeight, behavior: "smooth" }); + } + }, +}; Hooks.ScrollIntoDiv = { mounted() { - let t = document.querySelector(this.el.dataset.target) - if (this.el.dataset.postsNb > 4) t.scrollTo({top: t.scrollHeight, behavior: 'smooth'}); - - this.handleEvent("scroll", () => { - let t = document.querySelector(this.el.dataset.target); - if (this.el.childElementCount > 4 && (t.scrollHeight - t.scrollTop < t.clientHeight + 100)) { - t.scrollTo({top: t.scrollHeight, behavior: 'smooth'}); - } - }) - } -} + this.scrollElement(true); + this.handleEvent("scroll", this.scrollElement.bind(this)); + }, + scrollElement(firstScroll) { + let t = this.el.parentElement; + if ( + firstScroll === true || + t.scrollHeight - t.scrollTop - t.clientHeight <= 100 + ) { + t.scrollTo({ top: t.scrollHeight, behavior: "smooth" }); + } + }, +}; Hooks.NicknamePicker = { mounted() { - let currentNickname = localStorage.getItem("nickname") || "" + let currentNickname = localStorage.getItem("nickname") || ""; if (currentNickname.length > 0) { - this.pushEvent("set-nickname", {nickname: currentNickname}) + this.pushEvent("set-nickname", { nickname: currentNickname }); } - this.el.addEventListener("click", (e) => this.clicked(e)) + this.el.addEventListener("click", (e) => this.clicked(e)); }, - destroy() { - this.el.removeEventListener("click", (e) => this.clicked(e)) + destroyed() { + this.el.removeEventListener("click", (e) => this.clicked(e)); }, clicked(e) { - let nickname = prompt(this.el.dataset.prompt, localStorage.getItem("nickname") || "") + let nickname = prompt( + this.el.dataset.prompt, + localStorage.getItem("nickname") || "" + ); if (nickname) { - localStorage.setItem("nickname", nickname) - this.pushEvent("set-nickname", {nickname: nickname}) + localStorage.setItem("nickname", nickname); + this.pushEvent("set-nickname", { nickname: nickname }); } }, -} +}; Hooks.EmptyNickname = { mounted() { - this.el.addEventListener("click", (e) => this.clicked(e)) + this.el.addEventListener("click", (e) => this.clicked(e)); }, - destroy() { - this.el.removeEventListener("click", (e) => this.clicked(e)) + destroyed() { + this.el.removeEventListener("click", (e) => this.clicked(e)); }, clicked(e) { - localStorage.removeItem("nickname") + localStorage.removeItem("nickname"); }, -} +}; Hooks.PostForm = { onPress(e, submitBtn, TA) { if (e.key == "Enter" && !e.shiftKey) { - e.preventDefault() - submitBtn.click() + e.preventDefault(); + submitBtn.click(); } else { if (TA.value.length > 1 && TA.value.length < 256) { - submitBtn.classList.remove("opacity-50") - submitBtn.classList.add("opacity-100") - submitBtn.disabled = false + submitBtn.classList.remove("opacity-50"); + submitBtn.classList.add("opacity-100"); + submitBtn.disabled = false; } else { - submitBtn.classList.add("opacity-50") - submitBtn.classList.remove("opacity-100") - submitBtn.disabled = true + submitBtn.classList.add("opacity-50"); + submitBtn.classList.remove("opacity-100"); + submitBtn.disabled = true; } } }, onSubmit(e, TA) { - e.preventDefault() - document.getElementById("hiddenSubmit").click() - TA.value = "" + e.preventDefault(); + document.getElementById("hiddenSubmit").click(); + TA.value = ""; }, mounted() { setTimeout(() => { - const submitBtn = document.getElementById("submitBtn") - const TA = document.getElementById("postFormTA") + const submitBtn = document.getElementById("submitBtn"); + const TA = document.getElementById("postFormTA"); if (submitBtn && TA) { - submitBtn.addEventListener("click", (e) => this.onSubmit(e, TA)) - TA.addEventListener("keydown", (e) => this.onPress(e, submitBtn, TA)) + submitBtn.addEventListener("click", (e) => this.onSubmit(e, TA)); + TA.addEventListener("keydown", (e) => this.onPress(e, submitBtn, TA)); } - }, 500) - + }, 500); + // set nickname if present - let nickname = this.el.dataset.nickname + let nickname = this.el.dataset.nickname; if (nickname) { - localStorage.setItem("nickname", nickname) + localStorage.setItem("nickname", nickname); } }, updated() { - const submitBtn = document.getElementById("submitBtn") - const TA = document.getElementById("postFormTA") + const submitBtn = document.getElementById("submitBtn"); + const TA = document.getElementById("postFormTA"); if (TA.value.length > 1 && TA.value.length < 256) { - submitBtn.classList.remove("opacity-50") - submitBtn.classList.add("opacity-100") - submitBtn.disabled = false + submitBtn.classList.remove("opacity-50"); + submitBtn.classList.add("opacity-100"); + submitBtn.disabled = false; } else { - submitBtn.classList.add("opacity-50") - submitBtn.classList.remove("opacity-100") - submitBtn.disabled = true + submitBtn.classList.add("opacity-50"); + submitBtn.classList.remove("opacity-100"); + submitBtn.disabled = true; } }, destroyed() { - const submitBtn = document.getElementById("submitBtn") - const TA = document.getElementById("postFormTA") + const submitBtn = document.getElementById("submitBtn"); + const TA = document.getElementById("postFormTA"); if (submitBtn && TA) { - TA.removeEventListener("keydown", (e) => this.onPress(e, submitBtn, TA)) - submitBtn.removeEventListener("click", (e) => this.onSubmit(e, TA)) + TA.removeEventListener("keydown", (e) => this.onPress(e, submitBtn, TA)); + submitBtn.removeEventListener("click", (e) => this.onSubmit(e, TA)); } - } -} + }, +}; Hooks.CalendarLocalDate = { mounted() { - this.el.innerHTML = moment.utc(this.el.dataset.date).local().calendar() + this.el.innerHTML = moment.utc(this.el.dataset.date).local().calendar(); }, updated() { - this.el.innerHTML = moment.utc(this.el.dataset.date).local().calendar() - } -} + this.el.innerHTML = moment.utc(this.el.dataset.date).local().calendar(); + }, +}; Hooks.Pickr = { mounted() { - const getDefaultDate = (dateStart, dateEnd, mode) => { - if (mode == "range") { - return moment.utc(dateStart).format('Y-MM-DD HH:mm') + " - " + moment.utc(dateEnd).format('Y-MM-DD HH:mm') - } else { - return moment.utc(dateStart).format('Y-MM-DD HH:mm') - } - }; - this.pickr = flatpickr(this.el, { - wrap: true, - inline: false, - enableTime: true, - enable: JSON.parse(this.el.dataset.enable), - time_24hr: true, - formatDate: (date, format, locale) => { - return moment(date).utc().format('Y-MM-DD HH:mm'); - }, - parseDate: (datestr, format) => { - return moment.utc(datestr).local().toDate(); + const localTime = this.el.querySelector("input[type=text]"); + const utcTime = this.el.querySelector("input[type=hidden]"); + localTime.value = moment + .utc(utcTime.value) + .local() + .format("DD-MM-YYYY HH:mm"); + this.pickr = new AirDatepicker(localTime, { + dateFormat: "dd-MM-yyyy", + timepicker: true, + minutesStep: 5, + minDate: moment(), + timeFormat: "HH:mm", + selectedDates: [moment(localTime.value, "DD-MM-YYYY HH:mm").toDate()], + onSelect: ({ date }) => { + const utc = moment(date).utc().format("YYYY-MM-DDTHH:mm:ss"); + utcTime.value = utc; }, - locale: { - firstDayOfWeek: 1, - rangeSeparator: ' - ' - }, - mode: this.el.dataset.mode == "range" ? "range" : "single", - minuteIncrement: 1, - dateFormat: "Y-m-d H:i", - defaultDate: getDefaultDate(this.el.dataset.defaultDateStart, this.el.dataset.defaultDateEnd, this.el.dataset.mode) - }) - }, - updated() { + locale: airdatepickerLocale[locale], + }); }, + updated() {}, destroyed() { - this.pickr.destroy() - } -} + this.pickr.destroy(); + }, +}; Hooks.Presenter = { mounted() { - this.presenter = new Presenter(this) - this.presenter.init() - } -} + this.presenter = new Presenter(this); + this.presenter.init(); + }, +}; Hooks.Manager = { mounted() { - this.manager = new Manager(this) - this.manager.init() + this.manager = new Manager(this); + this.manager.init(); }, updated() { - this.manager.update() - } -} + this.manager.update(); + }, +}; Hooks.OpenPresenter = { open(e) { - e.preventDefault() - window.open(this.el.dataset.url, 'newwindow', - 'width=' + window.screen.width + ',height=' + window.screen.height) + e.preventDefault(); + window.open( + this.el.dataset.url, + "newwindow", + "width=" + window.screen.width + ",height=" + window.screen.height + ); }, mounted() { - this.el.addEventListener("click", e => this.open(e)) + this.el.addEventListener("click", (e) => this.open(e)); }, updated() { - this.el.removeEventListener("click", e => this.open(e)) - this.el.addEventListener("click", e => this.open(e)) + this.el.removeEventListener("click", (e) => this.open(e)); + this.el.addEventListener("click", (e) => this.open(e)); }, destroyed() { - this.el.removeEventListener("click", e => this.open(e)) - } -} + this.el.removeEventListener("click", (e) => this.open(e)); + }, +}; Hooks.GlobalReacts = { mounted() { - - this.handleEvent('global-react', data => { + this.handleEvent("global-react", (data) => { var img = document.createElement("img"); - img.src = "/images/icons/" + data.type + ".svg" - img.className = "react-animation absolute transform opacity-0" + this.el.className - this.el.appendChild(img) - }) - this.handleEvent('reset-global-react', data => { - this.el.innerHTML = "" - }) - } -} + img.src = "/images/icons/" + data.type + ".svg"; + img.className = + "react-animation absolute transform opacity-0" + this.el.className; + this.el.appendChild(img); + }); + this.handleEvent("reset-global-react", (data) => { + this.el.innerHTML = ""; + }); + }, +}; Hooks.JoinEvent = { mounted() { - const loading = document.getElementById("loading") - const submit = document.getElementById("submit") - const input = document.getElementById("input") + const loading = document.getElementById("loading"); + const submit = document.getElementById("submit"); + const input = document.getElementById("input"); submit.addEventListener("click", (e) => { if (input.value.length > 0) { - submit.style.display = "none" - loading.style.display = "block" + submit.style.display = "none"; + loading.style.display = "block"; } - }) + }); }, destroyed() { - const loading = document.getElementById("loading") - const submit = document.getElementById("submit") - const input = document.getElementById("input") + const loading = document.getElementById("loading"); + const submit = document.getElementById("submit"); + const input = document.getElementById("input"); submit.removeEventListener("click", (e) => { if (input.value.length > 0) { - submit.style.display = "none" - loading.style.display = "block" + submit.style.display = "none"; + loading.style.display = "block"; } - }) - } -} + }); + }, +}; Hooks.WelcomeEarly = { mounted() { - if (localStorage.getItem("welcome-early") !== "false") { - this.el.style.display = "block" + this.el.style.display = "block"; this.el.children[0].addEventListener("click", (e) => { - e.preventDefault() - localStorage.setItem("welcome-early", "false") - this.el.style.display = "none" - }) + e.preventDefault(); + localStorage.setItem("welcome-early", "false"); + this.el.style.display = "none"; + }); } - }, destroyed() { this.el.children[0].removeEventListener("click", (e) => { - e.preventDefault() - localStorage.setItem("welcome-early", "false") - this.el.style.display = "none" - }) - } -} -Hooks.DefaultValue = { - mounted() { - this.el.value = moment(this.el.dataset.defaultValue ? this.el.dataset.defaultValue : undefined).utc().format(); - } -} + e.preventDefault(); + localStorage.setItem("welcome-early", "false"); + this.el.style.display = "none"; + }); + }, +}; Hooks.ClickFeedback = { clicked(e) { this.el.className = "animate__animated animate__rubberBand animate__faster"; setTimeout(() => { this.el.className = ""; - } , 500); + }, 500); }, mounted() { - this.el.addEventListener("click", (e) => this.clicked(e)) + this.el.addEventListener("click", (e) => this.clicked(e)); }, - destroy() { - this.el.removeEventListener("click", (e) => this.clicked(e)) - } -} + destroyed() { + this.el.removeEventListener("click", (e) => this.clicked(e)); + }, +}; Hooks.QRCode = { draw() { - var url = this.el.dataset.code ? window.location.protocol + "//" + window.location.host + "/e/" + this.el.dataset.code : window.location.href; - this.el.style.width = document.documentElement.clientWidth * .27 + "px" - this.el.style.height = document.documentElement.clientWidth * .27 + "px" + var url = this.el.dataset.code + ? window.location.protocol + + "//" + + window.location.host + + "/e/" + + this.el.dataset.code + : window.location.href; + this.el.style.width = document.documentElement.clientWidth * 0.27 + "px"; + this.el.style.height = document.documentElement.clientWidth * 0.27 + "px"; if (this.qrCode == null) { this.qrCode = new QRCodeStyling({ - width: this.el.dataset.dynamic ? document.documentElement.clientWidth * .25 : 240, - height: this.el.dataset.dynamic ? document.documentElement.clientWidth * .25 : 240, + width: this.el.dataset.dynamic + ? document.documentElement.clientWidth * 0.25 + : 240, + height: this.el.dataset.dynamic + ? document.documentElement.clientWidth * 0.25 + : 240, margin: 0, data: url, cornersSquareOptions: { - type: "square" + type: "square", }, dotsOptions: { type: "square", @@ -342,113 +443,133 @@ Hooks.QRCode = { imageOptions: { crossOrigin: "anonymous", imageSize: 0.6, - margin: 10 - } - }) - this.qrCode.append(this.el) + margin: 10, + }, + }); + this.qrCode.append(this.el); } else { this.qrCode.update({ - width: this.el.dataset.dynamic ? document.documentElement.clientWidth * .25 : 240, - height: this.el.dataset.dynamic ? document.documentElement.clientWidth * .25 : 240 - }) + width: this.el.dataset.dynamic + ? document.documentElement.clientWidth * 0.25 + : 240, + height: this.el.dataset.dynamic + ? document.documentElement.clientWidth * 0.25 + : 240, + }); } - }, mounted() { window.addEventListener("resize", this.draw.bind(this)); - this.draw() + this.draw(); if (this.el.dataset.getUrl) { setTimeout(() => { - var dataURL = this.qrCode._canvas.toDataURL() - document.getElementById("qr-url").value = dataURL - }, 500); + var dataURL = this.qrCode._canvas.toDataURL(); + document.getElementById("qr-url").value = dataURL; + }, 500); } }, - updated() { + updated() {}, + destroyed() {}, +}; + +Hooks.Dropdown = { + mounted() { + this.el.addEventListener("click", (e) => { + e.preventDefault(); + this.el.classList.toggle("hidden"); + }); }, - destroyed() { - } -} - -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() +}; + +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) } + if (event.lengthComputable) { + let percent = Math.round((event.loaded / event.total) * 100); + if (percent < 100) { + entry.progress(percent); + } } - }) - - xhr.open("POST", url, true) - xhr.send(formData) - }) -} + }); + xhr.open("POST", url, true); + xhr.send(formData); + }); +}; let liveSocket = new LiveSocket("/live", Socket, { uploaders: Uploaders, - params: {_csrf_token: csrfToken, tz: Intl.DateTimeFormat().resolvedOptions().timeZone, host: window.location.host}, + params: { + _csrf_token: csrfToken, + tz: Intl.DateTimeFormat().resolvedOptions().timeZone, + host: window.location.host, + }, hooks: Hooks, dom: { - onBeforeElUpdated(from, to){ - if(from._x_dataStack){ - window.Alpine.clone(from, to) - window.Alpine.initTree(to) + onBeforeElUpdated(from, to) { + if (from._x_dataStack) { + window.Alpine.clone(from, to); + window.Alpine.initTree(to); } - } - },}) + }, + }, +}); // Show progress bar on live navigation and form submits -let topBarScheduled = undefined -topbar.config({barColors: {0: "#fff"}, shadowColor: "rgba(0, 0, 0, .3)"}) -window.addEventListener("phx:page-loading-start", info => { - if(!topBarScheduled) { - topBarScheduled = setTimeout(() => topbar.show(), 500) +let topBarScheduled = undefined; +topbar.config({ barColors: { 0: "#fff" }, shadowColor: "rgba(0, 0, 0, .3)" }); +window.addEventListener("phx:page-loading-start", (info) => { + if (!topBarScheduled) { + topBarScheduled = setTimeout(() => topbar.show(), 500); } -}) -window.addEventListener("phx:page-loading-stop", info => { - clearTimeout(topBarScheduled) - topBarScheduled = undefined - topbar.hide() -}) - -const renderOnlineUsers = function(presences) { - let onlineUsers = Presence.list(presences, (_id, {metas: [user, ...rest]}) => { - return onlineUserTemplate(user); - }).join("") +}); +window.addEventListener("phx:page-loading-stop", (info) => { + clearTimeout(topBarScheduled); + topBarScheduled = undefined; + topbar.hide(); +}); + +const renderOnlineUsers = function (presences) { + let onlineUsers = Presence.list( + presences, + (_id, { metas: [user, ...rest] }) => { + return onlineUserTemplate(user); + } + ).join(""); document.querySelector("body").innerHTML = onlineUsers; -} +}; -const onlineUserTemplate = function(user) { +const onlineUserTemplate = function (user) { return `
aaa
- ` -} + `; +}; let presences = {}; -liveSocket.on("presence_state", state => { - presences = Presence.syncState(presences, state) - renderOnlineUsers(presences) -}) +liveSocket.on("presence_state", (state) => { + presences = Presence.syncState(presences, state); + renderOnlineUsers(presences); +}); // connect if there are any LiveViews on the page -liveSocket.connect() +liveSocket.connect(); // expose liveSocket on window for web console debug logs and latency simulation: // >> liveSocket.enableDebug() // >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session // >> liveSocket.disableLatencySim() -window.liveSocket = liveSocket \ No newline at end of file +window.liveSocket = liveSocket; diff --git a/assets/js/manager.js b/assets/js/manager.js index 158255c..b138312 100644 --- a/assets/js/manager.js +++ b/assets/js/manager.js @@ -15,8 +15,9 @@ export class Manager { if (el) { setTimeout(() => { - document.getElementById("slide-preview-" + data.current_page).scrollIntoView({ - block: 'center', + document.getElementById("slides").scrollTo({ + top: el.offsetTop - el.scrollHeight, + left: 0, behavior: 'smooth' }); }, data.timeout ? data.timeout : 0) @@ -51,10 +52,13 @@ export class Manager { var el = document.getElementById("slide-preview-" + this.currentPage) if (el) { - document.getElementById("slide-preview-" + this.currentPage).scrollIntoView({ - block: 'center', - behavior: 'smooth' - }); + setTimeout(() => { + document.getElementById("slides").scrollTo({ + top: el.offsetTop - el.scrollHeight, + left: 0, + behavior: 'smooth' + }); + }, 50) } } diff --git a/assets/package-lock.json b/assets/package-lock.json index 74357c5..5ae5a83 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -1,6 +1,1717 @@ { + "name": "assets", + "lockfileVersion": 2, "requires": true, - "lockfileVersion": 1, + "packages": { + "": { + "dependencies": { + "@sjmc11/tourguidejs": "^0.0.16", + "air-datepicker": "^3.5.0", + "animate.css": "^4.1.1", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "phoenix": "file:../deps/phoenix", + "phoenix_html": "file:../deps/phoenix_html", + "phoenix_live_view": "file:../deps/phoenix_live_view", + "qr-code-styling": "^1.6.0-rc.1", + "split-grid": "^1.0.11", + "split.js": "^1.6.5", + "tiny-slider": "^2.9.4" + }, + "devDependencies": { + "alpinejs": "^3.13.8", + "autoprefixer": "^10.4.19", + "esbuild": "^0.20.2", + "postcss": "^8.4.38", + "postcss-import": "^15.1.0", + "tailwindcss": "^3.3.3" + } + }, + "../deps/phoenix": { + "version": "1.7.11", + "license": "MIT" + }, + "../deps/phoenix_html": { + "version": "4.1.0" + }, + "../deps/phoenix_live_view": { + "version": "0.20.14", + "license": "MIT", + "devDependencies": { + "@playwright/test": "^1.41.0" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "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==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "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==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sjmc11/tourguidejs": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@sjmc11/tourguidejs/-/tourguidejs-0.0.16.tgz", + "integrity": "sha512-NpK7OyW1l0R1XCajbWp+ibJAJbQK7dpBfqy+Etcy4fj/+qk3JPKY8RwoSX1UzzfBauuriNKJiv1KmTB3RHajQg==", + "dependencies": { + "@floating-ui/dom": "^1.0.3", + "sass": "^1.55.0" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "dev": true, + "dependencies": { + "@vue/shared": "3.1.5" + } + }, + "node_modules/@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", + "dev": true + }, + "node_modules/air-datepicker": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/air-datepicker/-/air-datepicker-3.5.0.tgz", + "integrity": "sha512-WOpn1MaSl5drcXSwkXg5Gh/jXX/VFfamNnIb8E43AY4UKuW/bNEW06e3GGsiWLDBQLabD22L6b6cP7KHnAy54w==" + }, + "node_modules/alpinejs": { + "version": "3.13.8", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.8.tgz", + "integrity": "sha512-XolbBJryCndomtaHd/KHQjQeD/L72FJxy/YhLLFD4Lr7zzGcpcbg+UgXteMR2pYg1KhRUr6V4O3GfN1zJAmRWw==", + "dev": true, + "dependencies": { + "@vue/reactivity": "~3.1.1" + } + }, + "node_modules/animate.css": { + "version": "4.1.1", + "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==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "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" + } + ], + "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" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "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==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "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==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "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/fast-glob/node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "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==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "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==", + "dev": true, + "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", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "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==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "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==", + "dev": true, + "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", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", + "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "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==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "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", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/phoenix": { + "resolved": "../deps/phoenix", + "link": true + }, + "node_modules/phoenix_html": { + "resolved": "../deps/phoenix_html", + "link": true + }, + "node_modules/phoenix_live_view": { + "resolved": "../deps/phoenix_live_view", + "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==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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", + "integrity": "sha512-ModRIiW6oUnsP18QzrRYZSc/CFKFKIdj7pUs57AEVH20ajlglRpN3HukjHk0UbNMTlKGuaYl7Gt6/O5Gg2NU2Q==", + "dependencies": { + "qrcode-generator": "^1.4.3" + } + }, + "node_modules/qrcode-generator": { + "version": "1.4.4", + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-grid": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/split-grid/-/split-grid-1.0.11.tgz", + "integrity": "sha512-ELtFtxc3r5we5GZfe6Fi0BFFxIi2M6BY1YEntBscKRDD3zx4JVHqx2VnTRSQu1BixCYSTH3MTjKd4esI2R7EgQ==" + }, + "node_modules/split.js": { + "version": "1.6.5", + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tiny-slider": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/tiny-slider/-/tiny-slider-2.9.4.tgz", + "integrity": "sha512-LAs2kldWcY+BqCKw4kxd4CMx2RhWrHyEePEsymlOIISTlOVkjfK40sSD7ay73eKXBLg/UkluAZpcfCstimHXew==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "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==", + "dev": true + }, + "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==", + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + } + }, "dependencies": { "@alloc/quick-lru": { "version": "5.2.0", @@ -8,13 +1719,189 @@ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "dev": true }, + "@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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "dev": true, + "optional": true + }, "@esbuild/linux-loong64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", - "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", "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==", + "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==", + "dev": true, + "optional": true + }, + "@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "requires": { + "@floating-ui/utils": "^0.2.1" + } + }, + "@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "requires": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/utils": { + "version": "0.2.1", + "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", @@ -80,6 +1967,15 @@ "fastq": "^1.6.0" } }, + "@sjmc11/tourguidejs": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@sjmc11/tourguidejs/-/tourguidejs-0.0.16.tgz", + "integrity": "sha512-NpK7OyW1l0R1XCajbWp+ibJAJbQK7dpBfqy+Etcy4fj/+qk3JPKY8RwoSX1UzzfBauuriNKJiv1KmTB3RHajQg==", + "requires": { + "@floating-ui/dom": "^1.0.3", + "sass": "^1.55.0" + } + }, "@vue/reactivity": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", @@ -95,10 +1991,15 @@ "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==", "dev": true }, + "air-datepicker": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/air-datepicker/-/air-datepicker-3.5.0.tgz", + "integrity": "sha512-WOpn1MaSl5drcXSwkXg5Gh/jXX/VFfamNnIb8E43AY4UKuW/bNEW06e3GGsiWLDBQLabD22L6b6cP7KHnAy54w==" + }, "alpinejs": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.2.tgz", - "integrity": "sha512-WzojeeN082kLZznGI1HAuP8yFJSWqJ1fGdz2mUjj45H4y0XwToE7fFqtI3mCPRR+BpcSbxT/NL+FyPnYAWSltw==", + "version": "3.13.8", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.8.tgz", + "integrity": "sha512-XolbBJryCndomtaHd/KHQjQeD/L72FJxy/YhLLFD4Lr7zzGcpcbg+UgXteMR2pYg1KhRUr6V4O3GfN1zJAmRWw==", "dev": true, "requires": { "@vue/reactivity": "~3.1.1" @@ -115,6 +2016,15 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -122,14 +2032,14 @@ "dev": true }, "autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "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.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "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" @@ -141,6 +2051,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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", @@ -151,15 +2066,23 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, "browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" } }, @@ -170,11 +2093,26 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001551", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", - "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", + "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 }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -206,184 +2144,46 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.563", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.563.tgz", - "integrity": "sha512-dg5gj5qOgfZNkPNeyKBZQAQitIQ/xwfIDmEQJHCbXaD9ebTZxwJXUsDYcBlAvZGZLi+/354l35J1wkmP6CqYaw==", + "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 }, "esbuild": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", - "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "requires": { - "@esbuild/linux-loong64": "0.14.54", - "esbuild-android-64": "0.14.54", - "esbuild-android-arm64": "0.14.54", - "esbuild-darwin-64": "0.14.54", - "esbuild-darwin-arm64": "0.14.54", - "esbuild-freebsd-64": "0.14.54", - "esbuild-freebsd-arm64": "0.14.54", - "esbuild-linux-32": "0.14.54", - "esbuild-linux-64": "0.14.54", - "esbuild-linux-arm": "0.14.54", - "esbuild-linux-arm64": "0.14.54", - "esbuild-linux-mips64le": "0.14.54", - "esbuild-linux-ppc64le": "0.14.54", - "esbuild-linux-riscv64": "0.14.54", - "esbuild-linux-s390x": "0.14.54", - "esbuild-netbsd-64": "0.14.54", - "esbuild-openbsd-64": "0.14.54", - "esbuild-sunos-64": "0.14.54", - "esbuild-windows-32": "0.14.54", - "esbuild-windows-64": "0.14.54", - "esbuild-windows-arm64": "0.14.54" - } - }, - "esbuild-android-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", - "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", - "dev": true, - "optional": true - }, - "esbuild-android-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", - "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", - "dev": true, - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", - "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", - "dev": true, - "optional": true - }, - "esbuild-darwin-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", - "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", - "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", - "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", - "dev": true, - "optional": true - }, - "esbuild-linux-32": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", - "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", - "dev": true, - "optional": true - }, - "esbuild-linux-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", - "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", - "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", - "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", - "dev": true, - "optional": true - }, - "esbuild-linux-mips64le": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", - "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", - "dev": true, - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", - "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", - "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", - "dev": true, - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", - "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", - "dev": true, - "optional": true - }, - "esbuild-netbsd-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", - "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", - "dev": true, - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", - "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", - "dev": true, - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", - "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", - "dev": true, - "optional": true - }, - "esbuild-windows-32": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", - "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", - "dev": true, - "optional": true - }, - "esbuild-windows-64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", - "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", - "dev": true, - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.14.54", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", - "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", - "dev": true, - "optional": true + "@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" + } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "fast-glob": { @@ -399,48 +2199,6 @@ "micromatch": "^4.0.4" }, "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -462,11 +2220,13 @@ "reusify": "^1.0.4" } }, - "flatpickr": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", - "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==", - "dev": true + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } }, "fraction.js": { "version": "4.3.7", @@ -480,12 +2240,26 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "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==", "dev": true }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, "hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -495,6 +2269,11 @@ "function-bind": "^1.1.2" } }, + "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", @@ -511,6 +2290,14 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "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", @@ -520,6 +2307,24 @@ "hasown": "^2.0.0" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "jiti": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", @@ -578,17 +2383,22 @@ } }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "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", @@ -635,7 +2445,10 @@ "version": "file:../deps/phoenix_html" }, "phoenix_live_view": { - "version": "file:../deps/phoenix_live_view" + "version": "file:../deps/phoenix_live_view", + "requires": { + "@playwright/test": "^1.41.0" + } }, "picocolors": { "version": "1.0.0", @@ -646,8 +2459,7 @@ "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pify": { "version": "2.3.0", @@ -662,14 +2474,14 @@ "dev": true }, "postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "requires": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "postcss-import": { @@ -755,6 +2567,14 @@ "pify": "^2.3.0" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -781,11 +2601,30 @@ "queue-microtask": "^1.2.2" } }, + "sass": { + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" + }, + "split-grid": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/split-grid/-/split-grid-1.0.11.tgz", + "integrity": "sha512-ELtFtxc3r5we5GZfe6Fi0BFFxIi2M6BY1YEntBscKRDD3zx4JVHqx2VnTRSQu1BixCYSTH3MTjKd4esI2R7EgQ==" + }, + "split.js": { + "version": "1.6.5", + "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", @@ -854,74 +2693,6 @@ "sucrase": "^3.32.0" }, "dependencies": { - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -931,30 +2702,6 @@ "is-glob": "^4.0.3" } }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -964,21 +2711,6 @@ "braces": "^3.0.2", "picomatch": "^2.3.1" } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } } } }, @@ -1009,17 +2741,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" - }, - "dependencies": { - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - } } }, "ts-interface-checker": { diff --git a/assets/package.json b/assets/package.json index 2f4c4a2..489c528 100644 --- a/assets/package.json +++ b/assets/package.json @@ -3,15 +3,16 @@ "deploy": "NODE_ENV=production tailwindcss --postcss --minify --input=css/app.css --output=../priv/static/assets/app.css" }, "devDependencies": { - "alpinejs": "^3.13.1", - "autoprefixer": "^10.4.15", - "esbuild": "^0.14.54", - "flatpickr": "^4.6.13", - "postcss": "^8.4.29", + "alpinejs": "^3.13.8", + "autoprefixer": "^10.4.19", + "esbuild": "^0.20.2", + "postcss": "^8.4.38", "postcss-import": "^15.1.0", "tailwindcss": "^3.3.3" }, "dependencies": { + "@sjmc11/tourguidejs": "^0.0.16", + "air-datepicker": "^3.5.0", "animate.css": "^4.1.1", "moment": "^2.29.4", "moment-timezone": "^0.5.43", @@ -19,6 +20,8 @@ "phoenix_html": "file:../deps/phoenix_html", "phoenix_live_view": "file:../deps/phoenix_live_view", "qr-code-styling": "^1.6.0-rc.1", + "split-grid": "^1.0.11", + "split.js": "^1.6.5", "tiny-slider": "^2.9.4" } -} +} \ No newline at end of file diff --git a/config/config.exs b/config/config.exs index b59c3ce..d15426b 100644 --- a/config/config.exs +++ b/config/config.exs @@ -21,7 +21,7 @@ config :claper, ClaperWeb.Gettext, locales: ~w(fr en de) config :dart_sass, - version: "1.58.0", + version: "1.61.0", default: [ args: ~w(css/custom.scss ../priv/static/assets/custom.css), cd: Path.expand("../assets", __DIR__) diff --git a/config/runtime.exs b/config/runtime.exs index cfcdc70..5ad65c6 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -41,8 +41,18 @@ case secret_key_base do nil end -endpoint_host = get_var_from_path_or_env(config_dir, "ENDPOINT_HOST", "localhost") -endpoint_port = get_int_from_path_or_env(config_dir, "ENDPOINT_PORT", 4000) +site_url = get_var_from_path_or_env(config_dir, "SITE_URL", "http://localhost:4000") +base_url = get_var_from_path_or_env(config_dir, "BASE_URL") + +if !base_url do + raise "BASE_URL configuration option is required. See https://docs.claper.co/configuration.html#production-docker" +end + +base_url = URI.parse(base_url) + +if base_url.scheme not in ["http", "https"] do + raise "BASE_URL must start with `http` or `https`. Currently configured as `#{System.get_env("BASE_URL")}`" +end max_file_size = get_int_from_path_or_env(config_dir, "MAX_FILE_SIZE_MB", 15) @@ -67,6 +77,11 @@ aws_access_key_id = get_var_from_path_or_env(config_dir, "AWS_ACCESS_KEY_ID", ni 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) +same_site_cookie = get_var_from_path_or_env(config_dir, "SAME_SITE_COOKIE", "Lax") + +secure_cookie = + get_var_from_path_or_env(config_dir, "SECURE_COOKIE", "false") |> String.to_existing_atom() + config :claper, Claper.Repo, url: database_url, ssl: db_ssl, @@ -78,17 +93,16 @@ config :claper, Claper.Repo, queue_target: queue_target config :claper, ClaperWeb.Endpoint, - url: [ - host: endpoint_host, - port: endpoint_port - ], + url: [scheme: base_url.scheme, host: base_url.host, path: base_url.path, port: base_url.port], http: [ ip: listen_ip, port: port, transport_options: [max_connections: :infinity], protocol_options: [max_request_line_length: 8192, max_header_value_length: 8192] ], - secret_key_base: secret_key_base + secret_key_base: secret_key_base, + same_site_cookie: same_site_cookie, + secure_cookie: secure_cookie config :claper, enable_account_creation: enable_account_creation diff --git a/config/test.exs b/config/test.exs index 0a47223..a3d9540 100644 --- a/config/test.exs +++ b/config/test.exs @@ -11,7 +11,7 @@ config :claper, Claper.Repo, database: "claper_test#{System.get_env("MIX_TEST_PARTITION")}", hostname: "localhost", pool: Ecto.Adapters.SQL.Sandbox, - pool_size: 10 + pool_size: 1 # We don't run a server during test. If one is required, # you can enable the server option below. @@ -24,7 +24,7 @@ config :claper, ClaperWeb.Endpoint, config :claper, Claper.Mailer, adapter: Swoosh.Adapters.Test # Print only warnings and errors during test -config :logger, level: :warn +config :logger, level: :warning # Initialize plugs at runtime for faster test compilation config :phoenix, :plug_init_mode, :runtime diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml deleted file mode 100644 index 2e41cb4..0000000 --- a/docker-compose-dev.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: "3.0" -services: - db: - image: postgres:9 - ports: - - 5432:5432 - volumes: - - postgres-data:/var/lib/postgresql/data - environment: - POSTGRES_PASSWORD: claper - POSTGRES_USER: claper - POSTGRES_DB: claper - healthcheck: - test: ["CMD-SHELL", "pg_isready -U claper"] - interval: 5s - timeout: 5s - retries: 10 - app: - build: . - user: 0:0 - ports: - - 4000:4000 - volumes: - - uploads:/app/uploads - environment: - DATABASE_URL: postgres://claper:claper@db:5432/claper - SECRET_KEY_BASE: 0LZiQBLw4WvqPlz4cz8RsHJlxNiSqM9B48y4ChyJ5v1oA0L/TPIqRjQNdPZN3iEG - MAIL_TRANSPORT: local - ENDPOINT_PORT: 4000 - PRESENTATION_STORAGE: local - MAX_FILE_SIZE_MB: 15 - ENABLE_ACCOUNT_CREATION: true - depends_on: - db: - condition: service_healthy -volumes: - postgres-data: - uploads: diff --git a/docker-compose.yml b/docker-compose.yml index 721e398..c25890c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,37 +1,51 @@ -version: "3.0" services: db: - image: postgres:9 - ports: + image: postgres:15 + ports: - 5432:5432 volumes: - - ./postgres-data:/var/lib/postgresql/data + - "claper-db:/var/lib/postgresql/data" + healthcheck: + test: + - CMD + - pg_isready + - "-q" + - "-d" + - "claper" + - "-U" + - "claper" + retries: 3 + timeout: 5s environment: POSTGRES_PASSWORD: claper POSTGRES_USER: claper POSTGRES_DB: claper - healthcheck: - test: ["CMD-SHELL", "pg_isready -U claper"] - interval: 5s - timeout: 5s - retries: 10 + networks: + - claper-net app: - image: ghcr.io/claperco/claper:latest - user: 0:0 - ports: + image: ghcr.io/claperco/claper:latest # or build: . + ports: - 4000:4000 volumes: - - uploads:/app/uploads - environment: - DATABASE_URL: postgres://claper:claper@db:5432/claper - SECRET_KEY_BASE: 0LZiQBLw4WvqPlz4cz8RsHJlxNiSqM9B48y4ChyJ5v1oA0L/TPIqRjQNdPZN3iEG - MAIL_TRANSPORT: local - ENDPOINT_PORT: 4000 - PRESENTATION_STORAGE: local - MAX_FILE_SIZE_MB: 15 - ENABLE_ACCOUNT_CREATION: true + - "claper-uploads:/app/uploads" + healthcheck: + test: curl --fail http://localhost:4000 || exit 1 + retries: 3 + start_period: 20s + timeout: 5s + env_file: .env depends_on: db: condition: service_healthy + networks: + - claper-net + volumes: - uploads: \ No newline at end of file + claper-db: + driver: local + claper-uploads: + driver: local + +networks: + claper-net: + driver: bridge diff --git a/guides/assets/add-poll.gif b/guides/assets/add-poll.gif deleted file mode 100644 index 1a752fd..0000000 Binary files a/guides/assets/add-poll.gif and /dev/null differ diff --git a/guides/assets/card-event.png b/guides/assets/card-event.png deleted file mode 100644 index 77a55d6..0000000 Binary files a/guides/assets/card-event.png and /dev/null differ diff --git a/guides/assets/feature1.png b/guides/assets/feature1.png deleted file mode 100644 index 38df8c1..0000000 Binary files a/guides/assets/feature1.png and /dev/null differ diff --git a/guides/assets/feature2.png b/guides/assets/feature2.png deleted file mode 100644 index d2e1b8c..0000000 Binary files a/guides/assets/feature2.png and /dev/null differ diff --git a/guides/assets/logo-large.png b/guides/assets/logo-large.png deleted file mode 100644 index 6296869..0000000 Binary files a/guides/assets/logo-large.png and /dev/null differ diff --git a/guides/assets/messages.png b/guides/assets/messages.png deleted file mode 100644 index a733c6b..0000000 Binary files a/guides/assets/messages.png and /dev/null differ diff --git a/guides/assets/moderation-view.png b/guides/assets/moderation-view.png deleted file mode 100644 index 737544c..0000000 Binary files a/guides/assets/moderation-view.png and /dev/null differ diff --git a/guides/assets/new-form.png b/guides/assets/new-form.png deleted file mode 100644 index ae6effc..0000000 Binary files a/guides/assets/new-form.png and /dev/null differ diff --git a/guides/assets/preview.png b/guides/assets/preview.png deleted file mode 100644 index 8946578..0000000 Binary files a/guides/assets/preview.png and /dev/null differ diff --git a/guides/introduction/configuration.md b/guides/introduction/configuration.md deleted file mode 100644 index 3284c04..0000000 --- a/guides/introduction/configuration.md +++ /dev/null @@ -1,55 +0,0 @@ -# Configuration - -## Environment file - -All configuration used by the app is stored in the `.env` file. You can find an example file in `.env.sample`, but you should copy it to `.env` and fill it with your own values (described below). - -### Storage - -Variable | Values | Default | Required | Description ---- | --- | --- | --- | --- -PRESENTATION_STORAGE | local, s3 | local | - | Define where the presentation files will be stored -PRESENTATION_STORAGE_DIR | - | priv/static (/app/uploads for Docker) | - | If `local` storage is used, this is the directory where the presentation files will be stored. Compile-time config, so you need to recompile the app if you change it (or rebuild the Docker image). -AWS_ACCESS_KEY_ID | - | - | _only for s3_ | Your AWS Access Key ID -AWS_SECRET_ACCESS_KEY | - | - | _only for s3_ | Your AWS Secret Access Key -AWS_PRES_BUCKET | - | - | _only for s3_ | The name of the bucket where the presentation files will be stored -AWS_REGION | - | - | _only for s3_ | The region where the bucket is located - -### Mail - -Variable | Values | Default | Required | Description ---- | --- | --- | --- | --- -MAIL_TRANSPORT | local, smtp, postmark | local | - | Define how the emails will be sent -MAIL_FROM | - | Claper | - | Email address used to send emails -MAIL_FROM_NAME | - | noreply@claper.co | - | Name used to send emails -SMTP_RELAY | - | - | _only for smtp_ | SMTP relay server -SMTP_USERNAME | - | - | _only for smtp_ | SMTP username -SMTP_PASSWORD | - | - | _only for smtp_ | SMTP password -SMTP_PORT | - | 25 | - | SMTP port -SMTP_TLS | always, never, if_available | always | - | SMTP TLS -SMTP_AUTH | always, never, if_available | always | - | SMTP Auth -SMTP_SSL | true, false | true | - | SMTP SSL -ENABLE_MAILBOX_ROUTE | true, false | false | - | Enable/disable route to local mailbox (`/dev/mailbox`) -MAILBOX_USER | - | - | - | Basic auth user for mailbox route -MAILBOX_PASSWORD | - | - | - | Basic auth password for mailbox route -POSTMARK_API_KEY | - | - | _only for postmark_ | Postmark API key - -### Application - -Variable | Values | Default | Required | Description ---- | --- | --- | --- | --- -ENABLE_ACCOUNT_CREATION | true, false | true | - | Enable/disable user registration -MAX_FILE_SIZE_MB | - | 15 | - | Max file size to upload in MB -GS_JPG_RESOLUTION | - | 300x300 | - | Resolution (DPI) of the JPG generated from PDF, higher resolution means bigger files but better quality - -## Production / Docker - -You can use all local variables plus the following: - -Variable | Values | Default | Required | Description ---- | --- | --- | --- | --- -DATABASE_URL | - | - | ✓ | Postgres connection string -SECRET_KEY_BASE | - | - | ✓ | Generate it with `mix phx.gen.secret` -ENDPOINT_HOST | - | localhost | - | Host used to access the app (used for url generation) -ENDPOINT_PORT | - | 80 | - | Port used to access the app (used for url generation) -PORT | - | 4000 | - | Port to listen to diff --git a/guides/introduction/deployment.md b/guides/introduction/deployment.md deleted file mode 100644 index 6a4926b..0000000 --- a/guides/introduction/deployment.md +++ /dev/null @@ -1,150 +0,0 @@ -# Deployment - -## Prerequisites - -To run Claper on your production environment you need to have: -* Postgres >= 9 -* Elixir >= 1.13.2 -* Erlang >= 24 -* NPM >= 6.14.17 -* NodeJS >= 14.19.2 -* Ghostscript >= 9.5.0 (for PDF support) -* Libreoffice >= 6.4 (for PPT/PPTX support) - - -## Steps (without docker) - -1. Clone the repo - ```sh - git clone https://github.com/ClaperCo/Claper.git - ``` -2. Install dependencies - ```sh - mix deps.get --only prod - ``` -3. Migrate your database - ```sh - mix ecto.migrate - ``` -4. Compile assets - ```sh - MIX_ENV=prod mix compile - ``` -5. Deploy assets - ```sh - MIX_ENV=prod mix assets.deploy - ``` -6. Start Phoenix endpoint with - ```sh - MIX_ENV=prod mix phx.server - ``` - -You can follow the steps from the official Phoenix guide for further details and release management: [Introduction to Deployement](https://hexdocs.pm/phoenix/deployment.html) and [Deploying with Releases](https://hexdocs.pm/phoenix/releases.html). - -## Steps (with docker) - -You can follow the same steps as in the [installation guide](/installation.html#using-docker) to run Claper with Docker. - -## Behind Nginx - -This an example of Nginx configuration file to run Claper behind Nginx. - -```nginx -server { - listen 80; - server_name app.claper.co; # Your own domain - - location / { - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - proxy_pass http://localhost:4000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -``` - -## Behind Traefik - -Here is a docker-compose example to run Claper behind Traefik. - -```yaml -version: "3.0" -services: - db: - image: postgres:9 - environment: - POSTGRES_PASSWORD: claper - POSTGRES_USER: claper - POSTGRES_DB: claper - app: - build: . - environment: - DATABASE_URL: postgres://claper:claper@db:5432/claper - SECRET_KEY_BASE: 0LZiQBLw4WvqPlz4cz8RsHJlxNiSqM9B48y4ChyJ5v1oA0L/TPIqRjQNdPZN3iEG - MAIL_TRANSPORT: local - ENDPOINT_HOST: claper.local - ENDPOINT_PORT: 4000 - labels: - - "traefik.enable=true" - - "traefik.http.routers.claper.rule=Host(`claper.local`)" - - "traefik.http.routers.claper.entrypoints=web" - depends_on: - - db - - traefik - - traefik: - image: traefik - command: - #- "--log.level=DEBUG" - - "--api.insecure=true" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - ports: - - "80:80" - - "8080:8080" -``` - -## Behind Kubernetes - -Change the `rel/env.sh.eex` file to uncomment: - -```sh -export POD_A_RECORD=$(echo $POD_IP | sed 's/\./-/g') -export RELEASE_DISTRIBUTION=name -export RELEASE_NODE=<%= @release.name %>@$(echo $POD_A_RECORD).$(echo $NAMESPACE).pod.cluster.local -``` - -and comment as follows: - -```sh -#export RELEASE_DISTRIBUTION=sname -#export RELEASE_NODE=<%= @release.name %> -``` - -In Kubernetes, you have to use `libcluster` to make the nodes discoverable. You can use the following configuration in your `config/prod.exs`: - -```elixir -config :libcluster, - topologies: [ - default: [ - strategy: Cluster.Strategy.Kubernetes, - config: [ - mode: :dns, - kubernetes_node_basename: "claper", - kubernetes_selector: "app=claper", - kubernetes_namespace: "default", - polling_interval: 10_000 - ] - ] - ] -``` - -### Helm chart - -You can check the [Claper Helm chart](https://github.com/ClaperCo/Claper/tree/main/charts/claper) to deploy Claper on Kubernetes. diff --git a/guides/introduction/installation.md b/guides/introduction/installation.md deleted file mode 100644 index b6008dc..0000000 --- a/guides/introduction/installation.md +++ /dev/null @@ -1,72 +0,0 @@ -# Local installation - -## Prerequisites - -To run Claper on your local environment you need to have: -* Postgres >= 9 -* Elixir >= 1.13.2 -* Erlang >= 24 -* NPM >= 6.14.17 -* NodeJS >= 14.19.2 -* Ghostscript >= 9.5.0 (for PDF support) -* Libreoffice >= 6.4 (for PPT/PPTX support) - -You can also use Docker to easily run a Postgres instance: -```sh - docker run -p 5432:5432 -e POSTGRES_PASSWORD=claper -e POSTGRES_USER=claper -e POSTGRES_DB=claper --name claper-db -d postgres:9 - ``` - -1. Clone the repo - ```sh - git clone https://github.com/ClaperCo/Claper.git - ``` -2. Install dependencies - ```sh - mix deps.get - ``` -3. Migrate your database - ```sh - mix ecto.migrate - ``` -4. Install JS dependencies - ```sh - cd assets && npm i - ``` -5. Allow execution of startup file - ```sh - chmod +x ./start.sh - ``` -6. Start Phoenix endpoint with - ```sh - ./start.sh - ``` - -Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. - -If you have configured `MAIL` to `local`, you can access to the mailbox at [`localhost:4000/dev/mailbox`](http://localhost:4000/dev/mailbox). - - -## Using Docker Compose - -A Docker Compose [reference file](https://github.com/ClaperCo/Claper/blob/main/docker-compose.yml) is provided in the repository. You can use it to run Claper with Docker Compose. - -```sh -git clone https://github.com/ClaperCo/Claper.git -cd Claper -docker compose up -``` - -## Using Docker Compose for Dev - -To easy check new features, it is possible to directly build the Docker image from the source code and run the container with the [docker-compose-dev.yml](https://github.com/ClaperCo/Claper/blob/main/docker-compose-dev.yml) file. - -```sh -git clone https://github.com/ClaperCo/Claper.git -cd Claper -docker compose -f docker-compose-dev.yml up -``` - - -### ARM architecture - -If you are using an ARM architecture (like Apple M1), the original Docker image won't work. You can build the image yourself by replacing the `BUILDER_IMAGE` argument in the `Dockerfile` with `ARG BUILDER_IMAGE="hexpm/elixir-arm64:1.13.2-erlang-24.2.1-debian-bullseye-20210902-slim"` and then build the image as described above. diff --git a/guides/introduction/overview.md b/guides/introduction/overview.md deleted file mode 100644 index 866b76b..0000000 --- a/guides/introduction/overview.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview - -![Contributors][contributors-shield] -![Forks][forks-shield] -![Stargazers][stars-shield] -![Issues][issues-shield] -![MIT License][license-shield] - - - -Claper turns your presentations into an interactive, engaging and exciting experience. - -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. - - -![](assets/preview.png) - -[contributors-shield]: https://img.shields.io/github/contributors/ClaperCo/Claper.svg?style=for-the-badge -[forks-shield]: https://img.shields.io/github/forks/ClaperCo/Claper.svg?style=for-the-badge -[stars-shield]: https://img.shields.io/github/stars/ClaperCo/Claper.svg?style=for-the-badge -[issues-shield]: https://img.shields.io/github/issues/ClaperCo/Claper.svg?style=for-the-badge -[license-shield]: https://img.shields.io/github/license/ClaperCo/Claper.svg?style=for-the-badge diff --git a/guides/introduction/storage.md b/guides/introduction/storage.md deleted file mode 100644 index f0bc9e3..0000000 --- a/guides/introduction/storage.md +++ /dev/null @@ -1,19 +0,0 @@ -# Presentation storage - -You can configure different storage options for your presentations. By default, Claper uses the local storage. - -Each presentation has a unique hash that is generated in two steps, first with `:erlang.phash2("#{code}-#{name}")` and then `:erlang.phash2("#{hash}-#{System.system_time(:second)}")`. - -## Local storage - -The local storage is the default storage option. It stores the presentations in the `priv/static/uploads/[hash]` folder. - -You can change the directory where the presentations are stored by changing the `PRESENTATION_STORAGE_DIR` variable in the `.env` file. - -The `uploads` folder will be created automatically if it doesn't exist. - -## S3 storage - -You can use S3 storage to store your presentations. - -When user upload a new presentation, the destination file is uploaded to S3 in your bucket in `presentations/[hash]` and the local file is deleted. diff --git a/guides/usage/features.md b/guides/usage/features.md deleted file mode 100644 index 94271f9..0000000 --- a/guides/usage/features.md +++ /dev/null @@ -1,63 +0,0 @@ -# Features - -The main goal of Claper is to provide a simple and easy to use integrate feedback during your presentations. - -We don't want to add a lot of features but instead focusing on the core features that are needed to provide a good feedback experience. - -## Questions and Answers - -Users can send instant message during the presentation and interact to others messages with emoji reactions. - - - -You can choose to be anoynmous or use your own name before sending a message. - -You can also pin a message to the screen to highlight it and only show pinned messages. - -## Polls - -You can add polls during your presentation. Users can vote to the poll and see the results in real time. - -When you create a new presentation, click on **Present/Customize**, select the slide where you want to add poll and click **Add interaction**. - -During your presentation, enable **Active poll results** on the dashboard to see the poll results in real time. - -You can choose between single choice and multiple choice polls. - - - -## Forms - -You can also add forms during your presentation. Users can fill the form and you can see all submissions in real time. - -When you create a new presentation, click on **Present/Customize**, select the slide where you want to add form and click **Add interaction**. - -After your presentation, you can export all the submissions in CSV format. - -## Web content - -Any web content like Youtube, Slideshare, Google Slides, etc. can be embedded in your presentation. - -When you create a new presentation, click on **Present/Customize**, select the slide where you want to add embed and click **Add interaction**. - -You can choose to show the embed in the attendee side, so your audience can see the embed content during your presentation. - -## Moderation tools - -You can moderate the messages during your presentation. You can delete messages or ban users from the dashboard. - -Banning the user will prevent him to send messages during the presentation and is based on a token that is stored in the browser. If the user clear his cookies, he will be able to send messages again. - - - -### Control your presentation - -You have several settings to control your presentation like avoiding anonymous chat messages, disabling the chat, showing poll results on the screen or instructions to join your Clapper event. - -## Facilitators - -You can add users as facilitators to your presentation. Facilitators can moderate the messages from the dashboard but cannot deleted or edit your presentation. - -## Reports - -When the presentation is over, you can access to the report with all the messages and reactions and other statistics about the presentation engagement. \ No newline at end of file diff --git a/guides/usage/howto.md b/guides/usage/howto.md deleted file mode 100644 index 05aad29..0000000 --- a/guides/usage/howto.md +++ /dev/null @@ -1,58 +0,0 @@ -# How-to - -## Preparations -The first thing you need to have is your **Powerpoint or Keynote presentation**. - -Do you plan to add a poll or ask questions? - -Plan slides that will include interactions, for example for a poll, a slide with the title of your poll. Each interaction will be linked to a slide in your presentation. - -When everything is ready, you must **save/export your presentation in PDF or PPT/PPTX format**. It is recommended to use PDF format, which will guarantee you a final rendering identical to the original. - -You now have your exported presentation and ready to be imported into Claper. - -## Using Claper -**Log in to your Claper account** and create a new presentation. - -**Upload your file** then choose a **name** for your event, a **code** that will allow your attendees to join the event and a start and end date. -Your attendees will not be able to join the event before the start date and will not be able to join it after the end date. - -Note that at the end of your presentation, you will have access to your **statistical report** in order to know the engagement rate and other useful metrics. - - - -Before saving, you can add facilitators with their email. They will only be able to moderate your presentation and project it. Your presentation will appear in their dashboard after they log in. - -**The first step is finished**, wait a few minutes for your file to be processed. - -**It's time to add interactions!** - -You can add interactions during your presentation or prepare them ahead of time. - -Click on **Present/Customize**, you will find all the slides of your presentation. - - - -Below each slide, you can add interactions that will be available when the slide is active. - - - - - -In the **right side** you will have access to all posts, which is useful for moderators who can moderate posts by deleting them or banning disruptive attendees. - -At the **bottom right** you will be able to view the instructions with the QR to join your meeting, _it's best to activate it at the beginning of the presentation before you start talking_. - -You also have the option to display messages from your attendees and the result of the current poll. - -## Presenting - -**You are finally ready to start!** - -That's what the **Start** button in the top right corner is for. This will open a new window that will be used during your presentation. - -**To go into full screen mode, press the F key.** - -To control your presentation, use the moderation screen, you can also control your presentation on your phone if you are logged in with your account. - -You are finally ready to interact effectively with your audience! \ No newline at end of file diff --git a/lib/claper/accounts.ex b/lib/claper/accounts.ex index fa59fd5..655b8e1 100644 --- a/lib/claper/accounts.ex +++ b/lib/claper/accounts.ex @@ -108,6 +108,19 @@ defmodule Claper.Accounts do User.email_changeset(user, attrs) end + @doc """ + Returns an `%Ecto.Changeset{}` for changing the user preferences. + + ## Examples + + iex> change_user_preferences(user) + %Ecto.Changeset{data: %User{}} + + """ + def change_user_preferences(user, attrs \\ %{}) do + User.preferences_changeset(user, attrs) + end + @doc """ Emulates that the email will change without actually changing it in the database. @@ -177,12 +190,26 @@ defmodule Claper.Accounts do end end + @doc """ + Updates the user preferences. + ## Examples + iex> update_user_preferences(user, %{locale: "en}) + {:ok, %User{}} + iex> update_user_preferences(user, %{locale: "invalid}) + {:error, %Ecto.Changeset{}} + """ + def update_user_preferences(user, attrs \\ %{}) do + user + |> User.preferences_changeset(attrs) + |> Repo.update() + end + @doc """ Delivers the magic link email to the given user. ## Examples - iex> deliver_magic_link(user, &Routes.user_confirmation_url(conn, :confirm_magic, &1)) + iex> deliver_magic_link(user, &url(~p"/users/magic/&1")) {:ok, %{to: ..., body: ...}} """ @@ -423,4 +450,8 @@ defmodule Claper.Accounts do UserToken.user_magic_and_contexts_query(token.sent_to, ["magic"]) ) end + + def delete(user) do + Repo.delete(user) + end end diff --git a/lib/claper/accounts/user.ex b/lib/claper/accounts/user.ex index d55a8ad..53bed30 100644 --- a/lib/claper/accounts/user.ex +++ b/lib/claper/accounts/user.ex @@ -10,6 +10,7 @@ defmodule Claper.Accounts.User do field :hashed_password, :string, redact: true field :is_admin, :boolean field :confirmed_at, :naive_datetime + field :locale, :string has_many :events, Claper.Events.Event @@ -23,6 +24,11 @@ defmodule Claper.Accounts.User do |> validate_password(opts) end + def preferences_changeset(user, attrs) do + user + |> cast(attrs, [:locale]) + end + defp validate_email(changeset) do changeset |> validate_required([:email]) diff --git a/lib/claper/events.ex b/lib/claper/events.ex index e52d59b..8672f9d 100644 --- a/lib/claper/events.ex +++ b/lib/claper/events.ex @@ -20,7 +20,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.expired_at]) + from(e in Event, where: e.user_id == ^user_id, order_by: [desc: e.inserted_at]) |> Repo.all() |> Repo.preload(preload) end @@ -140,7 +140,7 @@ defmodule Claper.Events do def get_event_with_code!(code, preload \\ []) do now = NaiveDateTime.utc_now() - from(e in Event, where: e.code == ^code and e.expired_at > ^now) + from(e in Event, where: e.code == ^code and (is_nil(e.expired_at) or e.expired_at > ^now)) |> Repo.one!() |> Repo.preload(preload) end @@ -148,7 +148,7 @@ defmodule Claper.Events do def get_event_with_code(code, preload \\ []) do now = DateTime.utc_now() - from(e in Event, where: e.code == ^code and e.expired_at > ^now) + from(e in Event, where: e.code == ^code and (is_nil(e.expired_at) or e.expired_at > ^now)) |> Repo.one() |> Repo.preload(preload) end @@ -234,7 +234,7 @@ defmodule Claper.Events do end @doc """ - Updates a event. + Updates an event. ## Examples @@ -258,6 +258,28 @@ defmodule Claper.Events do end end + @doc """ + Terminates an event. + + ## Examples + + iex> terminate_event(event) + {:ok, %Event{}} + + """ + def terminate_event(%Event{} = event) do + event + |> Event.update_changeset(%{expired_at: NaiveDateTime.utc_now()}) + |> Repo.update() + |> case do + {:ok, event} -> + broadcast({:ok, event, event.uuid}, :event_terminated) + + {:error, changeset} -> + {:error, %{changeset | action: :update}} + end + end + @doc """ Import interactions from another event @@ -421,4 +443,16 @@ defmodule Claper.Events do def change_activity_leader(%ActivityLeader{} = activity_leader, attrs \\ %{}) do ActivityLeader.changeset(activity_leader, attrs) end + + defp broadcast({:error, _reason} = error, _event), do: error + + defp broadcast({:ok, e, event_uuid}, event) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{event_uuid}", + {event, event_uuid} + ) + + {:ok, e} + end end diff --git a/lib/claper/events/event.ex b/lib/claper/events/event.ex index 0009463..2a0b7e5 100644 --- a/lib/claper/events/event.ex +++ b/lib/claper/events/event.ex @@ -10,8 +10,6 @@ defmodule Claper.Events.Event do field :started_at, :naive_datetime field :expired_at, :naive_datetime - field :date_range, :string, virtual: true - has_many :posts, Claper.Posts.Post has_many :leaders, Claper.Events.ActivityLeader, on_replace: :delete @@ -30,21 +28,19 @@ defmodule Claper.Events.Event do :code, :started_at, :expired_at, - :date_range, :audience_peak ]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code]) - |> validate_date_range + |> validate_required([:code, :name]) end def create_changeset(event, attrs) do event - |> cast(attrs, [:name, :code, :user_id, :started_at, :expired_at, :date_range]) + |> cast(attrs, [:name, :code, :user_id, :started_at, :expired_at]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code, :started_at, :expired_at]) + |> validate_required([:code, :started_at]) |> downcase_code end @@ -56,38 +52,12 @@ defmodule Claper.Events.Event do ) end - defp validate_date_range(changeset) do - date_range = get_change(changeset, :date_range) - - if date_range != nil do - splited = date_range |> String.split(" - ") - - if splited |> Enum.count() == 2 do - changeset - |> put_change(:started_at, Enum.at(splited, 0)) - |> put_change(:expired_at, Enum.at(splited, 1)) - else - add_error(changeset, :date_range, "invalid date range") - end - else - start_date = get_change(changeset, :started_at) - end_date = get_change(changeset, :expired_at) - - if start_date != nil && end_date != nil do - changeset - |> put_change(:date_range, "#{start_date} - #{end_date}") - else - changeset - end - end - end - def update_changeset(event, attrs) do event - |> cast(attrs, [:name, :code, :started_at, :expired_at, :date_range, :audience_peak]) + |> cast(attrs, [:name, :code, :started_at, :expired_at, :audience_peak]) |> cast_assoc(:presentation_file) |> cast_assoc(:leaders) - |> validate_required([:code, :started_at, :expired_at]) + |> validate_required([:code, :started_at]) |> downcase_code end @@ -105,4 +75,8 @@ defmodule Claper.Events.Event do def started?(event) do NaiveDateTime.compare(NaiveDateTime.utc_now(), event.started_at) == :gt end + + def finished?(event) do + event.expired_at && NaiveDateTime.compare(NaiveDateTime.utc_now(), event.expired_at) == :gt + end end diff --git a/lib/claper/forms.ex b/lib/claper/forms.ex index 210d8d8..635a689 100644 --- a/lib/claper/forms.ex +++ b/lib/claper/forms.ex @@ -238,13 +238,14 @@ defmodule Claper.Forms do [%FormSubmit{}, ...] """ - def list_form_submits(presentation_file_id) do + def list_form_submits(presentation_file_id, preload \\ []) do from(fs in FormSubmit, join: f in Form, on: f.id == fs.form_id, where: f.presentation_file_id == ^presentation_file_id ) |> Repo.all() + |> Repo.preload(preload) end @doc """ diff --git a/lib/claper/posts.ex b/lib/claper/posts.ex index 0b31f46..9691288 100644 --- a/lib/claper/posts.ex +++ b/lib/claper/posts.ex @@ -24,6 +24,28 @@ defmodule Claper.Posts do |> Repo.preload(preload) end + @doc """ + Get event posts which are questions + + """ + def list_questions(event_id, preload \\ [], sort \\ :date) do + query = + from(p in Post, + join: e in assoc(p, :event), + where: e.uuid == ^event_id and like(p.body, "%?%") + ) + + query = + case sort do + :likes -> from(p in query, order_by: [desc: p.like_count]) + _ -> from(p in query, order_by: [asc: p.id]) + end + + query + |> Repo.all() + |> Repo.preload(preload) + end + @doc """ Get only the pinned event posts. """ diff --git a/lib/claper/presentations/presentation_state.ex b/lib/claper/presentations/presentation_state.ex index d384f2b..dd1ef7c 100644 --- a/lib/claper/presentations/presentation_state.ex +++ b/lib/claper/presentations/presentation_state.ex @@ -9,6 +9,8 @@ defmodule Claper.Presentations.PresentationState do field :join_screen_visible, :boolean field :chat_enabled, :boolean field :anonymous_chat_enabled, :boolean + field :message_reaction_enabled, :boolean, default: true + field :show_poll_results_enabled, :boolean, default: true field :banned, {:array, :string}, default: [] field :show_only_pinned, :boolean, default: false @@ -29,7 +31,9 @@ defmodule Claper.Presentations.PresentationState do :presentation_file_id, :chat_enabled, :anonymous_chat_enabled, - :show_only_pinned + :show_only_pinned, + :message_reaction_enabled, + :show_poll_results_enabled ]) |> validate_required([]) end diff --git a/lib/claper/stats.ex b/lib/claper/stats.ex index 3145912..ea38a5c 100644 --- a/lib/claper/stats.ex +++ b/lib/claper/stats.ex @@ -16,11 +16,14 @@ defmodule Claper.Stats do def total_vote_count(presentation_file_id) do from(p in Claper.Polls.Poll, - join: o in Claper.Polls.PollOpt, - on: o.poll_id == p.id, + join: pv in Claper.Polls.PollVote, + on: pv.poll_id == p.id, where: p.presentation_file_id == ^presentation_file_id, - group_by: o.poll_id, - select: sum(o.vote_count) + group_by: p.presentation_file_id, + select: + count( + fragment("DISTINCT COALESCE(?, CAST(? AS varchar))", pv.attendee_identifier, pv.user_id) + ) ) |> Repo.all() end diff --git a/lib/claper/tasks/converter.ex b/lib/claper/tasks/converter.ex index ca2b4d2..2420c31 100644 --- a/lib/claper/tasks/converter.ex +++ b/lib/claper/tasks/converter.ex @@ -43,8 +43,6 @@ defmodule Claper.Tasks.Converter do Remove the presentation files directory """ def clear(hash) do - IO.puts("Clearing #{hash}...") - if get_presentation_storage() == "local" do File.rm_rf( Path.join([ @@ -65,7 +63,7 @@ defmodule Claper.Tasks.Converter do defp file_to_pdf(:ppt, path, file) do Porcelain.exec( - "libreoffice", + get_libreoffice_binary(), [ "--headless", "--invisible", @@ -80,7 +78,7 @@ defmodule Claper.Tasks.Converter do defp file_to_pdf(:pptx, path, file) do Porcelain.exec( - "libreoffice", + get_libreoffice_binary(), [ "--headless", "--invisible", @@ -207,4 +205,11 @@ defmodule Claper.Tasks.Converter do defp get_resolution do Application.get_env(:claper, :presentations) |> Keyword.get(:resolution) end + + defp get_libreoffice_binary do + case :os.type() do + {:unix, :darwin} -> "soffice" + _ -> "libreoffice" + end + end end diff --git a/lib/claper_web.ex b/lib/claper_web.ex index a866b3a..5ebb91b 100644 --- a/lib/claper_web.ex +++ b/lib/claper_web.ex @@ -17,13 +17,16 @@ defmodule ClaperWeb do and import those modules here. """ + def static_paths, do: ~w(assets fonts .well-known images favicon.ico robots.txt) + def controller do quote do use Phoenix.Controller, namespace: ClaperWeb import Plug.Conn import ClaperWeb.Gettext - alias ClaperWeb.Router.Helpers, as: Routes + + unquote(verified_routes()) end end @@ -71,7 +74,9 @@ defmodule ClaperWeb do def view_component do quote do - use Phoenix.HTML + import Phoenix.HTML + import Phoenix.HTML.Form + use PhoenixHTMLHelpers use Phoenix.Component import ClaperWeb.ErrorHelpers alias Phoenix.LiveView.JS @@ -89,7 +94,9 @@ defmodule ClaperWeb do defp view_helpers do quote do # Use all HTML functionality (forms, tags, etc) - use Phoenix.HTML + import Phoenix.HTML + import Phoenix.HTML.Form + use PhoenixHTMLHelpers # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) import Phoenix.LiveView.Helpers @@ -101,7 +108,17 @@ defmodule ClaperWeb do import ClaperWeb.ErrorHelpers import ClaperWeb.Gettext - alias ClaperWeb.Router.Helpers, as: Routes + + unquote(verified_routes()) + end + end + + def verified_routes do + quote do + use Phoenix.VerifiedRoutes, + endpoint: ClaperWeb.Endpoint, + router: ClaperWeb.Router, + statics: ClaperWeb.static_paths() end end diff --git a/lib/claper_web/controllers/stat_controller.ex b/lib/claper_web/controllers/stat_controller.ex index 64f4a5a..81ed3ef 100644 --- a/lib/claper_web/controllers/stat_controller.ex +++ b/lib/claper_web/controllers/stat_controller.ex @@ -5,22 +5,22 @@ defmodule ClaperWeb.StatController do def export(conn, %{"form_id" => form_id}) do form = Forms.get_form!(form_id, [:form_submits]) - csv_data = csv_content(form.form_submits |> Enum.map(& &1.response)) + headers = form.fields |> Enum.map(& &1.name) + csv_data = headers |> csv_content(form.form_submits |> Enum.map(& &1.response)) conn |> put_resp_content_type("text/csv") - |> put_resp_header("content-disposition", "attachment; filename=\"export.csv\"") + |> put_resp_header("content-disposition", "attachment; filename=\"#{form.title}.csv\"") |> put_root_layout(false) |> send_resp(200, csv_data) end - defp csv_content(records) do - records - |> Enum.map(fn record -> - record - |> Map.new(fn {k, v} -> {String.to_atom(k), v} end) - |> Map.values() - end) + defp csv_content(headers, records) do + data = + records + |> Enum.map(&(&1 |> Map.values())) + + ([headers] ++ data) |> CSV.encode() |> Enum.to_list() |> to_string() diff --git a/lib/claper_web/controllers/user_auth.ex b/lib/claper_web/controllers/user_auth.ex index 1f525d2..5fb26fe 100644 --- a/lib/claper_web/controllers/user_auth.ex +++ b/lib/claper_web/controllers/user_auth.ex @@ -2,12 +2,12 @@ defmodule ClaperWeb.UserAuth do @moduledoc """ Plug for user authentication. """ + use ClaperWeb, :controller import Plug.Conn import Phoenix.Controller alias Claper.Accounts - alias ClaperWeb.Router.Helpers, as: Routes # Make the remember me cookie valid for 60 days. # If you want bump or reduce this value, also change @@ -137,13 +137,13 @@ defmodule ClaperWeb.UserAuth do conn else conn - # |> redirect(to: Routes.user_registration_path(conn, :confirm)) + # |> redirect(to: ~p"/users/register/confirm") end else conn |> put_flash(:error, "You must log in to access this page.") |> maybe_store_return_to() - |> redirect(to: Routes.user_session_path(conn, :new)) + |> redirect(to: ~p"/users/log_in") |> halt() end end diff --git a/lib/claper_web/controllers/user_confirmation_controller.ex b/lib/claper_web/controllers/user_confirmation_controller.ex index 0fd9c89..a1980ae 100644 --- a/lib/claper_web/controllers/user_confirmation_controller.ex +++ b/lib/claper_web/controllers/user_confirmation_controller.ex @@ -11,7 +11,7 @@ defmodule ClaperWeb.UserConfirmationController do if user = Accounts.get_user_by_email(email) do Accounts.deliver_user_confirmation_instructions( user, - &Routes.user_confirmation_url(conn, :update, &1) + &url(~p"/users/confirm/#{&1}") ) end diff --git a/lib/claper_web/controllers/user_registration_controller.ex b/lib/claper_web/controllers/user_registration_controller.ex index 65fe14b..2e9c6ec 100644 --- a/lib/claper_web/controllers/user_registration_controller.ex +++ b/lib/claper_web/controllers/user_registration_controller.ex @@ -26,7 +26,7 @@ defmodule ClaperWeb.UserRegistrationController do # {:ok, _} = # Accounts.deliver_user_confirmation_instructions( # user, - # &Routes.user_confirmation_url(conn, :update, &1) + # &url(~p"/users/confirm/#{&1}") # ) conn diff --git a/lib/claper_web/controllers/user_reset_password_controller.ex b/lib/claper_web/controllers/user_reset_password_controller.ex index 2f35249..d4d4408 100644 --- a/lib/claper_web/controllers/user_reset_password_controller.ex +++ b/lib/claper_web/controllers/user_reset_password_controller.ex @@ -15,7 +15,7 @@ defmodule ClaperWeb.UserResetPasswordController do if user = Accounts.get_user_by_email(email) do Accounts.deliver_user_reset_password_instructions( user, - &Routes.user_reset_password_url(conn, :edit, &1) + &url(~p"/users/reset_password/#{&1}") ) end diff --git a/lib/claper_web/controllers/user_session_controller.ex b/lib/claper_web/controllers/user_session_controller.ex index c6485e0..1de54e7 100644 --- a/lib/claper_web/controllers/user_session_controller.ex +++ b/lib/claper_web/controllers/user_session_controller.ex @@ -10,10 +10,10 @@ defmodule ClaperWeb.UserSessionController do end # def create(conn, %{"user" => %{"email" => email}} = _user_params) do - # Accounts.deliver_magic_link(email, &Routes.user_confirmation_url(conn, :confirm_magic, &1)) + # Accounts.deliver_magic_link(email, &url(~p"/users/magic/#{&1}")) # conn - # |> redirect(to: Routes.user_registration_path(conn, :confirm, %{email: email})) + # |> redirect(to: ~p"/users/register/confirm?#{[%{email: email}]}") # end def create(conn, %{"user" => user_params}) do %{"email" => email, "password" => password} = user_params diff --git a/lib/claper_web/controllers/user_settings_controller.ex b/lib/claper_web/controllers/user_settings_controller.ex index 6bc6d12..97e2bdc 100644 --- a/lib/claper_web/controllers/user_settings_controller.ex +++ b/lib/claper_web/controllers/user_settings_controller.ex @@ -18,7 +18,7 @@ defmodule ClaperWeb.UserSettingsController do Accounts.deliver_update_email_instructions( applied_user, user.email, - &Routes.user_settings_url(conn, :confirm_email, &1) + &url(~p"/users/settings/confirm_email/#{&1}") ) conn @@ -26,7 +26,7 @@ defmodule ClaperWeb.UserSettingsController do :info, "A link to confirm your email change has been sent to the new address." ) - |> redirect(to: Routes.user_settings_show_path(conn, :show)) + |> redirect(to: ~p"/users/settings") {:error, changeset} -> render(conn, "edit.html", email_changeset: changeset) @@ -38,12 +38,12 @@ defmodule ClaperWeb.UserSettingsController do :ok -> conn |> put_flash(:info, "Email changed successfully.") - |> redirect(to: Routes.user_settings_show_path(conn, :show)) + |> redirect(to: ~p"/users/settings") :error -> conn |> put_flash(:error, "Email change link is invalid or it has expired.") - |> redirect(to: Routes.user_settings_show_path(conn, :show)) + |> redirect(to: ~p"/users/settings") end end diff --git a/lib/claper_web/endpoint.ex b/lib/claper_web/endpoint.ex index d9a213c..63ae0be 100644 --- a/lib/claper_web/endpoint.ex +++ b/lib/claper_web/endpoint.ex @@ -10,7 +10,12 @@ defmodule ClaperWeb.Endpoint do signing_salt: "Tg18Y2zU" ] - socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]] + socket "/live", Phoenix.LiveView.Socket, + websocket: [ + connect_info: [ + session: {__MODULE__, :runtime_opts, []} + ] + ] # Serve at "/" the static files from "priv/static" directory. # @@ -20,8 +25,7 @@ defmodule ClaperWeb.Endpoint do at: "/", from: :claper, gzip: false, - only: - ~w(assets fonts .well-known images favicon.ico robots.txt loaderio-eb3b956a176cdd4f54eb8570ce8bbb06.txt) + only: ClaperWeb.static_paths() plug Plug.Static, at: "/uploads", @@ -51,6 +55,18 @@ defmodule ClaperWeb.Endpoint do plug Plug.MethodOverride plug Plug.Head - plug Plug.Session, @session_options + + plug(:runtime_session) + plug ClaperWeb.Router + + def runtime_session(conn, _opts) do + Plug.run(conn, [{Plug.Session, runtime_opts()}]) + end + + def runtime_opts() do + @session_options + |> Keyword.put(:same_site, Application.get_env(:claper, __MODULE__)[:same_site_cookie]) + |> Keyword.put(:secure, Application.get_env(:claper, __MODULE__)[:secure_cookie]) + end end diff --git a/lib/claper_web/live/embed_live/form_component.ex b/lib/claper_web/live/embed_live/form_component.ex index 28fdb0c..fcf4dee 100644 --- a/lib/claper_web/live/embed_live/form_component.ex +++ b/lib/claper_web/live/embed_live/form_component.ex @@ -20,7 +20,7 @@ defmodule ClaperWeb.EmbedLive.FormComponent do embed = Embeds.get_embed!(id) {:ok, _} = Embeds.delete_embed(socket.assigns.event_uuid, embed) - {:noreply, socket |> push_redirect(to: socket.assigns.return_to)} + {:noreply, socket |> push_navigate(to: socket.assigns.return_to)} end @impl true @@ -47,7 +47,7 @@ defmodule ClaperWeb.EmbedLive.FormComponent do {:ok, _embed} -> {:noreply, socket - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} @@ -65,7 +65,7 @@ defmodule ClaperWeb.EmbedLive.FormComponent do {:noreply, socket |> maybe_change_current_embed(embed) - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, changeset: changeset)} 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 688da1c..6b88c79 100644 --- a/lib/claper_web/live/event_live/event_card_component.ex +++ b/lib/claper_web/live/event_live/event_card_component.ex @@ -1,6 +1,8 @@ defmodule ClaperWeb.EventLive.EventCardComponent do use ClaperWeb, :live_component + alias Claper.Events.Event + def render(assigns) do assigns = assigns @@ -15,17 +17,19 @@ defmodule ClaperWeb.EventLive.EventCardComponent do <%= @event.name %>

- <%= if NaiveDateTime.compare(@current_time, @event.started_at) == :gt and NaiveDateTime.compare(@current_time, @event.expired_at) == :lt do %> -

- <%= gettext("In progress") %> -

+ <%= if Event.started?(@event) && !Event.finished?(@event) do %> +
+ + + <%= gettext("Live") %> +
<% end %> - <%= if NaiveDateTime.compare(@current_time, @event.started_at) == :lt do %> + <%= if !Event.started?(@event) && !Event.finished?(@event) do %>

<%= gettext("Incoming") %>

<% end %> - <%= if NaiveDateTime.compare(@current_time, @event.expired_at) == :gt do %> + <%= if Event.finished?(@event) do %>

<%= gettext("Finished") %>

@@ -44,150 +48,227 @@ defmodule ClaperWeb.EventLive.EventCardComponent do class="flex items-center text-sm text-gray-500 space-x-1" phx-update="ignore" > - - <%= if NaiveDateTime.compare(@current_time, @event.started_at) == :gt and NaiveDateTime.compare(@current_time, @event.expired_at) == :lt do %> -

- <%= gettext("Finish on") %> - -

- <% end %> - <%= if NaiveDateTime.compare(@current_time, @event.started_at) == :lt do %> -

- <%= gettext("Starting on") %> - -

- <% end %> - <%= if NaiveDateTime.compare(@current_time, @event.expired_at) == :gt do %> -

- <%= gettext("Finished on") %> - -

- <% end %> + +

+ <%= gettext("Starting on") %> + +

+

+ <%= gettext("Finished on") %> + +

- <%= if @event.presentation_file.status == "fail" && @event.presentation_file.hash do %> -

- <%= gettext("Error when processing the new file") %> -

- <% end %> - - <%= if NaiveDateTime.compare(@current_time, @event.expired_at) == :lt do %> - <%= if @event.presentation_file.status == "done" || (@event.presentation_file.status == "fail" && @event.presentation_file.hash) do %> -
+ <%= if !Event.finished?(@event) do %> +
+
+ + <.link + :if={Event.started?(@event) && not @is_leader} + data-confirm={ + gettext( + "Are you sure you want to terminate this event? This action cannot be undone." + ) + } + 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" + > + + + + <%= gettext("Terminate") %> + +
+
+ <%= if not @is_leader do %> - - <%= gettext("Present/Customize") %> + <%= gettext("Edit") %> + <% end %> +
+
+ +
+ + <%= gettext("Error when processing the file") %> + +
+ <%= if not @is_leader do %> - - <%= gettext("Join") %> + <%= gettext("Edit") %> -
-
- <%= if not @is_leader do %> - - <%= gettext("Edit") %> - - <% end %> -
-
- <% end %> - - <%= if @event.presentation_file.status == "fail" && is_nil(@event.presentation_file.hash) do %> -
- - <%= gettext("Error when processing the file") %> - -
- <%= if not @is_leader do %> - - <%= gettext("Edit") %> - - <% end %> -
+ <% end %>
- <% end %> +
- <%= if @event.presentation_file.status == "progress" do %> -
- - <%= gettext("Processing your file...") %> -
- <% end %> +
+ + <%= gettext("Processing your file...") %> +
<% end %> - <%= if NaiveDateTime.compare(@current_time, @event.expired_at) == :gt do %> -
-
+ -
- <%= if not @is_leader do %> - <%= link(gettext("Delete"), - to: "#", - phx_click: "delete", - phx_value_id: @event.uuid, - data: [ - confirm: - gettext( - "This will delete all data related to your event, this cannot be undone. Confirm ?" - ) - ], - class: - "flex w-full lg:w-auto rounded-md tracking-wide focus:outline-none focus:shadow-outline text-red-500 text-sm items-center" - ) %> - <% end %> -
+ + + + <%= gettext("View report") %> +
- <% end %> +
+ <%= if not @is_leader do %> + <%= link(gettext("Delete"), + to: "#", + phx_click: "delete", + phx_value_id: @event.uuid, + data: [ + confirm: + gettext( + "This will delete all data related to your event, this cannot be undone. Confirm ?" + ) + ], + class: + "flex w-full lg:w-auto rounded-md tracking-wide focus:outline-none focus:shadow-outline text-red-500 text-sm items-center" + ) %> + <% end %> +
+
""" end + + def handle_event("open", _params, socket) do + {:noreply, socket |> assign(:dropdown, true)} + end end diff --git a/lib/claper_web/live/event_live/event_form_component.ex b/lib/claper_web/live/event_live/event_form_component.ex index 7053c25..572007e 100644 --- a/lib/claper_web/live/event_live/event_form_component.ex +++ b/lib/claper_web/live/event_live/event_form_component.ex @@ -1,4 +1,5 @@ defmodule ClaperWeb.EventLive.EventFormComponent do + alias Claper.Presentations.PresentationFile use ClaperWeb, :live_component alias Claper.Events @@ -118,7 +119,7 @@ defmodule ClaperWeb.EventLive.EventFormComponent do File.cp!(path, dest) - {:ok, Routes.static_path(socket, "/uploads/#{hash}/#{Path.basename(dest)}")} + {:ok, "/uploads/#{hash}/#{Path.basename(dest)}"} end) [ext | _] = MIME.extensions(MIME.from_path(dest)) @@ -151,10 +152,56 @@ defmodule ClaperWeb.EventLive.EventFormComponent do save_file(socket, event_params, &edit_event/4) end - defp save_event(socket, :new, event_params) do + defp save_event( + %{assigns: %{event: %{:presentation_file => %PresentationFile{}}}} = socket, + :new, + event_params + ) do save_file(socket, event_params, &create_event/4) end + defp save_event( + %{assigns: %{event: %{:presentation_file => %Ecto.Association.NotLoaded{}}}} = socket, + :new, + event_params + ) do + case uploaded_entries(socket, :presentation_file) do + {[_ | _], []} -> save_file(socket, event_params, &create_event/4) + _ -> create_event(socket, event_params) + end + end + + defp create_event(socket, event_params) do + case Events.create_event( + event_params + |> Map.put("user_id", socket.assigns.current_user.id) + |> Map.put("presentation_file", %{ + "status" => "done", + "length" => 0, + "presentation_state" => %{} + }) + ) do + {:ok, event} -> + with e <- Events.get_event!(event.uuid, [:leaders]) do + Enum.each(e.leaders, fn leader -> + Claper.Accounts.LeaderNotifier.deliver_event_invitation( + e.name, + leader.email, + url(~p"/events") + ) + end) + end + + {:noreply, + socket + |> put_flash(:info, gettext("Created successfully")) + |> redirect(to: socket.assigns.return_to)} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign(socket, changeset: changeset)} + end + end + defp create_event(socket, event_params, hash, ext) do case Events.create_event( event_params @@ -176,7 +223,7 @@ defmodule ClaperWeb.EventLive.EventFormComponent do Claper.Accounts.LeaderNotifier.deliver_event_invitation( e.name, leader.email, - Routes.event_index_url(socket, :index) + url(~p"/events") ) end) end @@ -184,7 +231,7 @@ defmodule ClaperWeb.EventLive.EventFormComponent do {:noreply, socket |> put_flash(:info, gettext("Created successfully")) - |> push_redirect(to: socket.assigns.return_to)} + |> redirect(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, changeset: changeset)} @@ -204,7 +251,7 @@ defmodule ClaperWeb.EventLive.EventFormComponent do {:noreply, socket |> put_flash(:info, gettext("Updated successfully")) - |> push_redirect(to: socket.assigns.return_to)} + |> redirect(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} @@ -246,7 +293,7 @@ defmodule ClaperWeb.EventLive.EventFormComponent do Claper.Accounts.LeaderNotifier.deliver_event_invitation( e.name, leader.email, - Routes.event_index_url(socket, :index) + url(~p"/events") ) end end) 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 ab4a1ab..7dca54c 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 @@ -1,4 +1,11 @@ -
+

@@ -6,7 +13,7 @@

- <%= if @uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) >= 100 || Map.has_key?(@event.presentation_file, :id) do %> + <%= if (@uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) == 0 || @uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) == 100) && @changeset.valid? do %>
<% end %> - <%= if @action == :edit && NaiveDateTime.compare(NaiveDateTime.utc_now(), @event.expired_at) == :lt do %> + <%= if @action == :edit && !@event.expired_at do %> <%= link(gettext("Delete"), to: "#", phx_click: "delete", @@ -39,10 +46,16 @@
- <%= if Map.get(@event, :presentation_file) == nil || Map.get(@event.presentation_file, :id) == nil do %> -
+ <%= if Map.get(@event, :presentation_file) == nil || Map.get(@event.presentation_file, :length) == 0 || Map.get(@event.presentation_file, :id) == nil do %> +
#{gettext("Select your presentation file. Accepted formats are PDF, PPT, or PPTX. Ensure the file size does not exceed the maximum limit.")}

#{gettext("Animations in PPT/PPTX files are not supported, which is why we recommend exporting your presentation to PDF to ensure it displays correctly.")}

"} + data-tg-title={"📄 #{gettext("Presentation file (optional)")}"} + >
<%= if @uploads.presentation_file.entries |> Enum.at(0, %{}) |> Map.get(:progress, 0) < 100 do %> @@ -70,7 +83,7 @@ phx-target={@myself} > <%= gettext("Upload a file") %> - <%= live_file_input(@uploads.presentation_file, class: "sr-only") %> + <.live_file_input upload={@uploads.presentation_file} class="sr-only" />

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

@@ -157,7 +170,7 @@ phx-target={@myself} > <%= gettext("Change file") %> - <%= live_file_input(@uploads.presentation_file, class: "sr-only") %> + <.live_file_input upload={@uploads.presentation_file} class="sr-only" />
-
+
#{gettext("This code will be used by your attendees to access the event. You have the option to create a custom code.")}

"} + data-tg-group="create-event" + data-tg-order="2" + >
-
- #{gettext("Select the start date for your event. Future dates are permissible.")}

#{gettext("Attendees attempting to access the event prior to this date will be directed to a waiting room.")}

"} + data-tg-group="create-event" + data-tg-order="3" + phx-update="ignore" + id="date-picker" + > + @@ -270,7 +293,13 @@ <% end %>
-
+
#{gettext("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.")}

#{gettext("Note: Facilitators do not have the ability to delete your event.")}

"} + data-tg-group="create-event" + data-tg-order="4" + > <%= gettext("Facilitators can present and manage interactions") %> @@ -278,7 +307,7 @@ type="button" phx-click="add-leader" phx-target={@myself} - class="rounded-md bg-primary-500 hover:bg-primary-600 transition flex items-center mt-3 md:w-max text-white py-7 px-3 text-sm max-h-0" + class="rounded-md bg-primary-500 hover:bg-primary-600 transition flex items-center mt-3 md:w-max text-white py-5 px-3 text-sm max-h-0" > - <%= gettext("Add facilitator") %> + <%= gettext("Add facilitator") %>
diff --git a/lib/claper_web/live/event_live/index.ex b/lib/claper_web/live/event_live/index.ex index 4685058..1eb53eb 100644 --- a/lib/claper_web/live/event_live/index.ex +++ b/lib/claper_web/live/event_live/index.ex @@ -12,16 +12,24 @@ defmodule ClaperWeb.EventLive.Index do Gettext.put_locale(ClaperWeb.Gettext, locale) end + changeset = + Events.change_event(%Event{}, %{ + started_at: NaiveDateTime.utc_now(), + code: Enum.random(1000..9999), + leaders: [] + }) + if connected?(socket) do Phoenix.PubSub.subscribe(Claper.PubSub, "events:#{socket.assigns.current_user.id}") end socket = socket - |> assign(:events, list_events(socket)) + |> stream(:events, list_events(socket)) |> assign(:managed_events, list_managed_events(socket)) + |> assign(:quick_event_changeset, changeset) - {:ok, socket, temporary_assigns: [events: []]} + {:ok, socket} end @impl true @@ -33,37 +41,104 @@ defmodule ClaperWeb.EventLive.Index do def handle_info({:presentation_file_process_done, presentation}, socket) do event = Claper.Events.get_event!(presentation.event.uuid, [:presentation_file]) - {:noreply, - socket |> update(:events, fn events -> [event | events] end) |> put_flash(:info, nil)} + {:noreply, socket |> stream_insert(:events, event) |> put_flash(:info, nil)} + end + + @impl true + def handle_event("validate", %{"event" => event_params}, socket) do + changeset = + %Event{} + |> Claper.Events.change_event(event_params) + |> Map.put(:action, :validate) + + {:noreply, socket |> assign(:quick_event_changeset, changeset)} + end + + @impl true + def handle_event("save", %{"event" => event_params}, socket) do + case Claper.Events.create_event( + event_params + |> Map.put("user_id", socket.assigns.current_user.id) + |> Map.put("presentation_file", %{ + "status" => "done", + "length" => 0, + "presentation_state" => %{} + }) + |> Map.put("started_at", NaiveDateTime.utc_now()) + |> Map.put("code", "#{Enum.random(1000..9999)}") + ) do + {:ok, _event} -> + {:noreply, + socket + |> put_flash(:info, gettext("Quick event created successfully")) + |> push_navigate(to: ~p"/events")} + + {:error, %Ecto.Changeset{} = changeset} -> + {:noreply, assign(socket, quick_event_changeset: changeset)} + end end @impl true - def handle_event("delete", %{"id" => id}, socket) do - event = Events.get_event!(id, [:presentation_file]) + def handle_event("delete", %{"id" => id}, %{assigns: %{current_user: current_user}} = socket) do + event = Events.get_user_event!(current_user.id, id, [:presentation_file]) {:ok, _} = Events.delete_event(event) Task.Supervisor.async_nolink(Claper.TaskSupervisor, fn -> Claper.Tasks.Converter.clear(event.presentation_file.hash) end) - {:noreply, redirect(socket, to: Routes.event_index_path(socket, :index))} + {:noreply, redirect(socket, to: ~p"/events")} + end + + @impl true + def handle_event( + "checked", + %{"key" => "no_file", "value" => value}, + %{assigns: %{event: event}} = socket + ) do + {:noreply, socket |> assign(:event, %{event | no_file: value})} + end + + @impl true + def handle_event("terminate", %{"id" => id}, %{assigns: %{current_user: current_user}} = socket) do + event = Events.get_user_event!(current_user.id, id) + {:ok, _} = Events.terminate_event(event) + {:noreply, redirect(socket, to: ~p"/events")} + end + + @impl true + def handle_event( + "toggle-quick-create", + _params, + %{assigns: %{:live_action => :quick_create}} = socket + ) do + {:noreply, assign(socket, :live_action, :index)} + end + + @impl true + def handle_event("toggle-quick-create", _params, %{assigns: %{:live_action => :index}} = socket) do + {:noreply, assign(socket, :live_action, :quick_create)} end defp apply_action(socket, :edit, %{"id" => id}) do event = Events.get_user_event!(socket.assigns.current_user.id, id, [:presentation_file, :leaders]) - if event.presentation_file.status == "fail" && event.presentation_file.hash do - Claper.Presentations.update_presentation_file(event.presentation_file, %{ - "status" => "done" - }) - end + if event.expired_at && NaiveDateTime.compare(NaiveDateTime.utc_now(), event.expired_at) == :gt do + redirect(socket, to: ~p"/events") + else + if event.presentation_file.status == "fail" && event.presentation_file.hash do + Claper.Presentations.update_presentation_file(event.presentation_file, %{ + "status" => "done" + }) + end - {:ok, socket |> assign(:event, event)} + {:ok, socket |> assign(:event, event)} - socket - |> assign(:page_title, gettext("Edit")) - |> assign(:event, event) + socket + |> assign(:page_title, gettext("Edit")) + |> assign(:event, event) + end end defp apply_action(socket, :new, _params) do @@ -71,7 +146,6 @@ defmodule ClaperWeb.EventLive.Index do |> assign(:page_title, gettext("Create")) |> assign(:event, %Event{ started_at: NaiveDateTime.utc_now(), - expired_at: NaiveDateTime.utc_now() |> NaiveDateTime.add(3600 * 2, :second), code: Enum.random(1000..9999), leaders: [] }) diff --git a/lib/claper_web/live/event_live/index.html.heex b/lib/claper_web/live/event_live/index.html.heex index 9a643ea..1f7d1d7 100644 --- a/lib/claper_web/live/event_live/index.html.heex +++ b/lib/claper_web/live/event_live/index.html.heex @@ -1,4 +1,4 @@ -
+
<%= if @live_action in [:new, :edit] do %> <.live_component module={ClaperWeb.EventLive.EventFormComponent} @@ -6,21 +6,117 @@ event={@event} page_title={@page_title} action={@live_action} - return_to={Routes.event_index_path(@socket, :index)} + return_to={~p"/events"} current_user={@current_user} /> <% else %> -
+ + -
-
    +
    +
      <% current_time = NaiveDateTime.utc_now() %> - <%= for event <- @events do %> - <.live_component - module={ClaperWeb.EventLive.EventCardComponent} - id={"event-#{event.uuid}"} - event={event} - current_time={current_time} - /> - <% end %> + <.live_component + :for={{id, event} <- @streams.events} + module={ClaperWeb.EventLive.EventCardComponent} + id={id} + event={event} + current_time={current_time} + />
    - <%= if Enum.count(@events) == 0 do %> + <%= if Enum.count(@streams.events) == 0 do %>
    -

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

    +

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

    <% end %>
    @@ -67,18 +162,13 @@

    - <%= gettext("Invited presentations") %> + <%= gettext("Invited events") %>

    -
    -
      +
      +
        <% current_time = NaiveDateTime.utc_now() %> <%= for event <- @managed_events do %> <.live_component diff --git a/lib/claper_web/live/event_live/join.ex b/lib/claper_web/live/event_live/join.ex index 3d6f408..455116a 100644 --- a/lib/claper_web/live/event_live/join.ex +++ b/lib/claper_web/live/event_live/join.ex @@ -28,8 +28,7 @@ defmodule ClaperWeb.EventLive.Join do @impl true def handle_event("join", %{"event" => %{"code" => code}}, socket) do - {:noreply, - socket |> push_redirect(to: Routes.event_show_path(socket, :show, String.downcase(code)))} + {:noreply, socket |> push_navigate(to: ~p"/e/#{String.downcase(code)}")} end defp apply_action(socket, :join, _params) do diff --git a/lib/claper_web/live/event_live/join.html.heex b/lib/claper_web/live/event_live/join.html.heex index 9b1efa8..0624078 100644 --- a/lib/claper_web/live/event_live/join.html.heex +++ b/lib/claper_web/live/event_live/join.html.heex @@ -3,6 +3,7 @@ background: linear-gradient(-45deg, #2C033A, #21033A, #053138, #053138); background-size: 400% 400%; animation: gradient 15s ease infinite; + height: 100vh; } @@ -23,17 +24,19 @@ <%= gettext("About") %> <%= if @current_user do %> - <%= live_patch(gettext("Dashboard"), - to: Routes.event_index_path(@socket, :index), - 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" - ) %> + <.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" + > + <%= gettext("Dashboard") %> + <% else %> - <%= live_patch(gettext("Login"), - to: Routes.user_session_path(@socket, :new), - 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" - ) %> + <.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" + > + <%= gettext("Login") %> + <% end %>
@@ -64,24 +69,7 @@
- <%= if @last_event do %> - <%= live_patch to: Routes.event_show_path(@socket, :show, @last_event.code) do %> -
-
-

- <%= gettext("Return to your last presentation") %> (#<%= @last_event.code %>) -

-

- - - -

-
-
- <% end %> - <% end %> - - <%= form_for :event, Routes.event_join_path(@socket, :join), ["phx-submit": "join", "phx-hook": "JoinEvent", id: "form"], fn f -> %> + <%= form_for :event, ~p"/join", ["phx-submit": "join", "phx-hook": "JoinEvent", id: "form"], fn f -> %>
<%= text_input(f, :code, required: true, @@ -107,6 +95,23 @@
+ + <%= if @last_event do %> + <.link href={~p"/e/#{@last_event.code}"}> +
+
+

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

+

+ + + +

+
+
+ + <% end %> <% end %>
diff --git a/lib/claper_web/live/event_live/manage.ex b/lib/claper_web/live/event_live/manage.ex index 9442c6d..cba079f 100644 --- a/lib/claper_web/live/event_live/manage.ex +++ b/lib/claper_web/live/event_live/manage.ex @@ -21,12 +21,11 @@ defmodule ClaperWeb.EventLive.Manage do if is_nil(event) || not is_leader(socket, event) do {:ok, socket - |> put_flash(:error, gettext("Presentation doesn't exist")) + |> put_flash(:error, gettext("Event doesn't exist")) |> redirect(to: "/")} else if connected?(socket) do Claper.Events.Event.subscribe(event.uuid) - # Claper.Presentations.subscribe(event.presentation_file.id) Presence.track( self(), @@ -36,14 +35,27 @@ defmodule ClaperWeb.EventLive.Manage do ) end + posts = list_all_posts(socket, event.uuid) + pinned_posts = list_pinned_posts(socket, event.uuid) + questions = list_all_questions(socket, event.uuid) + socket = socket + |> assign(:settings_modal, false) |> assign(:attendees_nb, 1) |> assign(:event, event) + |> assign(:sort_questions_by, "date") |> assign(:state, event.presentation_file.presentation_state) - |> assign(:pinned_posts, list_pinned_posts(socket, event.uuid)) - |> assign(:all_posts, list_all_posts(socket, event.uuid)) - |> assign(:pinned_post_count, length(list_pinned_posts(socket, event.uuid))) + |> stream(:posts, posts) + |> stream(:questions, questions) + |> stream(:pinned_posts, pinned_posts) + |> assign(:pinned_post_count, length(pinned_posts)) + |> assign(:question_count, length(questions)) + |> assign(:post_count, length(posts)) + |> assign( + :form_submit_count, + length(list_form_submits(socket, event.presentation_file.id)) + ) |> assign(:polls, list_polls(socket, event.presentation_file.id)) |> assign(:forms, list_forms(socket, event.presentation_file.id)) |> assign(:embeds, list_embeds(socket, event.presentation_file.id)) @@ -58,7 +70,7 @@ defmodule ClaperWeb.EventLive.Manage do |> form_at_position(false) |> embed_at_position(false) - {:ok, socket, temporary_assigns: [all_posts: [], pinned_posts: [], form_submits: []]} + {:ok, socket} end end @@ -76,37 +88,67 @@ defmodule ClaperWeb.EventLive.Manage do @impl true def handle_info({:post_created, post}, socket) do - {:noreply, - socket - |> assign(:all_posts, [post | socket.assigns.all_posts]) - |> push_event("scroll", %{})} + socket = + socket + |> stream_insert(:posts, post) + |> update(:post_count, fn post_count -> post_count + 1 end) + + case post.body =~ "?" do + true -> + {:noreply, + socket + |> stream_insert(:questions, post) + |> update(:question_count, fn question_count -> question_count + 1 end) + |> push_event("scroll", %{})} + + _ -> + {:noreply, socket |> push_event("scroll", %{})} + end end @impl true def handle_info({:post_updated, updated_post}, socket) do {:noreply, socket - |> update(:all_posts, fn posts -> [updated_post | posts] end) - |> update(:pinned_posts, fn posts -> [updated_post | posts] end)} + |> stream_insert(:posts, updated_post) + |> then(fn socket -> + sorted_questions = + list_all_questions(socket, socket.assigns.event.uuid, socket.assigns.sort_questions_by) + + stream(socket, :questions, sorted_questions, reset: true) + end) + |> stream_insert(:pinned_posts, updated_post)} end @impl true def handle_info({:post_deleted, deleted_post}, socket) do - {:noreply, - socket - |> update(:all_posts, fn posts -> [deleted_post | posts] end) - |> update(:pinned_posts, fn posts -> [deleted_post | posts] end) - |> update(:pinned_post_count, fn pinned_post_count -> - pinned_post_count - if deleted_post.pinned, do: 1, else: 0 - end)} + socket = + socket + |> stream_delete(:posts, deleted_post) + |> stream_delete(:pinned_posts, deleted_post) + |> update(:pinned_post_count, fn pinned_post_count -> + pinned_post_count - if deleted_post.pinned, do: 1, else: 0 + end) + |> update(:post_count, fn post_count -> post_count - 1 end) + + case deleted_post.body =~ "?" do + true -> + {:noreply, + socket + |> stream_delete(:questions, deleted_post) + |> update(:question_count, fn question_count -> question_count - 1 end)} + + _ -> + {:noreply, socket} + end end @impl true def handle_info({:post_pinned, post}, socket) do updated_socket = socket - |> update(:all_posts, fn all_posts -> [post | all_posts] end) - |> update(:pinned_posts, fn pinned_posts -> [post | pinned_posts] end) + |> stream_insert(:posts, post) + |> stream_insert(:pinned_posts, post) |> assign(:pinned_post_count, socket.assigns.pinned_post_count + 1) {:noreply, updated_socket} @@ -116,8 +158,8 @@ defmodule ClaperWeb.EventLive.Manage do def handle_info({:post_unpinned, post}, socket) do updated_socket = socket - |> update(:all_posts, fn all_posts -> [post | all_posts] end) - |> update(:pinned_posts, fn pinned_posts -> [post | pinned_posts] end) + |> stream_insert(:posts, post) + |> stream_delete(:pinned_posts, post) |> assign(:pinned_post_count, socket.assigns.pinned_post_count - 1) {:noreply, updated_socket} @@ -127,18 +169,22 @@ defmodule ClaperWeb.EventLive.Manage do def handle_info({:form_submit_created, fs}, socket) do {:noreply, socket - |> update(:form_submits, fn form_submits -> [fs | form_submits] end) + |> stream_insert(:form_submits, fs) + |> update(:form_submit_count, fn form_submit_count -> form_submit_count + 1 end) |> push_event("scroll", %{})} end @impl true def handle_info({:form_submit_updated, fs}, socket) do - {:noreply, socket |> update(:form_submits, fn form_submits -> [fs | form_submits] end)} + {:noreply, socket |> stream_insert(:form_submits, fs)} end @impl true def handle_info({:form_submit_deleted, fs}, socket) do - {:noreply, socket |> update(:form_submits, fn form_submits -> [fs | form_submits] end)} + {:noreply, + socket + |> stream_delete(:form_submits, fs) + |> update(:form_submit_count, fn form_submit_count -> form_submit_count - 1 end)} end @impl true @@ -218,14 +264,14 @@ defmodule ClaperWeb.EventLive.Manage do {:noreply, socket |> put_flash(:info, gettext("Interactions imported successfully")) - |> redirect(to: Routes.event_manage_path(socket, :show, current_event.code))} + |> redirect(to: ~p"/e/#{current_event.code}/manage")} end rescue Ecto.NoResultsError -> {:noreply, socket |> put_flash(:error, gettext("Interactions import failed")) - |> redirect(to: Routes.event_manage_path(socket, :show, current_event.code))} + |> redirect(to: ~p"/e/#{current_event.code}/manage")} end end @@ -496,6 +542,40 @@ defmodule ClaperWeb.EventLive.Manage do {:noreply, socket |> assign(:state, new_state)} end + @impl true + def handle_event( + "checked", + %{"key" => "message_reaction_enabled", "value" => value}, + %{assigns: %{state: state}} = socket + ) do + {:ok, new_state} = + Claper.Presentations.update_presentation_state( + state, + %{ + :message_reaction_enabled => value + } + ) + + {:noreply, socket |> assign(:state, new_state)} + end + + @impl true + def handle_event( + "checked", + %{"key" => "show_poll_results_enabled", "value" => value}, + %{assigns: %{state: state}} = socket + ) do + {:ok, new_state} = + Claper.Presentations.update_presentation_state( + state, + %{ + :show_poll_results_enabled => value + } + ) + + {:noreply, socket |> assign(:state, new_state)} + end + @impl true def handle_event( "checked", @@ -537,15 +617,28 @@ defmodule ClaperWeb.EventLive.Manage do updated_socket = if post.pinned do - assign(socket, :pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid)) - assign(socket, :all_posts, list_all_posts(socket, socket.assigns.event.uuid)) + stream(socket, :pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid), + reset: true + ) + + stream(socket, :posts, list_all_posts(socket, socket.assigns.event.uuid), reset: true) else - assign(socket, :all_posts, list_all_posts(socket, socket.assigns.event.uuid)) + stream(socket, :posts, list_all_posts(socket, socket.assigns.event.uuid), reset: true) end {:noreply, updated_socket} end + @impl true + def handle_event("sort-questions", %{"sort" => sort}, socket) do + {:noreply, + socket + |> assign(:sort_questions_by, sort) + |> stream(:questions, list_all_questions(socket, socket.assigns.event.uuid, sort), + reset: true + )} + end + @impl true def handle_event("delete-form-submit", %{"event-id" => event_id, "id" => id}, socket) do form = Claper.Forms.get_form_submit_by_id!(id) @@ -567,19 +660,27 @@ defmodule ClaperWeb.EventLive.Manage do case tab do "posts" -> socket - |> assign(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid)) - |> assign(:all_posts, list_all_posts(socket, socket.assigns.event.uuid)) + |> stream(:posts, list_all_posts(socket, socket.assigns.event.uuid), reset: true) + + "questions" -> + socket + |> stream(:questions, list_all_questions(socket, socket.assigns.event.uuid), + reset: true + ) "forms" -> - assign( + stream( socket, :form_submits, - list_form_submits(socket, socket.assigns.event.presentation_file.id) + list_form_submits(socket, socket.assigns.event.presentation_file.id), + reset: true ) "pinned_posts" -> socket - |> assign(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid)) + |> stream(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid), + reset: true + ) end {:noreply, socket} @@ -590,7 +691,7 @@ defmodule ClaperWeb.EventLive.Manage do if socket.assigns.create != nil do {:noreply, socket - |> push_redirect(to: Routes.event_manage_path(socket, :show, socket.assigns.event.code))} + |> push_navigate(to: ~p"/e/#{socket.assigns.event.code}/manage")} else {:noreply, socket} end @@ -621,6 +722,15 @@ defmodule ClaperWeb.EventLive.Manage do |> JS.push("maybe-redirect", target: "#add-modal") end + def toggle_settings_modal(js \\ %JS{}) do + js + |> JS.toggle( + to: "#settings-modal", + out: "animate__animated animate__fadeOut", + in: "animate__animated animate__fadeIn" + ) + end + defp apply_action(socket, :show, _params) do socket end @@ -775,6 +885,10 @@ defmodule ClaperWeb.EventLive.Manage do Claper.Posts.list_posts(event_id, [:event, :reactions]) end + defp list_all_questions(_socket, event_id, sort \\ "date") do + Claper.Posts.list_questions(event_id, [:event, :reactions], String.to_atom(sort)) + end + defp list_polls(_socket, presentation_file_id) do Claper.Polls.list_polls(presentation_file_id) end @@ -788,6 +902,6 @@ defmodule ClaperWeb.EventLive.Manage do end defp list_form_submits(_socket, presentation_file_id) do - Claper.Forms.list_form_submits(presentation_file_id) + Claper.Forms.list_form_submits(presentation_file_id, [:form]) end end diff --git a/lib/claper_web/live/event_live/manage.html.heex b/lib/claper_web/live/event_live/manage.html.heex index ebd4612..c075427 100644 --- a/lib/claper_web/live/event_live/manage.html.heex +++ b/lib/claper_web/live/event_live/manage.html.heex @@ -1,118 +1,50 @@
-
-
-
- - - - - -

- <%= @event.name %> -

-
- + @@ -153,17 +85,17 @@
- +
+
+ + +
+ + + + +
+
+
+
-
- <%= for poll <- Enum.filter(@polls, fn poll -> poll.position == index end) do %> -
-
- - - -
-
- - - <%= gettext "Poll" %> - : <%= poll.title %> - - <%= if @state.position==index do %> - <%= if poll.enabled do %> - + <% end %> + +
+ + +
+ <%= for poll <- Enum.filter(@polls, fn poll -> poll.position == index end) do %> +
+
+ + + +
+
+ + + <%= gettext "Poll" %> + : <%= poll.title %> + + <%= if @state.position==index do %> + <%= if poll.enabled do %> + + <% else %> + + <% end %> + - + - <%= gettext("Active") %> - - <% else %> - + <% end %> - - - - - - <% end %> -
-
-
- <% end %> - <%= for form <- Enum.filter(@forms, fn form -> form.position == index end) do %> -
-
- - - - - - - - - +
-
- - - <%= gettext "Form" %> - : <%= form.title %> - - <%= if @state.position==index do %> - <%= if form.enabled do %> -
+ <% end %> + <%= for form <- Enum.filter(@forms, fn form -> form.position == index end) do %> +
+
+ + + + + + + + + +
+
+ + + <%= gettext "Form" %> + : <%= form.title %> + + <%= if @state.position==index do %> + <%= if form.enabled do %> + + <% else %> + + <% end %> + - + - <%= gettext("Active") %> - - <% else %> - + <% end %> - - - - - - <% end %> -
-
-
- <% end %> - <%= for embed<- Enum.filter(@embeds, fn embed -> embed.position == index end) do %> -
-
- - - +
-
- - <%= gettext "Web content" %>: <%= embed.title %> - - <%= if @state.position == index do %> - <%= if embed.enabled do %> -
+ <% end %> + <%= for embed<- Enum.filter(@embeds, fn embed -> embed.position == index end) do %> +
+
+ + + +
+
+ + <%= gettext "Web content" %>: <%= embed.title %> + + <%= if @state.position == index do %> + <%= if embed.enabled do %> + + <% else %> + + <% end %> + - + - <%= gettext("Active") %> - - <% else %> - + <% end %> - - - - - - <% end %> +
-
-
+
+ <% end %> +
+ + <%= if @state.position==index do %> + <% end %>
- <%= if @state.position==index do %> - <% end %> -
- - <%= if @state.position==index && @state.position < @event.presentation_file.length - 1 do %> - <% end %> - <% end %> +
+
+ +
+ •••
-
-
-
- + - <%= if @list_tab==:posts do %> - <%= if Enum.count(@all_posts)==0 && Enum.count(@pinned_posts)==0 do %> + <%= if @list_tab == :posts do %>
@@ -756,373 +939,183 @@ <%= gettext("Messages from attendees will appear here.") %>

- <% end %> -
0} id="post-list" - class={"overflow-y-auto #{if Enum.count(@all_posts)> 0, do: ''} pb-5 pt-8 px-5"} - phx-update="append" - data-posts-nb={Enum.count(@all_posts)} + class="overflow-y-auto pb-5 px-5" + phx-update="stream" phx-hook="ScrollIntoDiv" - data-target="#post-list" > - <%= for post <- @all_posts do %> -
-
-
- <%= if post.attendee_identifier do %> - - <%= link( - if post.pinned do - gettext("Unpin") - else - gettext("Pin") - end, - to: "#", - phx_click: "pin", - phx_value_id: post.uuid, - phx_value_event_id: @event.uuid - ) %> - - / - - <%= link(gettext("Ban"), - to: "#", - phx_click: "ban", - phx_value_attendee_identifier: post.attendee_identifier, - data: [ - confirm: - gettext( - "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" - ) - ] - ) %> - - / - <% else %> - - <%= link( - if post.pinned do - gettext("Unpin") - else - gettext("Pin") - end, - to: "#", - phx_click: "pin", - phx_value_id: post.uuid, - phx_value_event_id: @event.uuid - ) %> - - / - - <%= link(gettext("Ban"), - to: "#", - phx_click: "ban", - phx_value_user_id: post.user_id, - data: [ - confirm: - gettext( - "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" - ) - ] - ) %> - - / - <% end %> - - <%= link(gettext("Delete"), - to: "#", - phx_click: "delete", - phx_value_id: post.uuid, - phx_value_event_id: @event.uuid - ) %> - -
- -
- <%= if post.attendee_identifier do %> - - <% else %> - - <% end %> - -
- <%= if post.name do %> -

- <%= post.name %> -

- <% end %> - -

- <%= post.body %> -

-
-
- - <%= if post.like_count> 0 || post.love_count > 0 || post.lol_count > 0 do %> -
-
- <%= if post.like_count> 0 do %> - - - <%= post.like_count %> - - <% end %> -
-
- <%= if post.love_count> 0 do %> - - - <%= post.love_count %> - - <% end %> -
-
- <%= if post.lol_count> 0 do %> - - - <%= post.lol_count %> - - <% end %> -
-
- <% end %> -
-
- <% end %> + <.live_component + :for={{id, post} <- @streams.posts} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + />
- -
- <% end %> - <%= if @list_tab == :pinned_posts do %> - <%= if Enum.count(@pinned_posts) == 0 do %> + <% end %> + + <%= if @list_tab == :questions do %>
- +

- <%= gettext("Pinned messages will appear here.") %> + <%= gettext("Questions will appear here.") %>

- <% end %> -
- <%= if Enum.any?(@pinned_posts) do %> -
- <%= for post <- @pinned_posts do %> -
0} class="overflow-y-auto max-h-full"> +
+ +
-
- <% end %> + <%= gettext("Sort by date") %> +
- <% end %> -
- <% end %> +
+ <.live_component + :for={{id, post} <- @streams.questions} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + /> +
+
+ <% end %> - <%= if @list_tab==:forms do %> - <%= if Enum.count(@form_submits)==0 do %> -
+ <%= if @list_tab == :pinned_posts do %> +
- - - - - - - +

- <%= gettext("Form submissions from attendees will appear here.") %> + <%= gettext("Pinned messages will appear here.") %>

- <% end %> -
0, do: 'max-h-full'} - pb-5 pt-8 px-5"} - phx-update="append" - data-forms-nb={Enum.count(@form_submits)} - phx-hook="ScrollIntoDiv" - data-target="#form-list" - > - <%= for submission <- @form_submits do %> + +
0} + id="pinned-post-list" + class="overflow-y-auto pb-5 px-5" + phx-update="stream" + phx-hook="ScrollIntoDiv" > + <.live_component + :for={{id, post} <- @streams.pinned_posts} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + /> +
+
+ <% end %> + + <%= if @list_tab == :forms do %> + <%= if @form_submit_count == 0 do %> +
+ + + + + + + + + + +

+ <%= gettext("Form submissions from attendees will appear here.") %> +

+
+ <% end %> +
+
@@ -1136,6 +1129,12 @@
+

+ + <%= gettext("Form") %> + : <%= submission.form.title %> +

+
<%= if submission.attendee_identifier do %>
- <% end %> -
- <% end %> -
- -
-
-
- - <%= gettext("On screen settings") %> - - -
- - <%= gettext("Show instructions") %>(Q) -
- -
- - <%= gettext("Show messages") %>(W) -
- -
- - - <%= gettext("Show only pinned messages") %>(E) - -
- -
- - <%= gettext("Show poll results") %>(R)
-
- -
- - <%= gettext("Attendees settings") %> - + <% end %> +
-
- - <%= gettext("Enable messages") %>(A) -
+ -
- - - <%= gettext("Enable anonymous messages") %>(S) - -
-
+
diff --git a/lib/claper_web/live/event_live/manageable_post_component.ex b/lib/claper_web/live/event_live/manageable_post_component.ex new file mode 100644 index 0000000..43b1fbd --- /dev/null +++ b/lib/claper_web/live/event_live/manageable_post_component.ex @@ -0,0 +1,158 @@ +defmodule ClaperWeb.EventLive.ManageablePostComponent do + use ClaperWeb, :live_component + + def render(assigns) do + assigns = assigns |> assign_new(:readonly, fn -> false end) + + ~H""" +
+
+ + + + + <%= gettext("Question") %> +
+
+ <%= if @post.attendee_identifier do %> + + <%= link( + if @post.pinned do + gettext("Unpin") + else + gettext("Pin") + end, + to: "#", + phx_click: "pin", + phx_value_id: @post.uuid, + phx_value_event_id: @event.uuid + ) %> + + / + + <%= link(gettext("Ban"), + to: "#", + phx_click: "ban", + phx_value_attendee_identifier: @post.attendee_identifier, + data: [ + confirm: + gettext( + "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" + ) + ] + ) %> + + / + <% else %> + + <%= link( + if @post.pinned do + gettext("Unpin") + else + gettext("Pin") + end, + to: "#", + phx_click: "pin", + phx_value_id: @post.uuid, + phx_value_event_id: @event.uuid + ) %> + + / + + <%= link(gettext("Ban"), + to: "#", + phx_click: "ban", + phx_value_user_id: @post.user_id, + data: [ + confirm: + gettext( + "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" + ) + ] + ) %> + + / + <% end %> + + <%= link(gettext("Delete"), + to: "#", + phx_click: "delete", + phx_value_id: @post.uuid, + phx_value_event_id: @event.uuid + ) %> + +
+ +
+ <%= if @post.attendee_identifier do %> + + <% else %> + + <% end %> + +
+ <%= if @post.name do %> +

+ <%= @post.name %> +

+ <% end %> + +

+ <%= @post.body %> +

+
+
+ + <%= if @post.like_count> 0 || @post.love_count > 0 || @post.lol_count > 0 do %> +
+
+ <%= if @post.like_count> 0 do %> + + + <%= @post.like_count %> + + <% end %> +
+
+ <%= if @post.love_count> 0 do %> + + + <%= @post.love_count %> + + <% end %> +
+
+ <%= if @post.lol_count> 0 do %> + + + <%= @post.lol_count %> + + <% end %> +
+
+ <% end %> +
+ """ + end +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 new file mode 100644 index 0000000..b6c94f7 --- /dev/null +++ b/lib/claper_web/live/event_live/manager_settings_component.ex @@ -0,0 +1,161 @@ +defmodule ClaperWeb.EventLive.ManagerSettingsComponent do + use ClaperWeb, :live_component + + def render(assigns) do + assigns = assigns |> assign_new(:show_shortcut, fn -> true end) + + ~H""" +
+
+ + <%= gettext("Presentation settings") %> + + +
+ + + <%= gettext("Show instructions") %> + + q + + +
+ +
+ + + <%= gettext("Show messages") %> + + w + + +
+ +
+ + + <%= gettext("Show only pinned messages") %> + + e + + +
+ +
+ + + <%= gettext("Show poll results") %> + + r + + +
+
+ +
+ + <%= gettext("Attendees settings") %> + + +
+ + + <%= gettext("Enable messages") %> + + a + + +
+ +
+ + + <%= gettext("Enable anonymous messages") %> + + s + + +
+ +
+ + + <%= gettext("Enable message reactions") %> + + d + + +
+ +
+ + + <%= gettext("Show poll results") %> + + f + + +
+
+
+ """ + end +end diff --git a/lib/claper_web/live/event_live/poll_component.ex b/lib/claper_web/live/event_live/poll_component.ex index 2749df1..5905487 100644 --- a/lib/claper_web/live/event_live/poll_component.ex +++ b/lib/claper_web/live/event_live/poll_component.ex @@ -59,7 +59,7 @@ defmodule ClaperWeb.EventLive.PollComponent do <%= if (length @current_poll_vote) > 0 do %>
- <%= opt.percentage %>% (<%= opt.vote_count %>) + + <%= opt.percentage %>% (<%= opt.vote_count %>) + <% else %>
- <%= opt.percentage %>% (<%= opt.vote_count %>) + + <%= opt.percentage %>% (<%= opt.vote_count %>) + <% end %> <% end %> diff --git a/lib/claper_web/live/event_live/post_component.ex b/lib/claper_web/live/event_live/post_component.ex index 88986dc..5379020 100644 --- a/lib/claper_web/live/event_live/post_component.ex +++ b/lib/claper_web/live/event_live/post_component.ex @@ -3,7 +3,7 @@ defmodule ClaperWeb.EventLive.PostComponent do def render(assigns) do ~H""" -
+
<%= if @post.attendee_identifier == @attendee_identifier || (not is_nil(@current_user) && @post.user_id == @current_user.id) do %>
- <% else %> - - <% end %> - <%= if not Enum.member?(@loved_posts, @post.id) do %> - - <% else %> - - <% end %> - <%= if not Enum.member?(@loled_posts, @post.id) do %> - - <% else %> - + <%= if @post.like_count > 0 do %> + <%= @post.like_count %> + <% end %> + + <% else %> + + <% end %> + <%= if not Enum.member?(@loved_posts, @post.id) do %> + + <% else %> + + <% end %> + <%= if not Enum.member?(@loled_posts, @post.id) do %> + + <% else %> + + <% end %> <% end %>
diff --git a/lib/claper_web/live/event_live/presenter.ex b/lib/claper_web/live/event_live/presenter.ex index 1dec23d..67ca89e 100644 --- a/lib/claper_web/live/event_live/presenter.ex +++ b/lib/claper_web/live/event_live/presenter.ex @@ -18,7 +18,7 @@ defmodule ClaperWeb.EventLive.Presenter do if is_nil(event) || not is_leader(socket, event) do {:ok, socket - |> put_flash(:error, gettext("Presentation doesn't exist")) + |> put_flash(:error, gettext("Event doesn't exist")) |> redirect(to: "/")} else if connected?(socket) do @@ -33,16 +33,24 @@ defmodule ClaperWeb.EventLive.Presenter do ) end - host = - case get_connect_params(socket) do - nil -> "" - %{"host" => host} -> host - end + endpoint_config = Application.get_env(:claper, ClaperWeb.Endpoint)[:url] + port = endpoint_config[:port] + scheme = endpoint_config[:scheme] + host = endpoint_config[:host] + path = endpoint_config[:path] + + default_ports = [80, 443] + port_suffix = if port in default_ports, do: "", else: ":" <> Integer.to_string(port) + + host = "#{scheme}://#{host}#{port_suffix}/#{path}" socket = socket |> assign(:attendees_nb, 1) - |> assign(:host, host) + |> assign( + :host, + host + ) |> assign(:event, event) |> assign(:state, event.presentation_file.presentation_state) |> assign(:posts, list_posts(socket, event.uuid)) diff --git a/lib/claper_web/live/event_live/presenter.html.heex b/lib/claper_web/live/event_live/presenter.html.heex index 0374040..9a13694 100644 --- a/lib/claper_web/live/event_live/presenter.html.heex +++ b/lib/claper_web/live/event_live/presenter.html.heex @@ -88,7 +88,7 @@ class="w-full min-h-screen flex items-center justify-center relative bg-black" >
0, do: 'opacity-100 w-3/12 px-4 showed', else: 'opacity-100 w-2/3 px-4 showed'), else: 'opacity-0 w-0 p-0'} transition-all duration-150 flex flex-col h-screen py-5 justify-end max-h-screen bg-black"} id="post-list-wrapper" phx-update="replace" > @@ -168,17 +168,19 @@
- <%= for index <- 1..@event.presentation_file.length 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"} - /> + <%= 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 %>
diff --git a/lib/claper_web/live/event_live/show.ex b/lib/claper_web/live/event_live/show.ex index ad52935..43f2541 100644 --- a/lib/claper_web/live/event_live/show.ex +++ b/lib/claper_web/live/event_live/show.ex @@ -21,7 +21,7 @@ defmodule ClaperWeb.EventLive.Show do if is_nil(event) do {:ok, socket - |> put_flash(:error, gettext("Presentation doesn't exist")) + |> put_flash(:error, gettext("Event doesn't exist")) |> redirect(to: "/")} else init( @@ -70,11 +70,12 @@ defmodule ClaperWeb.EventLive.Show do maybe_update_audience_peak(event, online) + posts = list_posts(socket, event.uuid) + socket = socket |> assign(:attendees_nb, 1) |> assign(:post_changeset, post_changeset) - |> assign(:posts, list_posts(socket, event.uuid)) |> assign(:liked_posts, reacted_posts(socket, event.id, "👍")) |> assign(:loved_posts, reacted_posts(socket, event.id, "❤️")) |> assign(:loled_posts, reacted_posts(socket, event.id, "😂")) @@ -83,6 +84,8 @@ defmodule ClaperWeb.EventLive.Show do |> assign(:event, event) |> assign(:state, event.presentation_file.presentation_state) |> assign(:nickname, "") + |> stream(:posts, posts) + |> assign(:post_count, Enum.count(posts)) |> starting_soon_assigns(event) |> get_current_poll(event) |> get_current_form(event) @@ -90,8 +93,7 @@ defmodule ClaperWeb.EventLive.Show do |> check_leader(event) |> leader_list(event) - {:ok, socket |> assign(:empty_room, Enum.empty?(socket.assigns.posts)), - temporary_assigns: [posts: []]} + {:ok, socket} end defp leader_list(socket, event) do @@ -145,9 +147,7 @@ defmodule ClaperWeb.EventLive.Show do def handle_info(:tick, %{assigns: %{diff: 0}} = socket) do {:noreply, socket - |> redirect( - to: Routes.event_show_path(socket, :show, String.downcase(socket.assigns.event.code)) - )} + |> redirect(to: ~p"/e/#{String.downcase(socket.assigns.event.code)}")} end @impl true @@ -174,16 +174,24 @@ defmodule ClaperWeb.EventLive.Show do def handle_info({:post_created, post}, socket) do {:noreply, socket - |> update(:posts, fn posts -> [post | posts] end) - |> push_event("scroll", %{}) - |> maybe_disable_empty_room} + |> stream_insert(:posts, post) + |> update(:post_count, fn count -> count + 1 end)} end @impl true def handle_info({:state_updated, presentation_state}, socket) do {:noreply, socket - |> assign(:state, presentation_state)} + |> assign(:state, presentation_state) + |> stream(:posts, list_posts(socket, socket.assigns.event.uuid), reset: true)} + end + + @impl true + def handle_info({:event_terminated, _event}, socket) do + {:noreply, + socket + |> put_flash(:error, gettext("This event has been terminated")) + |> push_navigate(to: ~p"/")} end @impl true @@ -196,7 +204,7 @@ defmodule ClaperWeb.EventLive.Show do {:noreply, socket |> put_flash(:error, gettext("You have been banned from this event")) - |> push_redirect(to: Routes.event_join_path(socket, :index))} + |> push_navigate(to: ~p"/")} else {:noreply, socket} end @@ -211,7 +219,7 @@ defmodule ClaperWeb.EventLive.Show do {:noreply, socket |> put_flash(:error, gettext("You have been banned from this event")) - |> push_redirect(to: Routes.event_join_path(socket, :index))} + |> push_navigate(to: ~p"/")} else {:noreply, socket} end @@ -256,32 +264,35 @@ defmodule ClaperWeb.EventLive.Show do @impl true def handle_info({:post_updated, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, socket |> stream_insert(:posts, post)} end @impl true def handle_info({:post_pinned, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, socket |> stream_insert(:posts, post)} end @impl true def handle_info({:post_unpinned, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, socket |> stream_insert(:posts, post)} end @impl true def handle_info({:reaction_added, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, socket |> stream_insert(:posts, post)} end @impl true def handle_info({:reaction_removed, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, socket |> stream_insert(:posts, post)} end @impl true def handle_info({:post_deleted, post}, socket) do - {:noreply, socket |> update(:posts, fn posts -> [post | posts] end)} + {:noreply, + socket + |> stream_delete(:posts, post) + |> update(:post_count, fn count -> count - 1 end)} end @impl true @@ -754,8 +765,4 @@ defmodule ClaperWeb.EventLive.Show do socket |> assign(:page_title, "##{socket.assigns.event.code} - #{socket.assigns.event.name}") end - - defp maybe_disable_empty_room(%{assigns: %{empty_room: empty_room}} = socket) do - if empty_room, do: assign(socket, :empty_room, false), else: socket - end end diff --git a/lib/claper_web/live/event_live/show.html.heex b/lib/claper_web/live/event_live/show.html.heex index e7d4aa8..36f2aff 100644 --- a/lib/claper_web/live/event_live/show.html.heex +++ b/lib/claper_web/live/event_live/show.html.heex @@ -20,7 +20,7 @@ <%= gettext("Leave") %> @@ -33,6 +33,12 @@ class="w-full bg-black fixed z-10 lg:w-1/3" style="box-shadow: 0px 15px 14px 1px rgba(0,0,0,0.75); -webkit-box-shadow: 0px 15px 14px 1px rgba(0,0,0,0.75); -moz-box-shadow: 0px 15px 14px 1px rgba(0,0,0,0.75);" > +
@@ -109,29 +116,29 @@
- <%= for post <- @posts do %> - <.live_component - module={ClaperWeb.EventLive.PostComponent} - id={"#{post.id}-post"} - post={post} - leaders={@leaders} - is_leader={@is_leader} - current_user={@current_user} - attendee_identifier={@attendee_identifier} - event={@event} - liked_posts={@liked_posts} - loved_posts={@loved_posts} - loled_posts={@loled_posts} - /> - <% end %> + <.live_component + :for={{id, post} <- @streams.posts} + module={ClaperWeb.EventLive.PostComponent} + id={id} + post={post} + leaders={@leaders} + is_leader={@is_leader} + current_user={@current_user} + attendee_identifier={@attendee_identifier} + event={@event} + reaction_enabled={@state.message_reaction_enabled} + liked_posts={@liked_posts} + loved_posts={@loved_posts} + loled_posts={@loled_posts} + />
- <%= if @empty_room && @state.chat_enabled do %> + <%= if @post_count == 0 && @state.chat_enabled do %>
<%= gettext("Be the first to react !") %> diff --git a/lib/claper_web/live/form_live/form_component.ex b/lib/claper_web/live/form_live/form_component.ex index bfb4558..a2f4271 100644 --- a/lib/claper_web/live/form_live/form_component.ex +++ b/lib/claper_web/live/form_live/form_component.ex @@ -20,7 +20,7 @@ defmodule ClaperWeb.FormLive.FormComponent do form = Forms.get_form!(id) {:ok, _} = Forms.delete_form(socket.assigns.event_uuid, form) - {:noreply, socket |> push_redirect(to: socket.assigns.return_to)} + {:noreply, socket |> push_navigate(to: socket.assigns.return_to)} end @impl true @@ -65,7 +65,7 @@ defmodule ClaperWeb.FormLive.FormComponent do {:ok, _form} -> {:noreply, socket - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} @@ -83,7 +83,7 @@ defmodule ClaperWeb.FormLive.FormComponent do {:noreply, socket |> maybe_change_current_form(form) - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, changeset: changeset)} diff --git a/lib/claper_web/live/live_helpers.ex b/lib/claper_web/live/live_helpers.ex index 7124ae5..9057a38 100644 --- a/lib/claper_web/live/live_helpers.ex +++ b/lib/claper_web/live/live_helpers.ex @@ -1,23 +1,2 @@ defmodule ClaperWeb.LiveHelpers do - import Phoenix.LiveView.Helpers - - @doc """ - Renders a component inside the `ClaperWeb.ModalComponent` component. - - The rendered modal receives a `:return_to` option to properly update - the URL when the modal is closed. - - ## Examples - - <%= live_modal ClaperWeb.PostLive.FormComponent, - id: @post.id || :new, - action: @live_action, - post: @post, - return_to: Routes.post_index_path(@socket, :index) %> - """ - def live_modal(component, opts) do - path = Keyword.fetch!(opts, :return_to) - modal_opts = [id: :modal, return_to: path, component: component, opts: opts] - live_component(ClaperWeb.ModalComponent, modal_opts) - end end diff --git a/lib/claper_web/live/poll_live/form_component.ex b/lib/claper_web/live/poll_live/form_component.ex index fdabbff..79aafa6 100644 --- a/lib/claper_web/live/poll_live/form_component.ex +++ b/lib/claper_web/live/poll_live/form_component.ex @@ -20,7 +20,7 @@ defmodule ClaperWeb.PollLive.FormComponent do poll = Polls.get_poll!(id) {:ok, _} = Polls.delete_poll(socket.assigns.event_uuid, poll) - {:noreply, socket |> push_redirect(to: socket.assigns.return_to)} + {:noreply, socket |> push_navigate(to: socket.assigns.return_to)} end @impl true @@ -65,7 +65,7 @@ defmodule ClaperWeb.PollLive.FormComponent do {:ok, _poll} -> {:noreply, socket - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} @@ -83,7 +83,7 @@ defmodule ClaperWeb.PollLive.FormComponent do {:noreply, socket |> maybe_change_current_poll(poll) - |> push_redirect(to: socket.assigns.return_to)} + |> push_navigate(to: socket.assigns.return_to)} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, changeset: changeset)} diff --git a/lib/claper_web/live/stat_live/index.html.heex b/lib/claper_web/live/stat_live/index.html.heex index f801025..a8b060c 100644 --- a/lib/claper_web/live/stat_live/index.html.heex +++ b/lib/claper_web/live/stat_live/index.html.heex @@ -1,4 +1,4 @@ -
+

@@ -157,18 +157,20 @@

<%= gettext("Interactions history") %>

- <%= for position <- 0..@event.presentation_file.length-1 do %> + <%= for position <- 0..max(0, @event.presentation_file.length-1) 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}/#{position+1}.jpg"} - /> + <%= 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}/#{position+1}.jpg"} + /> + <% end %> <% end %> <%= for poll <- Enum.filter(@event.presentation_file.polls, fn p -> p.position == position end) do %> @@ -211,12 +213,12 @@ <% forms = Enum.filter(@event.presentation_file.forms, fn f -> f.position == position end) %> <%= for form <- forms do %> - + <%= gettext("Form") %>: <%= form.title %> <%= if length(form.form_submits) > 0 do %> - <%= link to: Routes.stat_path(@socket, :export, form.id), class: "text-xs text-white bg-primary-500 rounded-md px-2 py-0.5", method: :post do %> + <%= link to: ~p"/export/#{form.id}", class: "text-xs text-white bg-primary-500 rounded-md px-2 py-0.5", method: :post do %> <%= gettext("Export all submissions") %> <% end %> <% end %> @@ -232,12 +234,12 @@ <%= if fs.attendee_identifier do %> <% else %> <% end %> @@ -253,7 +255,7 @@ <% end %> <%= for embed <- Enum.filter(@event.presentation_file.embeds , fn e -> e.position == position end) do %> - + <%= gettext("Web content") %>: <%= embed.title %>
@@ -265,63 +267,23 @@ <% posts = Enum.filter(@posts, fn p -> p.position == position end) %> - Messages + + <%= gettext("Messages") %> + <%= if length(posts) == 0 do %>

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

<% end %>
- <%= for post <- posts do %> -
-
-
- <%= if post.attendee_identifier do %> - - <% else %> - - <% end %> - -
- <%= if post.name do %> -

<%= post.name %>

- <% end %> - -

<%= post.body %>

-
-
- - <%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %> -
-
- <%= if post.like_count > 0 do %> - - <%= post.like_count %> - <% end %> -
-
- <%= if post.love_count > 0 do %> - - <%= post.love_count %> - <% end %> -
-
- <%= if post.lol_count > 0 do %> - - <%= post.lol_count %> - <% end %> -
-
- <% end %> -
-
- <% end %> + <.live_component + :for={post <- posts} + module={ClaperWeb.EventLive.ManageablePostComponent} + readonly={true} + id={post.uuid} + event={@event} + post={post} + />
<% end %> diff --git a/lib/claper_web/live/user_live_auth.ex b/lib/claper_web/live/user_live_auth.ex index 319ebaf..ccbe3bc 100644 --- a/lib/claper_web/live/user_live_auth.ex +++ b/lib/claper_web/live/user_live_auth.ex @@ -1,7 +1,10 @@ defmodule ClaperWeb.UserLiveAuth do import Phoenix.LiveView import Phoenix.Component - alias ClaperWeb.Router.Helpers, as: Routes + + use Phoenix.VerifiedRoutes, + endpoint: ClaperWeb.Endpoint, + router: ClaperWeb.Router def on_mount(:default, _params, %{"current_user" => current_user} = _session, socket) do socket = @@ -19,11 +22,11 @@ defmodule ClaperWeb.UserLiveAuth do # else # {:halt, # redirect(socket, - # to: Routes.user_registration_path(socket, :confirm, %{email: current_user.email}) + # to: ~p"/users/register/confirm?#{[%{email: current_user.email}]}" # )} # end end def on_mount(:default, _params, _session, socket), - do: {:halt, redirect(socket, to: Routes.user_registration_path(socket, :confirm))} + do: {:halt, redirect(socket, to: ~p"/users/register/confirm")} end diff --git a/lib/claper_web/live/user_settings_live/show.ex b/lib/claper_web/live/user_settings_live/show.ex index ea8799d..18efa24 100644 --- a/lib/claper_web/live/user_settings_live/show.ex +++ b/lib/claper_web/live/user_settings_live/show.ex @@ -13,11 +13,13 @@ defmodule ClaperWeb.UserSettingsLive.Show do email_changeset = Accounts.User.email_changeset(%Accounts.User{}, %{}) password_changeset = Accounts.User.password_changeset(%Accounts.User{}, %{}) + preferences_changeset = Accounts.User.preferences_changeset(socket.assigns.current_user, %{}) {:ok, socket |> assign(:email_changeset, email_changeset) - |> assign(:password_changeset, password_changeset)} + |> assign(:password_changeset, password_changeset) + |> assign(:preferences_changeset, preferences_changeset)} end @impl true @@ -59,7 +61,7 @@ defmodule ClaperWeb.UserSettingsLive.Show do Accounts.deliver_update_email_instructions( applied_user, user.email, - &Routes.user_settings_url(socket, :confirm_email, &1) + &url(~p"/users/settings/confirm_email/#{&1}") ) {:noreply, @@ -68,7 +70,7 @@ defmodule ClaperWeb.UserSettingsLive.Show do :info, gettext("A link to confirm your email change has been sent to the new address.") ) - |> push_redirect(to: Routes.user_settings_show_path(socket, :show))} + |> push_navigate(to: ~p"/users/settings")} {:error, changeset} -> {:noreply, assign(socket, :email_changeset, changeset)} @@ -90,13 +92,47 @@ defmodule ClaperWeb.UserSettingsLive.Show do :info, gettext("Your password has been updated.") ) - |> push_redirect(to: Routes.user_settings_show_path(socket, :show))} + |> push_navigate(to: ~p"/users/settings")} {:error, changeset} -> {:noreply, assign(socket, :password_changeset, changeset)} end end + @impl true + def handle_event("save", %{"action" => "update_preferences"} = params, socket) do + locale = params["user"]["locale"] + available_locales = Gettext.known_locales(ClaperWeb.Gettext) + + if Enum.member?(available_locales, locale) do + case Accounts.update_user_preferences(socket.assigns.current_user, params["user"]) do + {:ok, _applied_user} -> + {:noreply, + socket + |> put_flash( + :info, + gettext("Your preferences have been updated.") + ) + |> redirect(to: ~p"/users/settings")} + + {:error, changeset} -> + {:noreply, assign(socket, :preferences_changeset, changeset)} + end + else + {:noreply, socket} + end + end + + @impl true + def handle_event("delete_account", _params, %{assigns: %{current_user: user}} = socket) do + Accounts.delete(user) + + {:noreply, + socket + |> put_flash(:info, gettext("Your account has been deleted.")) + |> redirect(to: ~p"/users/log_in")} + end + @impl true def handle_event("validate", _params, socket) do {:noreply, socket} 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 1453f02..1487dbc 100644 --- a/lib/claper_web/live/user_settings_live/show.html.heex +++ b/lib/claper_web/live/user_settings_live/show.html.heex @@ -1,14 +1,14 @@ -
+

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

-
+
<%= if @live_action in [:edit_email] do %> <.live_component module={ClaperWeb.ModalComponent} @@ -16,7 +16,7 @@ id="modal-wrapper" title={@page_title} description={@page_description} - return_to={Routes.user_settings_show_path(@socket, :show)} + return_to={~p"/users/settings"} >
<.form @@ -52,7 +52,7 @@ id="modal-wrapper" title={@page_title} description={@page_description} - return_to={Routes.user_settings_show_path(@socket, :show)} + return_to={~p"/users/settings"} >
<.form @@ -93,7 +93,7 @@ <%= gettext("Personal informations") %>

- <%= gettext("Your personal informations only visible by you") %> + <%= gettext("Your personal informations to access your account") %>

@@ -105,10 +105,12 @@
<%= @current_user.email %> - <%= live_patch(gettext("Change"), - to: Routes.user_settings_show_path(@socket, :edit_email), - class: "rounded-md font-medium text-purple-600 hover:text-purple-500" - ) %> + <.link + patch={~p"/users/settings/edit/email"} + class="rounded-md font-medium text-purple-600 hover:text-purple-500" + > + <%= gettext("Change") %> +
@@ -118,15 +120,73 @@
******** - <%= live_patch(gettext("Change"), - to: Routes.user_settings_show_path(@socket, :edit_password), - class: "rounded-md font-medium text-purple-600 hover:text-purple-500" - ) %> + <.link + patch={~p"/users/settings/edit/password"} + class="rounded-md font-medium text-purple-600 hover:text-purple-500" + > + <%= gettext("Change") %> +
+
+
+

+ <%= gettext("Preferences") %> +

+

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

+
+
+
+
+ <.form :let={f} for={@preferences_changeset} phx-change="save"> + <%= hidden_input(f, :action, name: "action", value: "update_preferences") %> + + +
+
+
+
+
+
+

+ <%= gettext("Danger zone") %> +

+

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

+
+
+
+
+ +
+
+
+
diff --git a/lib/claper_web/plugs/iframe.ex b/lib/claper_web/plugs/iframe.ex new file mode 100644 index 0000000..f061028 --- /dev/null +++ b/lib/claper_web/plugs/iframe.ex @@ -0,0 +1,12 @@ +defmodule ClaperWeb.Plugs.Iframe do + import Plug.Conn + def init(_), do: %{} + + def call(conn, _opts) do + conn + |> put_resp_header( + "x-frame-options", + "ALLOWALL" + ) + end +end diff --git a/lib/claper_web/plugs/locale.ex b/lib/claper_web/plugs/locale.ex index fa1fc26..53bd15d 100644 --- a/lib/claper_web/plugs/locale.ex +++ b/lib/claper_web/plugs/locale.ex @@ -66,6 +66,7 @@ defmodule ClaperWeb.Plugs.Locale do def call(conn, _opts) do known_locales = Gettext.known_locales(ClaperWeb.Gettext) + user_locale = Map.get(conn.assigns.current_user || %{}, :locale) accepted_languages = extract_accept_language(conn) @@ -73,10 +74,10 @@ defmodule ClaperWeb.Plugs.Locale do case accepted_languages do [locale | _] -> - Gettext.put_locale(ClaperWeb.Gettext, locale) + Gettext.put_locale(ClaperWeb.Gettext, user_locale || locale) conn - |> put_session(:locale, locale) + |> put_session(:locale, user_locale || locale) _ -> conn diff --git a/lib/claper_web/router.ex b/lib/claper_web/router.ex index 8cf4663..741048e 100644 --- a/lib/claper_web/router.ex +++ b/lib/claper_web/router.ex @@ -29,7 +29,7 @@ defmodule ClaperWeb.Router do live_session :attendee do scope "/", ClaperWeb do - pipe_through([:browser, :attendee_registration]) + pipe_through([:browser, :attendee_registration, ClaperWeb.Plugs.Iframe]) live("/", EventLive.Join, :index) live("/join", EventLive.Join, :join) diff --git a/lib/claper_web/templates/error/404.html.heex b/lib/claper_web/templates/error/404.html.heex index 363b4b0..a6cfd75 100644 --- a/lib/claper_web/templates/error/404.html.heex +++ b/lib/claper_web/templates/error/404.html.heex @@ -5,20 +5,11 @@ <%= csrf_meta_tag() %> - <%= live_title_tag(assigns[:page_title] || "Claper", suffix: " · Claper") %> - - - - @@ -41,10 +32,9 @@

- <%= live_patch(gettext("Return to home"), - to: Routes.event_join_path(@conn, :index), - class: "text-sm text-white underline" - ) %> + + <%= gettext("Return to home") %> +
diff --git a/lib/claper_web/templates/error/500.html.heex b/lib/claper_web/templates/error/500.html.heex index ae4e578..6162aa6 100644 --- a/lib/claper_web/templates/error/500.html.heex +++ b/lib/claper_web/templates/error/500.html.heex @@ -5,20 +5,11 @@ <%= csrf_meta_tag() %> - <%= live_title_tag(assigns[:page_title] || "Claper", suffix: " · Claper.co") %> - - - - @@ -42,10 +33,9 @@

- <%= live_patch(gettext("Return to home"), - to: Routes.event_join_path(@conn, :index), - class: "text-sm text-white underline" - ) %> + + <%= gettext("Return to home") %> +

diff --git a/lib/claper_web/templates/layout/_profile_dropdown.html.heex b/lib/claper_web/templates/layout/_profile_dropdown.html.heex index cd2ab36..65c90dd 100644 --- a/lib/claper_web/templates/layout/_profile_dropdown.html.heex +++ b/lib/claper_web/templates/layout/_profile_dropdown.html.heex @@ -1,7 +1,7 @@
-
+
- + @@ -11,21 +11,8 @@
<%= link(gettext("Logout"), - to: Routes.user_session_path(@conn, :delete), + 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) %> +

+
diff --git a/lib/claper_web/templates/layout/root.html.heex b/lib/claper_web/templates/layout/root.html.heex index 3cb777e..9a903ea 100644 --- a/lib/claper_web/templates/layout/root.html.heex +++ b/lib/claper_web/templates/layout/root.html.heex @@ -5,20 +5,11 @@ <%= csrf_meta_tag() %> - <%= live_title_tag(assigns[:page_title] || "Claper", suffix: " · Claper") %> - - - - diff --git a/lib/claper_web/templates/layout/user.html.heex b/lib/claper_web/templates/layout/user.html.heex index a1b6e94..37f0a0b 100644 --- a/lib/claper_web/templates/layout/user.html.heex +++ b/lib/claper_web/templates/layout/user.html.heex @@ -1,24 +1,15 @@ - + <%= csrf_meta_tag() %> - <%= live_title_tag(assigns[:page_title] || "Claper", suffix: " · Claper") %> - - - - 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 919a4f3..16087e6 100644 --- a/lib/claper_web/templates/page/user_confirmation/edit.html.heex +++ b/lib/claper_web/templates/page/user_confirmation/edit.html.heex @@ -1,13 +1,13 @@

Confirm account

-<.form :let={_f} for={:user} action={Routes.user_confirmation_path(@conn, :update, @token)}> +<.form :let={_f} for={:user} action={~p"/users/confirm/#{@token}"}>
<%= submit("Confirm my account") %>

- <%= link("Register", to: Routes.user_registration_path(@conn, :new)) %> | <%= link("Log in", - to: Routes.user_session_path(@conn, :new) + <%= 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 b2b1c97..cf4fbb0 100644 --- a/lib/claper_web/templates/page/user_confirmation/new.html.heex +++ b/lib/claper_web/templates/page/user_confirmation/new.html.heex @@ -1,6 +1,6 @@

Resend confirmation instructions

-<.form :let={f} for={:user} action={Routes.user_confirmation_path(@conn, :create)}> +<.form :let={f} for={:user} action={~p"/users/confirm"}> <%= label(f, :email) %> <%= email_input(f, :email, required: true) %> @@ -10,7 +10,7 @@

- <%= link("Register", to: Routes.user_registration_path(@conn, :new)) %> | <%= link("Log in", - to: Routes.user_session_path(@conn, :new) + <%= 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 d12c739..46f92e4 100644 --- a/lib/claper_web/templates/user_confirmation/new.html.heex +++ b/lib/claper_web/templates/user_confirmation/new.html.heex @@ -1,6 +1,6 @@

Resend confirmation instructions

-<%= form_for :user, Routes.user_confirmation_path(@conn, :create), fn f -> %> +<%= form_for :user, ~p"/users/confirm", fn f -> %> <%= label(f, :email) %> <%= email_input(f, :email, required: true) %> @@ -10,7 +10,7 @@ <% end %>

- <%= link("Register", to: Routes.user_registration_path(@conn, :new)) %> | <%= link("Log in", - to: Routes.user_session_path(@conn, :new) + <%= link("Register", to: ~p"/users/register") %> | <%= link("Log in", + to: ~p"/users/log_in" ) %>

diff --git a/lib/claper_web/templates/user_registration/confirm.html.heex b/lib/claper_web/templates/user_registration/confirm.html.heex index b81d502..71f0ce7 100644 --- a/lib/claper_web/templates/user_registration/confirm.html.heex +++ b/lib/claper_web/templates/user_registration/confirm.html.heex @@ -25,10 +25,9 @@

- <%= live_patch(gettext("Return to home"), - to: Routes.event_join_path(@conn, :index), - class: "text-sm text-white underline" - ) %> + <.link href={~p"/"} class="text-sm text-white underline"> + <%= gettext("Return to home") %> +
diff --git a/lib/claper_web/templates/user_registration/new.html.heex b/lib/claper_web/templates/user_registration/new.html.heex index a9be935..478c954 100644 --- a/lib/claper_web/templates/user_registration/new.html.heex +++ b/lib/claper_web/templates/user_registration/new.html.heex @@ -13,12 +13,7 @@
- <.form - :let={f} - for={@changeset} - action={Routes.user_registration_path(@conn, :create)} - class="mt-8 space-y-6" - > + <.form :let={f} for={@changeset} action={~p"/users/register"} class="mt-8 space-y-6"> <%= if @changeset.action do %> 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 e12cd69..41e79db 100644 --- a/lib/claper_web/templates/user_reset_password/new.html.heex +++ b/lib/claper_web/templates/user_reset_password/new.html.heex @@ -13,12 +13,7 @@
- <.form - :let={f} - for={@changeset} - action={Routes.user_reset_password_path(@conn, :create)} - class="mt-8 space-y-6" - > + <.form :let={f} for={@changeset} action={~p"/users/reset_password"} class="mt-8 space-y-6"> <%= if @changeset.action do %>
- <.form - :let={f} - for={@conn} - action={Routes.user_session_path(@conn, :create)} - as={:user} - class="mt-12 mb-4" - > + <.form :let={f} for={@conn} action={~p"/users/log_in"} as={:user} class="mt-12 mb-4"> <%= if @error_message do %> <% end %> @@ -70,12 +64,12 @@
<%= link(gettext("Forgot your password?"), - to: Routes.user_reset_password_path(@conn, :new), + 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"), - to: Routes.user_registration_path(@conn, :new), + to: ~p"/users/register", class: "text-white text-sm text-center" ) %> <% end %> diff --git a/lib/claper_web/views/components/input_component.ex b/lib/claper_web/views/components/input_component.ex index 864a5d1..5c2519c 100644 --- a/lib/claper_web/views/components/input_component.ex +++ b/lib/claper_web/views/components/input_component.ex @@ -106,45 +106,29 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:shortcut, fn -> nil end) ~H""" - """ @@ -154,24 +138,6 @@ defmodule ClaperWeb.Component.Input do def checked(false, key, js) do js - |> JS.remove_class("translate-x-0", - to: "#check-#{key} > span" - ) - |> JS.add_class("translate-x-6", - to: "#check-#{key} > span" - ) - |> JS.remove_class("opacity-100 ease-in duration-200", - to: "#check-#{key} > span > span" - ) - |> JS.add_class("opacity-0 ease-out duration-100", - to: "#check-#{key} > span > span" - ) - |> JS.remove_class("opacity-0 ease-out duration-100", - to: "#check-#{key} > span > span:nth-child(2)" - ) - |> JS.add_class("opacity-100 ease-in duration-200", - to: "#check-#{key} > span > span:nth-child(2)" - ) |> JS.push("checked", value: %{key: key, value: true}) end @@ -233,63 +199,6 @@ defmodule ClaperWeb.Component.Input do end def date(assigns) do - assigns = - assigns - |> assign_new(:required, fn -> false end) - |> assign_new(:autofocus, fn -> false end) - |> assign_new(:value, fn -> Map.get(assigns.form.data, assigns.key) end) - - assigns = - if Map.has_key?(assigns, :dark), - do: assign(assigns, :containerTheme, "text-white"), - else: assign(assigns, :containerTheme, "text-black") - - ~H""" -
- <%= hidden_input(@form, :utc_date, - required: @required, - "x-ref": "utc", - "phx-hook": "DefaultValue", - "data-default-value": "#{assigns.value}" - ) %> - <%= text_input(@form, @key, - required: @required, - autofocus: @autofocus, - autocomplete: @key, - class: - "transition-all bg-transparent w-full #{@containerTheme} rounded px-3 border border-gray-500 focus:border-2 focus:border-primary-500 pt-5 pb-2 focus:outline-none input active:outline-none text-left", - "x-model": "input", - "x-ref": "input", - "data-input": "true", - "x-on:change": "$refs.utc.value = moment($refs.input.value).utc().format()" - ) %> - <%= label(@form, @key, @name, - class: - "label absolute mb-0 -mt-2 pt-5 pl-3 leading-tighter text-gray-500 mt-2 cursor-text transition-all left-0", - "x-bind:class": "input.length > 0 ? 'text-sm -top-1.5' : 'top-1'", - "x-on:click": "$refs.input.focus()", - "x-on:click.away": "$refs.input.blur()" - ) %> - <%= if Keyword.has_key?(@form.errors, @key) do %> -

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

- <% end %> -
- """ - end - - def date_range(assigns) do assigns = assigns |> assign_new(:required, fn -> false end) @@ -298,47 +207,20 @@ defmodule ClaperWeb.Component.Input do |> assign_new(:readonly, fn -> false end) ~H""" -
-
- <%= hidden_input(@form, @start_date_field, "x-ref": "startDate") %> - <%= hidden_input(@form, @end_date_field, "x-ref": "endDate") %> +
+
<%= label(@form, @key, @name, class: "block text-sm font-medium text-gray-700") %>
+ <%= hidden_input(@form, @key) %> <%= text_input(@form, :local_date, - required: @required, - readonly: @readonly, - class: - "absolute z-0 outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-4 px-3 read-only:opacity-50", - "x-model": "date" - ) %> - - <%= text_input(@form, @key, autofocus: @autofocus, placeholder: @placeholder, - autocomplete: @key, + autocomplete: false, class: - "absolute z-10 bg-transparent text-transparent outline-none block w-full py-4 px-3", - "data-input": "true" + "outline-none shadow-base focus:ring-primary-500 focus:border-primary-500 block w-full text-lg border-gray-300 rounded-md py-4 px-3 read-only:opacity-50" ) %>
+ <%= if Keyword.has_key?(@form.errors, @key) do %>

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

<% end %> diff --git a/lib/claper_web/views/error_helpers.ex b/lib/claper_web/views/error_helpers.ex index 57d7a48..c569245 100644 --- a/lib/claper_web/views/error_helpers.ex +++ b/lib/claper_web/views/error_helpers.ex @@ -3,7 +3,8 @@ defmodule ClaperWeb.ErrorHelpers do Conveniences for translating and building error messages. """ - use Phoenix.HTML + import Phoenix.HTML.Form + use PhoenixHTMLHelpers @doc """ Generates tag for inlined form input errors. diff --git a/lib/claper_web/views/layout_view.ex b/lib/claper_web/views/layout_view.ex index f10c357..915811a 100644 --- a/lib/claper_web/views/layout_view.ex +++ b/lib/claper_web/views/layout_view.ex @@ -47,6 +47,6 @@ defmodule ClaperWeb.LayoutView do opts |> Keyword.put(:class, class) - live_patch(text, opts) + link(text, opts) end end diff --git a/lib/claper_web/views/leader_notifier_view.ex b/lib/claper_web/views/leader_notifier_view.ex index a657941..3e97e5c 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 Phoenix.HTML + use PhoenixHTMLHelpers end diff --git a/lib/claper_web/views/user_notifier_view.ex b/lib/claper_web/views/user_notifier_view.ex index 981728b..1a48574 100644 --- a/lib/claper_web/views/user_notifier_view.ex +++ b/lib/claper_web/views/user_notifier_view.ex @@ -1,5 +1,6 @@ defmodule ClaperWeb.UserNotifierView do use Phoenix.View, root: "lib/claper_web/templates" import ClaperWeb.Gettext - use Phoenix.HTML + import Phoenix.HTML + use PhoenixHTMLHelpers end diff --git a/mix.exs b/mix.exs index da0167b..4c5ea8e 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Claper.MixProject do use Mix.Project - @version "1.7.0" + @version "2.0.0" def project do [ @@ -18,24 +18,7 @@ defmodule Claper.MixProject do source_url: "https://github.com/ClaperCo/Claper", homepage_url: "https://claper.co", docs: [ - main: "overview", - assets: "guides/assets", logo: "priv/static/images/logo.png", - extra_section: "GUIDES", - extras: [ - "guides/introduction/overview.md", - "guides/introduction/configuration.md", - "guides/introduction/installation.md", - "guides/introduction/deployment.md", - "guides/introduction/storage.md", - "guides/usage/features.md", - "guides/usage/howto.md" - ], - groups_for_extras: [ - Introduction: ~r/guides\/introduction\/.?/, - Guides: ~r/guides\/[^\/]+\.md/, - Usage: ~r/guides\/usage\/.?/ - ], groups_for_modules: [ "User management": [ ~r/Claper\.Account\.?/, @@ -53,6 +36,14 @@ defmodule Claper.MixProject do ~r/Claper\.Event\.?/, ~r/ClaperWeb\.Event\.?/ ], + Forms: [ + ~r/Claper\.Forms\.?/, + ~r/ClaperWeb\.Form\.?/ + ], + WebContent: [ + ~r/Claper\.Embed\.?/, + ~r/ClaperWeb\.Embed\.?/ + ], Polls: [ ~r/Claper\.Polls\.?/, ~r/ClaperWeb\.Poll\.?/ @@ -87,21 +78,22 @@ defmodule Claper.MixProject do [ {:ex_aws, "~> 2.2"}, {:ex_aws_s3, "~> 2.3"}, - {:ex_doc, "~> 0.27", only: :dev, runtime: false}, + {:ex_doc, "~> 0.32", only: :dev, runtime: false}, {:bcrypt_elixir, "~> 2.0"}, {:phoenix, "~> 1.7"}, - {:phoenix_ecto, "~> 4.4"}, - {:ecto_sql, "~> 3.10"}, + {:phoenix_ecto, "~> 4.5"}, + {:ecto_sql, "~> 3.11"}, {:postgrex, ">= 0.0.0"}, - {:phoenix_html, "~> 3.0"}, - {:phoenix_live_reload, "~> 1.2", only: :dev}, - {:phoenix_live_view, "~> 0.18.3"}, - {:phoenix_swoosh, "~> 1.0"}, + {:phoenix_html, "~> 4.1"}, + {:phoenix_html_helpers, "~> 1.0"}, + {:phoenix_live_reload, "~> 1.5.2", only: :dev}, + {:phoenix_live_view, "~> 0.20.14"}, + {:phoenix_swoosh, "~> 1.2.1"}, {:phoenix_view, "~> 2.0"}, - {:floki, ">= 0.30.0", only: :test}, - {:phoenix_live_dashboard, "~> 0.7"}, + {:floki, ">= 0.36.1", only: :test}, + {:phoenix_live_dashboard, "~> 0.8"}, {:esbuild, "~> 0.2", runtime: Mix.env() == :dev}, - {:dart_sass, "~> 0.5", runtime: Mix.env() == :dev}, + {:dart_sass, "~> 0.7", runtime: Mix.env() == :dev}, {:swoosh, "~> 1.12"}, {:finch, "~> 0.16"}, {:telemetry_metrics, "~> 0.6"}, @@ -138,6 +130,11 @@ defmodule Claper.MixProject do "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 eef73a1..df10293 100644 --- a/mix.lock +++ b/mix.lock @@ -1,30 +1,30 @@ %{ "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"}, - "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "castore": {:hex, :castore, "1.0.4", "ff4d0fb2e6411c0479b1d965a814ea6d00e51eb2f58697446e9c41a97d940b28", [:mix], [], "hexpm", "9418c1b8144e11656f0be99943db4caf04612e3eaecefb5dae9a2a87565584f8"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, + "castore": {:hex, :castore, "1.0.6", "ffc42f110ebfdafab0ea159cd43d31365fa0af0ce4a02ecebf1707ae619ee727", [:mix], [], "hexpm", "374c6e7ca752296be3d6780a6d5b922854ffcc74123da90f2f328996b962d33a"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, "comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "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.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, - "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, + "credo": {:hex, :credo, "1.7.5", "643213503b1c766ec0496d828c90c424471ea54da77c8a168c725686377b9545", [: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", "f799e9b5cd1891577d8c773d245668aa74a2fcd15eb277f51a0131690ebfb3fd"}, "csv": {:hex, :csv, "3.0.5", "3c1455127e92de8845806db89554ad7d45e0212974be41dd9c38a5c881861713", [:mix], [], "hexpm", "cbbe5455c93df5f3f2943e995e28b7a8808361ba34cf3e44267d77a01eaf1609"}, - "dart_sass": {:hex, :dart_sass, "0.6.0", "1fe560c3ed5c577b6b9cf97134a0e05c82b69645d313b1ef0ffb4d659c3d0300", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "41f7bb065b5c30c3ea05e8b41aa3f9b5c62817079b94f70e2a22d133828475bb"}, - "db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"}, + "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"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"}, - "ecto": {:hex, :ecto, "3.10.1", "c6757101880e90acc6125b095853176a02da8f1afe056f91f1f90b80c9389822", [:mix], [{:decimal, "~> 1.6 or ~> 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", "d2ac4255f1601bdf7ac74c0ed971102c6829dc158719b94bd30041bbad77f87a"}, - "ecto_sql": {:hex, :ecto_sql, "3.10.1", "6ea6b3036a0b0ca94c2a02613fd9f742614b5cfe494c41af2e6571bb034dd94c", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.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", "f6a25bdbbd695f12c8171eaff0851fa4c8e72eec1e98c7364402dda9ce11c56b"}, + "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.0", "1785e69350b16514c1049330537c7da10039b1a53e1d253bbd703b135174aec3", [: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]}, {: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", "971b86e5495fc0ae1c318e35e23f389e74cf322f2c02d34037c6fc6d405006f1"}, + "ex_aws": {:hex, :ex_aws, "2.5.3", "9c2d05ba0c057395b12c7b5ca6267d14cdaec1d8e65bdf6481fe1fd245accfb4", [: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]}, {: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", "67115f1d399d7ec4d191812ee565c6106cb4b1bbf19a9d4db06f265fd87da97e"}, "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.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"}, + "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.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"}, - "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "finch": {:hex, :finch, "0.16.0", "40733f02c89f94a112518071c0a91fe86069560f5dbdb39f9150042f44dcfb1a", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f660174c4d519e5fec629016054d60edd822cdfe2b7270836739ac2f97735ec5"}, - "floki": {:hex, :floki, "0.34.2", "5fad07ef153b3b8ec110b6b155ec3780c4b2c4906297d0b4be1a7162d04a7e02", [:mix], [], "hexpm", "26b9d50f0f01796bc6be611ca815c5e0de034d2128e39cc9702eee6b66a4d1c8"}, + "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, + "floki": {:hex, :floki, "0.36.1", "712b7f2ba19a4d5a47dfe3e74d81876c95bbcbee44fe551f0af3d2a388abb3da", [:mix], [], "hexpm", "21ba57abb8204bcc70c439b423fc0dd9f0286de67dc82773a14b0200ada0995f"}, "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.22.3", "c8273e78db4a0bb6fba7e9f0fd881112f349a3117f7f7c598fa18c66c888e524", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "935f23447713954a6866f1bb28c3a878c4c011e802bcd68a726f5e558e4b64bd"}, "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"}, @@ -35,43 +35,44 @@ "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.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "libcluster": {:hex, :libcluster, "3.3.2", "84c6ebfdc72a03805955abfb5ff573f71921a3e299279cc3445445d5af619ad1", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8b691ce8185670fc8f3fc0b7ed59eff66c6889df890d13411f8f1a0e6871d8a5"}, - "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [: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", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "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"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "mint": {:hex, :mint, "1.5.1", "8db5239e56738552d85af398798c80648db0e90f343c8469f6c6d8898944fb6f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4a63e1e76a7c3956abd2c72f370a0d0aecddc3976dea5c27eccbecfa5e7d5b1e"}, + "mint": {:hex, :mint, "1.5.2", "4805e059f96028948870d23d7783613b7e6b0e2fb4e98d720383852a760067fd", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "d77d9e9ce4eb35941907f1d3df38d8f750c357865353e21d335bdcdf6d892a02"}, "mogrify": {:hex, :mogrify, "0.9.2", "b360984adea7dd6a55f18028e6327973c58de7f548fdb86c9859848aa904d5b0", [:mix], [], "hexpm", "c18d10fd70ca20e2585301616c89f6e4f7159d92efc9cc8ee579e00c886f699d"}, - "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.3.0", "9e18a119d9efc3370a3ef2a937bf0b24c088d9c4bf0ba9d7c3751d49d347d035", [:mix], [], "hexpm", "7977f183127a7cbe9346981e2f480dc04c55ffddaef746bd58debd566070eef8"}, - "nimble_pool": {:hex, :nimble_pool, "1.0.0", "5eb82705d138f4dd4423f69ceb19ac667b3b492ae570c9f5c900bb3d2f50a847", [:mix], [], "hexpm", "80be3b882d2d351882256087078e1b1952a28bf98d0a287be87e4a24a710b67a"}, + "nimble_options": {:hex, :nimble_options, "1.1.0", "3b31a57ede9cb1502071fade751ab0c7b8dbe75a9a4c2b5bbb0943a690b63172", [:mix], [], "hexpm", "8bbbb3941af3ca9acc7835f5655ea062111c9c27bcac53e004460dfd19008a99"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, - "phoenix": {:hex, :phoenix, "1.7.2", "c375ffb482beb4e3d20894f84dd7920442884f5f5b70b9f4528cbe0cedefec63", [: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.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.4", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "1ebca94b32b4d0e097ab2444a9742ed8ff3361acad17365e4e6b2e79b4792159"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, - "phoenix_html": {:hex, :phoenix_html, "3.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"}, - "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [: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]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, - "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.18", "1f38fbd7c363723f19aad1a04b5490ff3a178e37daaf6999594d5f34796c47fc", [:mix], [{: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", [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]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a5810d0472f3189ede6d2a95bda7f31c6113156b91784a3426cb0ab6a6d85214"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, - "phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.0", "a544d83fde4a767efb78f45404a74c9e37b2a9c5ea3339692e65a6966731f935", [: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", [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", "e88d117251e89a16b92222415a6d87b99a96747ddf674fc5c7631de734811dba"}, - "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, - "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, - "plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [: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", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [: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", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, + "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_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_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.15.3", "712976f504418f6dff0a3e554c40d705a9bcf89a7ccef92fc6a5ef8f16a30a97", [: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", "cc4365a3c010a56af402e0809208873d113e9c38c401cabd88027ef4f5c01fd2"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.7.0", "3ae9369c60641084363b08fe90267cbdd316df57e3557ea522114b30b63256ea", [:mix], [{:cowboy, "~> 2.7.0 or ~> 2.8.0 or ~> 2.9.0 or ~> 2.10.0", [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", "d85444fb8aa1f2fc62eabe83bbe387d81510d773886774ebdcb429b3da3c1a4a"}, + "plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"}, "porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"}, - "postgrex": {:hex, :postgrex, "0.17.1", "01c29fd1205940ee55f7addb8f1dc25618ca63a8817e56fac4f6846fc2cddcbe", [: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", "14b057b488e73be2beee508fb1955d8db90d6485c6466428fe9ccf1d6692a555"}, + "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"}, "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.12.0", "ecc85ee12947932986243299b8d28e6cdfc192c8d9e24c4c64f6738efdf344cb", [:mix], [{: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]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87db7ab0f35e358ba5eac3afc7422ed0c8c168a2d219d2a83ad8cb7a424f6cc9"}, + "swoosh": {:hex, :swoosh, "1.16.3", "4ab7dc429e84afaf8ffe1c7c06ce1acbc7ddde758d2cb9152dd2ac32289d5498", [: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.1.0", [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.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ff70980087650a72951ebd109a286d83c270e2b6610aba447140562adff8cf0a"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, - "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, + "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"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "uri_query": {:hex, :uri_query, "0.1.2", "ae35b83b472f3568c2c159eee3f3ccf585375d8a94fb5382db1ea3589e75c3b4", [:mix], [], "hexpm", "e3bc81816c98502c36498b9b2f239b89c71ce5eadfff7ceb2d6c0a2e6ae2ea0c"}, - "websock": {:hex, :websock, "0.5.0", "f6bbce90226121d62a0715bca7c986c5e43de0ccc9475d79c55381d1796368cc", [:mix], [], "hexpm", "b51ac706df8a7a48a2c622ee02d09d68be8c40418698ffa909d73ae207eb5fb8"}, - "websock_adapter": {:hex, :websock_adapter, "0.5.0", "cea35d8bbf1a6964e32d4b02ceb561dfb769c04f16d60d743885587e7d2ca55b", [:mix], [{:bandit, "~> 0.6", [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", "16318b124effab8209b1eb7906c636374f623dc9511a8278ad09c083cea5bb83"}, + "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"}, } diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po index d8fa231..f8f8fd8 100644 --- a/priv/gettext/de/LC_MESSAGES/default.po +++ b/priv/gettext/de/LC_MESSAGES/default.po @@ -8,19 +8,18 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/user_settings_live/show.ex:48 -#: lib/claper_web/live/user_settings_live/show.html.heex:5 -#: lib/claper_web/templates/layout/_user_menu.html.heex:2 +#: lib/claper_web/live/event_live/manage.html.heex:1174 +#: lib/claper_web/live/user_settings_live/show.ex:50 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Einstellungen" -#: lib/claper_web/live/event_live/manage.ex:650 +#: lib/claper_web/live/event_live/manage.ex:761 #: lib/claper_web/live/form_live/form_component.html.heex:37 #: lib/claper_web/live/user_settings_live/show.html.heex:34 -#: lib/claper_web/templates/user_registration/new.html.heex:34 -#: lib/claper_web/templates/user_reset_password/new.html.heex:33 -#: lib/claper_web/templates/user_session/new.html.heex:47 +#: 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:41 #, elixir-autogen, elixir-format msgid "Email" msgstr "E-Mail" @@ -30,20 +29,20 @@ msgstr "E-Mail" msgid "Join the Claper experience" msgstr "Werden Sie Teil der Claper Erfahrung" -#: lib/claper_web/templates/user_registration/new.html.heex:24 +#: 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:24 +#: 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 "Überprüfen Sie, ob alle Felder korrekt ausgefüllt sind." -#: lib/claper_web/live/user_settings_live/show.html.heex:108 -#: lib/claper_web/live/user_settings_live/show.html.heex:121 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#: lib/claper_web/live/user_settings_live/show.html.heex:127 #, elixir-autogen, elixir-format msgid "Change" msgstr "Ändern" -#: lib/claper_web/live/event_live/event_form_component.html.heex:239 +#: lib/claper_web/live/event_live/event_form_component.html.heex:257 #, elixir-autogen, elixir-format msgid "Code" msgstr "Code" @@ -53,7 +52,7 @@ msgstr "Code" msgid "Email address" msgstr "E-Mail Adresse" -#: lib/claper_web/templates/layout/_user_menu.html.heex:8 +#: lib/claper_web/templates/layout/_user_menu.html.heex:16 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Ausloggen" @@ -73,42 +72,36 @@ msgstr "Wir haben Ihnen bereits eine E-Mail zur Anmeldung geschickt, bitte versu msgid "We sent you an email at" msgstr "Wir haben Ihnen eine E-Mail geschickt an" -#: lib/claper_web/live/user_settings_live/show.html.heex:96 -#, elixir-autogen, elixir-format -msgid "Your personal informations only visible by you" -msgstr "Ihre persönlichen Informationen sind nur für Sie sichtbar" - -#: lib/claper_web/live/event_live/show.html.heex:405 +#: lib/claper_web/live/event_live/show.html.heex:412 #, elixir-autogen, elixir-format msgid "days" msgstr "Tage" -#: lib/claper_web/live/event_live/show.html.heex:411 +#: lib/claper_web/live/event_live/show.html.heex:418 #, elixir-autogen, elixir-format msgid "hours" msgstr "Stunden" -#: lib/claper_web/live/event_live/show.html.heex:417 +#: lib/claper_web/live/event_live/show.html.heex:424 #, elixir-autogen, elixir-format msgid "minutes" msgstr "Minuten" -#: lib/claper_web/live/event_live/show.html.heex:136 +#: lib/claper_web/live/event_live/show.html.heex:143 #, elixir-autogen, elixir-format msgid "Be the first to react !" msgstr "Seien Sie der Erste, der reagiert!" -#: lib/claper_web/live/event_live/event_card_component.ex:98 -#: lib/claper_web/live/event_live/join.ex:42 -#: lib/claper_web/live/event_live/join.html.heex:106 -#: lib/claper_web/live/event_live/show.html.heex:257 +#: 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/show.html.heex:264 #, elixir-autogen, elixir-format msgid "Join" msgstr "Teilnehmen" -#: lib/claper_web/live/event_live/index.ex:82 -#: lib/claper_web/live/event_live/join.html.heex:26 -#: lib/claper_web/live/event_live/join.html.heex:47 +#: lib/claper_web/live/event_live/index.ex:156 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Dashboard" @@ -119,38 +112,22 @@ msgstr "Dashboard" msgid "Host" msgstr "Host" -#: lib/claper_web/live/event_live/show.html.heex:423 +#: lib/claper_web/live/event_live/show.html.heex:430 #, elixir-autogen, elixir-format msgid "seconds" msgstr "Sekunden" -#: lib/claper_web/live/event_live/index.html.heex:61 -#, elixir-autogen, elixir-format -msgid "Create your first presentation" -msgstr "Erstellen Sie Ihre erste Präsentation" - -#: lib/claper_web/live/event_live/event_card_component.ex:50 -#: lib/claper_web/live/event_live/manage.html.heex:81 -#, elixir-autogen, elixir-format -msgid "Finish on" -msgstr "Endet um" - -#: lib/claper_web/live/event_live/event_card_component.ex:30 +#: lib/claper_web/live/event_live/event_card_component.ex:34 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Beendet" -#: lib/claper_web/live/event_live/event_card_component.ex:62 +#: lib/claper_web/live/event_live/event_card_component.ex:64 #, elixir-autogen, elixir-format msgid "Finished on" msgstr "Beendet um" -#: lib/claper_web/live/event_live/event_card_component.ex:20 -#, elixir-autogen, elixir-format -msgid "In progress" -msgstr "Läuft" - -#: lib/claper_web/live/event_live/event_card_component.ex:25 +#: lib/claper_web/live/event_live/event_card_component.ex:29 #, elixir-autogen, elixir-format msgid "Incoming" msgstr "Kommende" @@ -160,79 +137,53 @@ msgstr "Kommende" msgid "Leave" msgstr "Verlassen" -#: lib/claper_web/live/event_live/index.html.heex:16 -#, elixir-autogen, elixir-format -msgid "My presentations" -msgstr "Meine Präsentationen" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 -#, elixir-autogen, elixir-format -msgid "Name of your presentation" -msgstr "Name Ihrer Präsentation" - #: lib/claper_web/live/event_live/presenter.html.heex:26 -#: lib/claper_web/live/event_live/show.html.heex:432 +#: lib/claper_web/live/event_live/show.html.heex:439 #, elixir-autogen, elixir-format msgid "Scan to interact in real-time" msgstr "Scannen und in Echtzeit interagieren" -#: lib/claper_web/live/event_live/event_card_component.ex:56 +#: lib/claper_web/live/event_live/event_card_component.ex:60 #, elixir-autogen, elixir-format msgid "Starting on" msgstr "Startet um" -#: lib/claper_web/live/event_live/event_form_component.ex:206 +#: lib/claper_web/live/event_live/event_form_component.ex:253 #, elixir-autogen, elixir-format msgid "Updated successfully" msgstr "Erfolgreich aktualisiert" -#: lib/claper_web/live/event_live/event_form_component.html.heex:249 -#, elixir-autogen, elixir-format -msgid "When your presentation will be available ?" -msgstr "Wann wird Ihre Präsentation verfügbar sein?" - -#: lib/claper_web/live/event_live/join.html.heex:72 -#, elixir-autogen, elixir-format -msgid "Return to your last presentation" -msgstr "Zurück zu Ihrer letzten Präsentation" - #: lib/claper_web/templates/user_session/new.html.heex:22 #, elixir-autogen, elixir-format msgid "It's time to empower your presentations." msgstr "Es ist an der Zeit, Ihren Präsentationen mehr Bedeutung zu verleihen." -#: lib/claper_web/templates/error/404.html.heex:44 -#: lib/claper_web/templates/error/500.html.heex:45 -#: lib/claper_web/templates/user_registration/confirm.html.heex:28 +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 #, elixir-autogen, elixir-format msgid "Return to home" msgstr "Zurück zur Startseite" -#: lib/claper_web/live/event_live/event_form_component.ex:186 +#: lib/claper_web/live/event_live/event_form_component.ex:197 +#: lib/claper_web/live/event_live/event_form_component.ex:233 #, elixir-autogen, elixir-format msgid "Created successfully" msgstr "Erfolgreich erstellt" -#: lib/claper_web/live/event_live/manage.ex:24 -#: lib/claper_web/live/event_live/presenter.ex:21 -#: lib/claper_web/live/event_live/show.ex:24 -#, elixir-autogen, elixir-format -msgid "Presentation doesn't exist" -msgstr "Präsentation existiert nicht" - -#: lib/claper_web/live/event_live/event_card_component.ex:109 -#: lib/claper_web/live/event_live/event_card_component.ex:129 +#: lib/claper_web/live/event_live/event_card_component.ex:186 +#: lib/claper_web/live/event_live/event_card_component.ex:207 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:65 +#: lib/claper_web/live/event_live/index.ex:139 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Ändern" #: lib/claper_web/live/embed_live/form_component.html.heex:51 -#: lib/claper_web/live/event_live/event_form_component.html.heex:18 #: lib/claper_web/live/event_live/event_form_component.html.heex:25 -#: lib/claper_web/live/event_live/index.ex:71 -#: lib/claper_web/live/event_live/index.html.heex:40 +#: lib/claper_web/live/event_live/event_form_component.html.heex:32 +#: lib/claper_web/live/event_live/index.ex:146 +#: lib/claper_web/live/event_live/index.html.heex:64 #: lib/claper_web/live/form_live/form_component.html.heex:98 #: lib/claper_web/live/poll_live/form_component.html.heex:94 #, elixir-autogen, elixir-format @@ -240,11 +191,10 @@ msgid "Create" msgstr "Erstellen" #: lib/claper_web/live/embed_live/form_component.html.heex:56 -#: lib/claper_web/live/event_live/event_card_component.ex:171 -#: lib/claper_web/live/event_live/event_form_component.html.heex:30 -#: lib/claper_web/live/event_live/manage.html.heex:835 -#: lib/claper_web/live/event_live/manage.html.heex:1010 -#: lib/claper_web/live/event_live/manage.html.heex:1125 +#: lib/claper_web/live/event_live/event_card_component.ex:249 +#: lib/claper_web/live/event_live/event_form_component.html.heex:37 +#: lib/claper_web/live/event_live/manage.html.heex:1122 +#: 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 @@ -254,8 +204,8 @@ msgid "Delete" msgstr "Löschen" #: lib/claper_web/live/embed_live/form_component.html.heex:52 -#: lib/claper_web/live/event_live/event_form_component.html.heex:17 #: lib/claper_web/live/event_live/event_form_component.html.heex:24 +#: lib/claper_web/live/event_live/event_form_component.html.heex:31 #: lib/claper_web/live/form_live/form_component.html.heex:99 #: lib/claper_web/live/poll_live/form_component.html.heex:95 #: lib/claper_web/live/user_settings_live/show.html.heex:38 @@ -264,17 +214,17 @@ msgstr "Löschen" msgid "Save" msgstr "Speichern" -#: lib/claper_web/live/user_settings_live/show.ex:69 +#: lib/claper_web/live/user_settings_live/show.ex:71 #, elixir-autogen, elixir-format msgid "A link to confirm your email change has been sent to the new address." msgstr "Ein Link zur Bestätigung Ihrer E-Mail-Änderung wurde an die neue Adresse gesendet." -#: lib/claper_web/live/user_settings_live/show.ex:33 +#: lib/claper_web/live/user_settings_live/show.ex:35 #, elixir-autogen, elixir-format msgid "Change the email address you want associated with your account." msgstr "Ändern Sie die E-Mail-Adresse, die Sie mit Ihrem Konto verknüpfen möchten." -#: lib/claper_web/live/user_settings_live/show.ex:30 +#: lib/claper_web/live/user_settings_live/show.ex:32 #, elixir-autogen, elixir-format msgid "Update your email" msgstr "Ihre E-Mail ändern" @@ -316,73 +266,72 @@ msgstr "Wenn Sie kein Konto bei uns erstellt haben, ignorieren Sie dies bitte." msgid "You can log into your account by clicking here." msgstr "Sie können sich bei Ihrem Konto anmelden, indem Sie hier klicken." -#: lib/claper_web/live/event_live/event_form_component.html.heex:34 +#: lib/claper_web/live/event_live/event_form_component.html.heex:41 #: 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 "Sind Sie sicher?" -#: lib/claper_web/live/event_live/event_form_component.html.heex:149 +#: lib/claper_web/live/event_live/event_form_component.html.heex:162 #, elixir-autogen, elixir-format msgid "Presentation attached" msgstr "Präsentation angehängt" -#: lib/claper_web/live/event_live/event_form_component.html.heex:109 +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 #, elixir-autogen, elixir-format msgid "Presentation uploaded" msgstr "Präsentation hochgeladen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:120 -#: lib/claper_web/live/event_live/event_form_component.html.heex:198 -#: lib/claper_web/live/event_live/event_form_component.html.heex:323 -#: lib/claper_web/live/event_live/event_form_component.html.heex:346 +#: lib/claper_web/live/event_live/event_form_component.html.heex:133 +#: lib/claper_web/live/event_live/event_form_component.html.heex:211 +#: lib/claper_web/live/event_live/event_form_component.html.heex:352 +#: lib/claper_web/live/event_live/event_form_component.html.heex:375 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Entfernen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:45 -#: lib/claper_web/live/event_live/event_form_component.html.heex:130 +#: lib/claper_web/live/event_live/event_form_component.html.heex:143 #, elixir-autogen, elixir-format msgid "Select your presentation" msgstr "Wählen Sie Ihre Präsentation" -#: lib/claper_web/live/event_live/event_form_component.html.heex:72 +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Upload a file" msgstr "Datei hochladen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:76 +#: lib/claper_web/live/event_live/event_form_component.html.heex:89 #, elixir-autogen, elixir-format msgid "or drag and drop" msgstr "oder drag and drop" -#: lib/claper_web/live/event_live/event_form_component.ex:257 +#: lib/claper_web/live/event_live/event_form_component.ex:304 #, elixir-autogen, elixir-format msgid "You have selected an incorrect file type" msgstr "Sie haben einen falschen Dateityp ausgewählt" -#: lib/claper_web/live/event_live/event_form_component.ex:256 +#: lib/claper_web/live/event_live/event_form_component.ex:303 #, elixir-autogen, elixir-format msgid "Your file is too large" msgstr "Ihre Datei ist zu groß" -#: lib/claper_web/live/event_live/event_form_component.html.heex:159 +#: lib/claper_web/live/event_live/event_form_component.html.heex:172 #, elixir-autogen, elixir-format msgid "Change file" msgstr "Datei ändern" -#: lib/claper_web/live/event_live/event_form_component.html.heex:185 +#: lib/claper_web/live/event_live/event_form_component.html.heex:198 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Präsentation ersetzt" -#: lib/claper_web/live/event_live/manage.html.heex:293 +#: lib/claper_web/live/event_live/manage.html.heex:225 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Umfrage bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:292 +#: lib/claper_web/live/event_live/manage.html.heex:224 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Neue Umfrage" @@ -392,18 +341,18 @@ msgstr "Neue Umfrage" msgid "Title of your poll" msgstr "Titel Ihrer Umfrage" -#: lib/claper_web/live/event_live/event_form_component.ex:258 +#: lib/claper_web/live/event_live/event_form_component.ex:305 #, elixir-autogen, elixir-format msgid "Upload failed" msgstr "Hochladen fehlgeschlagen" -#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:112 #, 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:177 -#: lib/claper_web/live/event_live/manage.html.heex:461 +#: lib/claper_web/live/event_live/manage.html.heex:109 +#: lib/claper_web/live/event_live/manage.html.heex:604 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Umfrage" @@ -425,51 +374,36 @@ msgstr "Aktuelle Umfrage" msgid "See current poll" msgstr "Aktuelle Umfrage anzeigen" -#: lib/claper_web/live/event_live/poll_component.ex:123 -#: lib/claper_web/live/event_live/poll_component.ex:131 +#: 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 "Abstimmen" -#: lib/claper_web/live/event_live/index.html.heex:70 -#, elixir-autogen, elixir-format -msgid "Invited presentations" -msgstr "Vorstellung eingeladet" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:313 -#: lib/claper_web/live/event_live/event_form_component.html.heex:330 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#: lib/claper_web/live/event_live/event_form_component.html.heex:359 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Benutzer Email-Adresse" -#: lib/claper_web/live/event_live/event_card_component.ex:90 -#, elixir-autogen, elixir-format -msgid "Present/Customize" -msgstr "Vorstellen/Ändern" - -#: lib/claper_web/live/event_live/manage.html.heex:479 -#: lib/claper_web/live/event_live/manage.html.heex:561 -#: lib/claper_web/live/event_live/manage.html.heex:635 +#: lib/claper_web/live/event_live/manage.html.heex:622 +#: lib/claper_web/live/event_live/manage.html.heex:704 +#: lib/claper_web/live/event_live/manage.html.heex:778 #, elixir-autogen, elixir-format msgid "Active" msgstr "Aktiv" -#: lib/claper_web/live/event_live/event_form_component.html.heex:164 +#: lib/claper_web/live/event_live/event_form_component.html.heex:177 #, 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:752 +#: lib/claper_web/live/event_live/manage.html.heex:939 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Nachrichten von Teilnehmern werden hier erscheinen." -#: lib/claper_web/live/event_live/manage.html.heex:1170 -#, elixir-autogen, elixir-format -msgid "On screen settings" -msgstr "Bildschirmeinstellungen" - -#: lib/claper_web/live/event_live/event_card_component.ex:139 +#: lib/claper_web/live/event_live/event_card_component.ex:218 #, elixir-autogen, elixir-format msgid "Processing your file..." msgstr "Verarbeitung der Datei..." @@ -479,50 +413,46 @@ msgstr "Verarbeitung der Datei..." 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?" -#: lib/claper_web/live/event_live/manage.html.heex:113 -#, elixir-autogen, elixir-format -msgid "Start" -msgstr "Start" - -#: lib/claper_web/live/event_live/manage.html.heex:89 +#: lib/claper_web/live/event_live/manage.html.heex:395 #, elixir-autogen, elixir-format msgid "Press F in the presentation window to enable fullscreen" msgstr "Drücken Sie F im Präsentationsfenster, um den Vollbildmodus zu aktivieren" -#: lib/claper_web/live/event_live/show.html.heex:316 +#: lib/claper_web/live/event_live/show.html.heex:323 #, elixir-autogen, elixir-format msgid "Ask, comment..." msgstr "Fragen, kommentieren..." -#: lib/claper_web/live/event_live/manage.html.heex:710 +#: lib/claper_web/live/event_live/manage.html.heex:885 #: lib/claper_web/live/stat_live/index.html.heex:71 +#: lib/claper_web/live/stat_live/index.html.heex:271 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Nachrichten" -#: lib/claper_web/live/event_live/manage.html.heex:487 -#: lib/claper_web/live/event_live/manage.html.heex:569 -#: lib/claper_web/live/event_live/manage.html.heex:643 +#: lib/claper_web/live/event_live/manage.html.heex:630 +#: lib/claper_web/live/event_live/manage.html.heex:712 +#: lib/claper_web/live/event_live/manage.html.heex:786 #, elixir-autogen, elixir-format msgid "Set active" msgstr "Aktivieren" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:325 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Moderator hinzufügen" -#: lib/claper_web/templates/error/404.html.heex:40 +#: lib/claper_web/templates/error/404.html.heex:31 #, elixir-autogen, elixir-format msgid "Oops, page doesn't exist." msgstr "Hoppla, Seite existiert nicht." -#: lib/claper_web/templates/error/500.html.heex:40 +#: 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 "Die Seite wird gerade gewartet, wir sind bald wieder da!" -#: lib/claper_web/live/event_live/event_form_component.html.heex:275 +#: lib/claper_web/live/event_live/event_form_component.html.heex:304 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "Moderatoren können präsentieren und Interaktionen steuern" @@ -539,30 +469,26 @@ msgstr "Wenn Sie Probleme mit der obigen Schaltfläche haben, kopieren Sie die f 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:678 +#: lib/claper_web/live/event_live/manage.html.heex:830 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "Interaktion hinzufügen" -#: lib/claper_web/live/event_live/manage.html.heex:797 -#: lib/claper_web/live/event_live/manage.html.heex:826 -#: lib/claper_web/live/event_live/manage.html.heex:972 -#: lib/claper_web/live/event_live/manage.html.heex:1001 +#: 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 "Wenn Sie diesen Benutzer sperren, werden alle seine Nachrichten gelöscht, und er kann nicht mehr beitreten. Bestätigen?" #: lib/claper_web/live/event_live/show.ex:50 -#: lib/claper_web/live/event_live/show.ex:198 -#: lib/claper_web/live/event_live/show.ex:213 +#: 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 "Sie wurden von dieser Veranstaltung ausgeschlossen" -#: lib/claper_web/live/event_live/manage.html.heex:791 -#: lib/claper_web/live/event_live/manage.html.heex:820 -#: lib/claper_web/live/event_live/manage.html.heex:966 -#: lib/claper_web/live/event_live/manage.html.heex:995 +#: 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 "Ban" @@ -656,17 +582,12 @@ msgstr "Veranstaltung" msgid "Interactions history" msgstr "Interaktionsgeschichte" -#: lib/claper_web/live/stat_live/index.html.heex:271 +#: lib/claper_web/live/stat_live/index.html.heex:275 #, elixir-autogen, elixir-format msgid "No messages has been sent" msgstr "Es wurden keine Nachrichten gesendet" -#: lib/claper_web/live/event_live/event_card_component.ex:166 -#, elixir-autogen, elixir-format -msgid "Report" -msgstr "Bericht" - -#: lib/claper_web/live/event_live/event_card_component.ex:177 +#: lib/claper_web/live/event_live/event_card_component.ex:255 #, elixir-autogen, elixir-format msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" msgstr "Dadurch werden alle Daten im Zusammenhang mit Ihrer Veranstaltung gelöscht. Dies kann nicht rückgängig gemacht werden. Bestätigen?" @@ -688,25 +609,20 @@ msgstr "Max. Zuschauer" msgid "Engagement rate" msgstr "Engagementquote" -#: lib/claper_web/live/event_live/event_card_component.ex:119 +#: lib/claper_web/live/event_live/event_card_component.ex:197 #, elixir-autogen, elixir-format msgid "Error when processing the file" msgstr "Fehler beim Verarbeiten der Datei" -#: lib/claper_web/live/event_live/event_card_component.ex:71 -#, elixir-autogen, elixir-format -msgid "Error when processing the new file" -msgstr "Fehler beim Verarbeiten der neuen Datei" - -#: lib/claper_web/live/event_live/join.html.heex:23 -#: lib/claper_web/live/event_live/join.html.heex:44 +#: 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 "Über" -#: lib/claper_web/live/event_live/join.html.heex:32 -#: lib/claper_web/live/event_live/join.html.heex:53 -#: lib/claper_web/templates/user_session/new.html.heex:66 +#: 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:60 #, elixir-autogen, elixir-format msgid "Login" msgstr "Anmeldung" @@ -716,36 +632,36 @@ msgstr "Anmeldung" msgid "Connect to your account" msgstr "Verbinden Sie sich mit Ihrem Konto" -#: lib/claper_web/live/event_live/show.html.heex:441 +#: lib/claper_web/live/event_live/show.html.heex:448 #, elixir-autogen, elixir-format msgid "Or use the code:" msgstr "Oder verwenden Sie den Code:" -#: lib/claper_web/templates/user_registration/new.html.heex:51 -#: lib/claper_web/templates/user_session/new.html.heex:77 +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:71 #, elixir-autogen, elixir-format msgid "Create account" msgstr "Benutzerkonto erstellen" -#: lib/claper_web/live/user_settings_live/show.html.heex:116 -#: lib/claper_web/templates/user_registration/new.html.heex:42 +#: lib/claper_web/live/user_settings_live/show.html.heex:118 +#: 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:57 +#: lib/claper_web/templates/user_session/new.html.heex:51 #, elixir-autogen, elixir-format msgid "Password" msgstr "Passwort" -#: lib/claper_web/templates/user_session/new.html.heex:45 +#: lib/claper_web/templates/user_session/new.html.heex:39 #, elixir-autogen, elixir-format msgid "Your email address" msgstr "Ihre E-Mail-Adresse" -#: lib/claper_web/templates/user_session/new.html.heex:55 +#: lib/claper_web/templates/user_session/new.html.heex:49 #, elixir-autogen, elixir-format msgid "Your password" msgstr "Ihr Passwort" -#: lib/claper_web/live/user_settings_live/show.ex:42 +#: lib/claper_web/live/user_settings_live/show.ex:44 #, elixir-autogen, elixir-format msgid "Change the password used to access your account." msgstr "Ändern Sie das Passwort, mit dem Sie auf Ihr Konto zugreifen." @@ -760,12 +676,12 @@ msgstr "Aktuelles Passwort" msgid "New password" msgstr "Neues Kennwort" -#: lib/claper_web/live/user_settings_live/show.ex:39 +#: lib/claper_web/live/user_settings_live/show.ex:41 #, elixir-autogen, elixir-format msgid "Update your password" msgstr "Aktualisieren Sie Ihr Passwort" -#: lib/claper_web/live/user_settings_live/show.ex:91 +#: lib/claper_web/live/user_settings_live/show.ex:93 #, elixir-autogen, elixir-format msgid "Your password has been updated." msgstr "Dein Passwort wurde aktualisiert." @@ -777,7 +693,7 @@ msgid_plural "Field %{count}" msgstr[0] "Feld %{count}" msgstr[1] "Feld %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:219 +#: lib/claper_web/live/event_live/manage.html.heex:151 #, 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." @@ -787,39 +703,40 @@ 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:314 +#: lib/claper_web/live/event_live/manage.html.heex:246 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "Formular bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:216 -#: lib/claper_web/live/event_live/manage.html.heex:543 -#: lib/claper_web/live/stat_live/index.html.heex:215 +#: lib/claper_web/live/event_live/manage.html.heex:148 +#: lib/claper_web/live/event_live/manage.html.heex:686 +#: lib/claper_web/live/event_live/manage.html.heex:1134 +#: lib/claper_web/live/stat_live/index.html.heex:217 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formular" -#: lib/claper_web/live/event_live/manage.html.heex:722 +#: lib/claper_web/live/event_live/manage.html.heex:909 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Abgeschickte Formulare" -#: lib/claper_web/live/event_live/manage.html.heex:1104 +#: lib/claper_web/live/event_live/manage.html.heex:1107 #, 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:649 +#: lib/claper_web/live/event_live/manage.ex:760 #, elixir-autogen, elixir-format msgid "Name" msgstr "Name" -#: lib/claper_web/live/event_live/manage.html.heex:313 +#: lib/claper_web/live/event_live/manage.html.heex:245 #, elixir-autogen, elixir-format msgid "New form" msgstr "Neues Formular" -#: lib/claper_web/live/stat_live/index.html.heex:225 +#: lib/claper_web/live/stat_live/index.html.heex:227 #, elixir-autogen, elixir-format msgid "No form submission has been sent" msgstr "Es wurde kein Formular gesendet" @@ -839,7 +756,7 @@ msgstr "Abschicken" msgid "Text" msgstr "Text" -#: lib/claper_web/live/event_live/manage.html.heex:1130 +#: lib/claper_web/live/event_live/manage.html.heex:1127 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Dies kann nicht rückgängig gemacht werden. Bestätigen?" @@ -859,7 +776,7 @@ msgstr "Titel Ihres Formulars" msgid "Type" msgstr "Typ" -#: lib/claper_web/live/stat_live/index.html.heex:220 +#: lib/claper_web/live/stat_live/index.html.heex:222 #, elixir-autogen, elixir-format msgid "Export all submissions" msgstr "Alle Einsendungen exportieren" @@ -879,80 +796,81 @@ msgstr "Wählen Sie eine oder mehrere Optionen aus" msgid "Multiple answers" msgstr "Mehrere Antworten" -#: lib/claper_web/live/event_live/manage.html.heex:281 +#: lib/claper_web/live/event_live/manage.html.heex:213 #, elixir-autogen, elixir-format msgid "Import all interactions from another presentation" msgstr "Importieren Sie alle Interaktionen aus einer anderen Präsentation" -#: lib/claper_web/live/event_live/manage.ex:226 +#: lib/claper_web/live/event_live/manage.ex:273 #, elixir-autogen, elixir-format msgid "Interactions import failed" msgstr "Der Import der Interaktionen ist fehlgeschlagen" -#: lib/claper_web/live/event_live/manage.ex:219 +#: lib/claper_web/live/event_live/manage.ex:266 #, elixir-autogen, elixir-format msgid "Interactions imported successfully" msgstr "Interaktionen erfolgreich importiert" -#: lib/claper_web/live/event_live/manage.html.heex:354 +#: lib/claper_web/live/event_live/manage.html.heex:286 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "Präsentation auswählen" -#: lib/claper_web/live/event_live/event_form_component.html.heex:79 +#: lib/claper_web/live/event_live/event_form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX bis zu %{size} MB" -#: lib/claper_web/live/event_live/manage.html.heex:1215 +#: lib/claper_web/live/event_live/manager_settings_component.ex:86 #, elixir-autogen, elixir-format msgid "Attendees settings" msgstr "Teilnehmereinstellungen" -#: lib/claper_web/live/event_live/manage.html.heex:1224 +#: lib/claper_web/live/event_live/manager_settings_component.ex:96 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Nachrichten aktivieren" -#: lib/claper_web/live/event_live/manage.html.heex:1179 +#: lib/claper_web/live/event_live/manager_settings_component.ex:21 #, elixir-autogen, elixir-format msgid "Show instructions" msgstr "Anleitung anzeigen" -#: lib/claper_web/live/event_live/manage.html.heex:1188 +#: lib/claper_web/live/event_live/manager_settings_component.ex:38 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Nachrichten anzeigen" -#: lib/claper_web/live/event_live/manage.html.heex:1209 +#: lib/claper_web/live/event_live/manager_settings_component.ex:73 +#: lib/claper_web/live/event_live/manager_settings_component.ex:148 #, elixir-autogen, elixir-format msgid "Show poll results" msgstr "Umfrageergebnisse anzeigen" -#: lib/claper_web/live/event_live/show.html.heex:336 +#: lib/claper_web/live/event_live/show.html.heex:343 #, elixir-autogen, elixir-format msgid "Messages deactivated" msgstr "Nachrichten deaktiviert" -#: lib/claper_web/live/event_live/show.html.heex:179 -#: lib/claper_web/live/event_live/show.html.heex:200 -#: lib/claper_web/live/event_live/show.html.heex:300 +#: lib/claper_web/live/event_live/show.html.heex:186 +#: lib/claper_web/live/event_live/show.html.heex:207 +#: lib/claper_web/live/event_live/show.html.heex:307 #, elixir-autogen, elixir-format msgid "Anonymous" msgstr "Anonymous" -#: lib/claper_web/live/event_live/show.html.heex:226 +#: lib/claper_web/live/event_live/show.html.heex:233 #, elixir-autogen, elixir-format msgid "Close" msgstr "Schließen" -#: lib/claper_web/live/event_live/manage.html.heex:1234 +#: lib/claper_web/live/event_live/manager_settings_component.ex:113 #, elixir-autogen, elixir-format, fuzzy msgid "Enable anonymous messages" msgstr "Anonyme Nachrichten aktivieren" -#: lib/claper_web/live/event_live/show.html.heex:207 -#: lib/claper_web/live/event_live/show.html.heex:252 +#: lib/claper_web/live/event_live/show.html.heex:214 +#: lib/claper_web/live/event_live/show.html.heex:259 #, elixir-autogen, elixir-format, fuzzy msgid "Enter your name" msgstr "Benutze deinen Namen" @@ -962,12 +880,12 @@ msgstr "Benutze deinen Namen" msgid "Or go to %{url} and use the code:" msgstr "Oder gehen Sie zu %{url} und verwenden Sie den Code:" -#: lib/claper_web/live/event_live/show.html.heex:220 +#: lib/claper_web/live/event_live/show.html.heex:227 #, elixir-autogen, elixir-format msgid "Use your name" msgstr "Benutze deinen Namen" -#: lib/claper_web/live/event_live/show.html.heex:200 +#: lib/claper_web/live/event_live/show.html.heex:207 #, elixir-autogen, elixir-format msgid "disabled" msgstr "deaktiviert" @@ -977,7 +895,7 @@ msgstr "deaktiviert" msgid "Account creation is disabled" msgstr "Kontoerstellung ist deaktiviert" -#: lib/claper_web/live/event_live/manage.html.heex:250 +#: lib/claper_web/live/event_live/manage.html.heex:182 #, 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." @@ -987,7 +905,7 @@ msgstr "Fügen Sie ein YouTube-Video oder einen beliebigen Webinhalt hinzu." msgid "Confirm new password" msgstr "Neues Passwort bestätigen" -#: lib/claper_web/templates/user_session/new.html.heex:72 +#: lib/claper_web/templates/user_session/new.html.heex:66 #, elixir-autogen, elixir-format msgid "Forgot your password?" msgstr "Passwort vergessen?" @@ -1018,7 +936,7 @@ msgstr "Der Link zum Zurücksetzen des Kennworts ist ungültig oder er ist abgel msgid "Reset your password" msgstr "Aktualisieren Sie Ihr Passwort" -#: lib/claper_web/templates/user_reset_password/new.html.heex:41 +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 #, elixir-autogen, elixir-format msgid "Send link to reset password" msgstr "Link zum Zurücksetzen des Passworts senden" @@ -1033,12 +951,12 @@ msgstr "Der Teilnehmer kann die Webinhalte auf seinem Gerät anzeigen" msgid "Current web content" msgstr "Aktuelle Einbettung" -#: lib/claper_web/live/event_live/manage.html.heex:335 +#: lib/claper_web/live/event_live/manage.html.heex:267 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Webinhalt bearbeiten" -#: lib/claper_web/live/event_live/manage.html.heex:334 +#: lib/claper_web/live/event_live/manage.html.heex:266 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Neuer Webinhalt" @@ -1063,9 +981,9 @@ msgstr "Dies wird den Webinhalt löschen, sind Sie sicher?" msgid "Title" msgstr "Titel" -#: lib/claper_web/live/event_live/manage.html.heex:248 -#: lib/claper_web/live/event_live/manage.html.heex:618 -#: lib/claper_web/live/stat_live/index.html.heex:257 +#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:761 +#: lib/claper_web/live/stat_live/index.html.heex:259 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Webinhalt" @@ -1075,10 +993,8 @@ msgstr "Webinhalt" msgid "Invalid embed format (should start with )" msgstr "Ungültiges Einbettungsformat (sollte mit enden)" -#: lib/claper_web/live/event_live/manage.html.heex:781 -#: lib/claper_web/live/event_live/manage.html.heex:810 -#: lib/claper_web/live/event_live/manage.html.heex:956 -#: lib/claper_web/live/event_live/manage.html.heex:985 +#: 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 "Anpinnen" @@ -1089,25 +1005,23 @@ msgstr "Anpinnen" msgid "Pinned" msgstr "Angepinnt" -#: lib/claper_web/live/event_live/manage.html.heex:714 +#: lib/claper_web/live/event_live/manage.html.heex:901 #, elixir-autogen, elixir-format, fuzzy msgid "Pinned messages" msgstr "Angepinnte Nachrichten" -#: lib/claper_web/live/event_live/manage.html.heex:925 +#: lib/claper_web/live/event_live/manage.html.heex:1061 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Angepinnte Beiträge werden hier angezeigt." -#: lib/claper_web/live/event_live/manage.html.heex:1198 +#: lib/claper_web/live/event_live/manager_settings_component.ex:55 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Nur angepinnte Nachrichten anzeigen" -#: lib/claper_web/live/event_live/manage.html.heex:779 -#: lib/claper_web/live/event_live/manage.html.heex:808 -#: lib/claper_web/live/event_live/manage.html.heex:954 -#: lib/claper_web/live/event_live/manage.html.heex:983 +#: 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 "Lösen" @@ -1137,7 +1051,357 @@ msgstr "Sie wurden eingeladen" msgid "You have been invited to manage an event" msgstr "Sie wurden eingeladen, ein Ereignis zu verwalten" -#: lib/claper_web/live/event_live/form_component.ex:103 +#: lib/claper_web/live/event_live/form_component.ex:114 #, elixir-autogen, elixir-format, fuzzy msgid "Saved" msgstr "Gespeichert" + +#: lib/claper_web/live/event_live/event_card_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Access" +msgstr "Zugriff" + +#: lib/claper_web/live/user_settings_live/show.html.heex:179 +#, 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?" + +#: lib/claper_web/live/event_live/event_card_component.ex:157 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "Sind Sie sicher, dass Sie diese Veranstaltung beenden möchten? Diese Aktion kann nicht rückgängig gemacht werden." + +#: lib/claper_web/live/event_live/event_card_component.ex:149 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "Teilnehmerraum" + +#: lib/claper_web/live/user_settings_live/show.html.heex:171 +#, 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:168 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "Gefahrenzone" + +#: lib/claper_web/live/user_settings_live/show.html.heex:184 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete account" +msgstr "Konto löschen" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:130 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable message reactions" +msgstr "Nachrichtenreaktionen aktivieren" + +#: lib/claper_web/live/event_live/manage.html.heex:423 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "Präsentation öffnen" + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Terminate" +msgstr "Beenden" + +#: lib/claper_web/live/event_live/event_card_component.ex:244 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "Bericht ansehen" + +#: lib/claper_web/live/user_settings_live/show.ex:132 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "Ihr Konto wurde gelöscht." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:249 +#, elixir-autogen, elixir-format, fuzzy +msgid "Access code" +msgstr "Zugriff" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:873 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees interactions" +msgstr "Interaktionen der Teilnehmer" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:76 +#: lib/claper_web/live/event_live/manage.html.heex:327 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "Zurück" + +#: lib/claper_web/live/event_live/manage.html.heex:405 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window." +msgstr "Klicken Sie hier, um das Präsentationsfenster zu öffnen." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:298 +#, elixir-autogen, elixir-format, fuzzy +msgid "Facilitators" +msgstr "Moderatoren" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:77 +#: lib/claper_web/live/event_live/manage.html.heex:328 +#, elixir-autogen, elixir-format, fuzzy +msgid "Finish" +msgstr "Abschließen" + +#: lib/claper_web/live/event_live/manage.html.heex:875 +#, 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:875 +#, 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:4 +#: lib/claper_web/live/event_live/index.html.heex:75 +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "Next" +msgstr "Weiter" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:403 +#, 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:1176 +#, 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:1176 +#, 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:118 +#, 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:265 +#, 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:136 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create event" +msgstr "Veranstaltung erstellen" + +#: lib/claper_web/live/event_live/index.html.heex:156 +#, 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:264 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "Datum des Veranstaltungsbeginns" + +#: lib/claper_web/live/event_live/index.html.heex:88 +#, 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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "If you have slides, you can navigate through the slides with ease using the arrow keys on your keyboard." +msgstr "Wenn Sie Folien haben, können Sie mit den Pfeiltasten auf Ihrer Tastatur leicht durch die Folien navigieren." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, 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:93 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "Eilig?" + +#: lib/claper_web/live/event_live/index.html.heex:165 +#, elixir-autogen, elixir-format, fuzzy +msgid "Invited events" +msgstr "Eingeladene Veranstaltungen" + +#: lib/claper_web/live/event_live/event_card_component.ex:24 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "Live" + +#: lib/claper_web/live/event_live/index.html.heex:81 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "Meine Veranstaltungen" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:241 +#: lib/claper_web/live/event_live/index.html.heex:57 +#, 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:299 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation file (optional)" +msgstr "Präsentationsdatei (optional)" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:11 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation settings" +msgstr "Präsentationseinstellungen" + +#: lib/claper_web/live/event_live/index.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "Schnellveranstaltung" + +#: lib/claper_web/live/event_live/index.ex:73 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "Schnellveranstaltung erfolgreich erstellt" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Return to your last event" +msgstr "Zurück zu Ihrer letzten Veranstaltung" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:58 +#, elixir-autogen, elixir-format, fuzzy +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:250 +#, 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:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "Diese Veranstaltung wurde beendet" + +#: lib/claper_web/live/event_live/manage.html.heex:529 +#, elixir-autogen, elixir-format, fuzzy +msgid "This section contains all your presentation slides (if you have upload one). You have the option to add interactions to each slide." +msgstr "Dieser Abschnitt enthält alle Ihre Präsentationsfolien (falls Sie eine hochgeladen haben). Sie haben die Möglichkeit, jeder Folie Interaktionen hinzuzufügen." + +#: lib/claper_web/live/event_live/index.html.heex:117 +#, 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:274 +#, elixir-autogen, elixir-format, fuzzy +msgid "When your event will start?" +msgstr "Wann beginnt Ihre Veranstaltung?" + +#: lib/claper_web/live/event_live/manage.html.heex:528 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your slides and/or interactions" +msgstr "Ihre Folien und/oder Interaktionen" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "Erstellen Sie Ihre nächste Präsentation mit" + +#: lib/claper_web/live/event_live/manage.ex:24 +#: lib/claper_web/live/event_live/presenter.ex:21 +#: lib/claper_web/live/event_live/show.ex:24 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "Veranstaltung existiert nicht" + +#: lib/claper_web/live/user_settings_live/show.html.heex:140 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "Passen Sie Ihr Konto an" + +#: lib/claper_web/live/user_settings_live/show.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "Sprache" + +#: lib/claper_web/live/user_settings_live/show.html.heex:137 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "Einstellungen" + +#: lib/claper_web/live/user_settings_live/show.ex:114 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "Ihre Einstellungen wurden aktualisiert." + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "Frage" + +#: lib/claper_web/live/event_live/manage.html.heex:893 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "Fragen" + +#: lib/claper_web/live/event_live/manage.html.heex:980 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "Fragen werden hier erscheinen." + +#: lib/claper_web/live/event_live/manage.html.heex:1022 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "Nach Datum sortieren" + +#: lib/claper_web/live/event_live/manage.html.heex:1001 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "Nach Beliebtheit sortieren" + +#: lib/claper_web/live/event_live/event_card_component.ex:126 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "Veranstaltungsmanager" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "Dokumentation" + +#: 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 "Mein Konto" + +#: lib/claper_web/live/user_settings_live/show.html.heex:96 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your personal informations to access your account" +msgstr "Ihre persnlichen Informationen zum Zugreifen auf Ihr Konto" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 396630f..235bd45 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -10,19 +10,18 @@ msgid "" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:48 -#: lib/claper_web/live/user_settings_live/show.html.heex:5 -#: lib/claper_web/templates/layout/_user_menu.html.heex:2 +#: lib/claper_web/live/event_live/manage.html.heex:1174 +#: lib/claper_web/live/user_settings_live/show.ex:50 #, elixir-autogen, elixir-format msgid "Settings" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:650 +#: lib/claper_web/live/event_live/manage.ex:761 #: lib/claper_web/live/form_live/form_component.html.heex:37 #: lib/claper_web/live/user_settings_live/show.html.heex:34 -#: lib/claper_web/templates/user_registration/new.html.heex:34 -#: lib/claper_web/templates/user_reset_password/new.html.heex:33 -#: lib/claper_web/templates/user_session/new.html.heex:47 +#: 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:41 #, elixir-autogen, elixir-format msgid "Email" msgstr "" @@ -32,20 +31,20 @@ msgstr "" msgid "Join the Claper experience" msgstr "" -#: lib/claper_web/templates/user_registration/new.html.heex:24 +#: 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:24 +#: 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 "" -#: lib/claper_web/live/user_settings_live/show.html.heex:108 -#: lib/claper_web/live/user_settings_live/show.html.heex:121 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#: lib/claper_web/live/user_settings_live/show.html.heex:127 #, elixir-autogen, elixir-format msgid "Change" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:239 +#: lib/claper_web/live/event_live/event_form_component.html.heex:257 #, elixir-autogen, elixir-format msgid "Code" msgstr "" @@ -55,7 +54,7 @@ msgstr "" msgid "Email address" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:8 +#: lib/claper_web/templates/layout/_user_menu.html.heex:16 #, elixir-autogen, elixir-format msgid "Logout" msgstr "" @@ -75,42 +74,36 @@ msgstr "" msgid "We sent you an email at" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:96 -#, elixir-autogen, elixir-format -msgid "Your personal informations only visible by you" -msgstr "" - -#: lib/claper_web/live/event_live/show.html.heex:405 +#: lib/claper_web/live/event_live/show.html.heex:412 #, elixir-autogen, elixir-format msgid "days" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:411 +#: lib/claper_web/live/event_live/show.html.heex:418 #, elixir-autogen, elixir-format msgid "hours" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:417 +#: lib/claper_web/live/event_live/show.html.heex:424 #, elixir-autogen, elixir-format msgid "minutes" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:136 +#: lib/claper_web/live/event_live/show.html.heex:143 #, elixir-autogen, elixir-format msgid "Be the first to react !" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:98 -#: lib/claper_web/live/event_live/join.ex:42 -#: lib/claper_web/live/event_live/join.html.heex:106 -#: lib/claper_web/live/event_live/show.html.heex:257 +#: 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/show.html.heex:264 #, elixir-autogen, elixir-format msgid "Join" msgstr "" -#: lib/claper_web/live/event_live/index.ex:82 -#: lib/claper_web/live/event_live/join.html.heex:26 -#: lib/claper_web/live/event_live/join.html.heex:47 +#: lib/claper_web/live/event_live/index.ex:156 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "" @@ -121,38 +114,22 @@ msgstr "" msgid "Host" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:423 +#: lib/claper_web/live/event_live/show.html.heex:430 #, elixir-autogen, elixir-format msgid "seconds" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:61 -#, elixir-autogen, elixir-format -msgid "Create your first presentation" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:50 -#: lib/claper_web/live/event_live/manage.html.heex:81 -#, elixir-autogen, elixir-format -msgid "Finish on" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:30 +#: lib/claper_web/live/event_live/event_card_component.ex:34 #, elixir-autogen, elixir-format msgid "Finished" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:62 +#: lib/claper_web/live/event_live/event_card_component.ex:64 #, elixir-autogen, elixir-format msgid "Finished on" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:20 -#, elixir-autogen, elixir-format -msgid "In progress" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:25 +#: lib/claper_web/live/event_live/event_card_component.ex:29 #, elixir-autogen, elixir-format msgid "Incoming" msgstr "" @@ -162,79 +139,53 @@ msgstr "" msgid "Leave" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:16 -#, elixir-autogen, elixir-format -msgid "My presentations" -msgstr "" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 -#, elixir-autogen, elixir-format -msgid "Name of your presentation" -msgstr "" - #: lib/claper_web/live/event_live/presenter.html.heex:26 -#: lib/claper_web/live/event_live/show.html.heex:432 +#: lib/claper_web/live/event_live/show.html.heex:439 #, elixir-autogen, elixir-format msgid "Scan to interact in real-time" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:56 +#: lib/claper_web/live/event_live/event_card_component.ex:60 #, elixir-autogen, elixir-format msgid "Starting on" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:206 +#: lib/claper_web/live/event_live/event_form_component.ex:253 #, elixir-autogen, elixir-format msgid "Updated successfully" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:249 -#, elixir-autogen, elixir-format -msgid "When your presentation will be available ?" -msgstr "" - -#: lib/claper_web/live/event_live/join.html.heex:72 -#, elixir-autogen, elixir-format -msgid "Return to your last presentation" -msgstr "" - #: lib/claper_web/templates/user_session/new.html.heex:22 #, elixir-autogen, elixir-format msgid "It's time to empower your presentations." msgstr "" -#: lib/claper_web/templates/error/404.html.heex:44 -#: lib/claper_web/templates/error/500.html.heex:45 -#: lib/claper_web/templates/user_registration/confirm.html.heex:28 +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 #, elixir-autogen, elixir-format msgid "Return to home" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:186 +#: lib/claper_web/live/event_live/event_form_component.ex:197 +#: lib/claper_web/live/event_live/event_form_component.ex:233 #, elixir-autogen, elixir-format msgid "Created successfully" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:24 -#: lib/claper_web/live/event_live/presenter.ex:21 -#: lib/claper_web/live/event_live/show.ex:24 -#, elixir-autogen, elixir-format -msgid "Presentation doesn't exist" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:109 -#: lib/claper_web/live/event_live/event_card_component.ex:129 +#: lib/claper_web/live/event_live/event_card_component.ex:186 +#: lib/claper_web/live/event_live/event_card_component.ex:207 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:65 +#: lib/claper_web/live/event_live/index.ex:139 #, elixir-autogen, elixir-format msgid "Edit" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:51 -#: lib/claper_web/live/event_live/event_form_component.html.heex:18 #: lib/claper_web/live/event_live/event_form_component.html.heex:25 -#: lib/claper_web/live/event_live/index.ex:71 -#: lib/claper_web/live/event_live/index.html.heex:40 +#: lib/claper_web/live/event_live/event_form_component.html.heex:32 +#: lib/claper_web/live/event_live/index.ex:146 +#: lib/claper_web/live/event_live/index.html.heex:64 #: lib/claper_web/live/form_live/form_component.html.heex:98 #: lib/claper_web/live/poll_live/form_component.html.heex:94 #, elixir-autogen, elixir-format @@ -242,11 +193,10 @@ msgid "Create" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:56 -#: lib/claper_web/live/event_live/event_card_component.ex:171 -#: lib/claper_web/live/event_live/event_form_component.html.heex:30 -#: lib/claper_web/live/event_live/manage.html.heex:835 -#: lib/claper_web/live/event_live/manage.html.heex:1010 -#: lib/claper_web/live/event_live/manage.html.heex:1125 +#: lib/claper_web/live/event_live/event_card_component.ex:249 +#: lib/claper_web/live/event_live/event_form_component.html.heex:37 +#: lib/claper_web/live/event_live/manage.html.heex:1122 +#: 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 @@ -256,8 +206,8 @@ msgid "Delete" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:52 -#: lib/claper_web/live/event_live/event_form_component.html.heex:17 #: lib/claper_web/live/event_live/event_form_component.html.heex:24 +#: lib/claper_web/live/event_live/event_form_component.html.heex:31 #: lib/claper_web/live/form_live/form_component.html.heex:99 #: lib/claper_web/live/poll_live/form_component.html.heex:95 #: lib/claper_web/live/user_settings_live/show.html.heex:38 @@ -266,17 +216,17 @@ msgstr "" msgid "Save" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:69 +#: lib/claper_web/live/user_settings_live/show.ex:71 #, elixir-autogen, elixir-format msgid "A link to confirm your email change has been sent to the new address." msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:33 +#: lib/claper_web/live/user_settings_live/show.ex:35 #, elixir-autogen, elixir-format msgid "Change the email address you want associated with your account." msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:30 +#: lib/claper_web/live/user_settings_live/show.ex:32 #, elixir-autogen, elixir-format msgid "Update your email" msgstr "" @@ -318,73 +268,72 @@ msgstr "" msgid "You can log into your account by clicking here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:34 +#: lib/claper_web/live/event_live/event_form_component.html.heex:41 #: 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 "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:149 +#: lib/claper_web/live/event_live/event_form_component.html.heex:162 #, elixir-autogen, elixir-format msgid "Presentation attached" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:109 +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 #, elixir-autogen, elixir-format msgid "Presentation uploaded" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:120 -#: lib/claper_web/live/event_live/event_form_component.html.heex:198 -#: lib/claper_web/live/event_live/event_form_component.html.heex:323 -#: lib/claper_web/live/event_live/event_form_component.html.heex:346 +#: lib/claper_web/live/event_live/event_form_component.html.heex:133 +#: lib/claper_web/live/event_live/event_form_component.html.heex:211 +#: lib/claper_web/live/event_live/event_form_component.html.heex:352 +#: lib/claper_web/live/event_live/event_form_component.html.heex:375 #, elixir-autogen, elixir-format msgid "Remove" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:45 -#: lib/claper_web/live/event_live/event_form_component.html.heex:130 +#: lib/claper_web/live/event_live/event_form_component.html.heex:143 #, elixir-autogen, elixir-format msgid "Select your presentation" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:72 +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Upload a file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:76 +#: lib/claper_web/live/event_live/event_form_component.html.heex:89 #, elixir-autogen, elixir-format msgid "or drag and drop" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:257 +#: lib/claper_web/live/event_live/event_form_component.ex:304 #, elixir-autogen, elixir-format msgid "You have selected an incorrect file type" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:256 +#: lib/claper_web/live/event_live/event_form_component.ex:303 #, elixir-autogen, elixir-format msgid "Your file is too large" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:159 +#: lib/claper_web/live/event_live/event_form_component.html.heex:172 #, elixir-autogen, elixir-format msgid "Change file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:185 +#: lib/claper_web/live/event_live/event_form_component.html.heex:198 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:293 +#: lib/claper_web/live/event_live/manage.html.heex:225 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:292 +#: lib/claper_web/live/event_live/manage.html.heex:224 #, elixir-autogen, elixir-format msgid "New poll" msgstr "" @@ -394,18 +343,18 @@ msgstr "" msgid "Title of your poll" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:258 +#: lib/claper_web/live/event_live/event_form_component.ex:305 #, elixir-autogen, elixir-format msgid "Upload failed" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:112 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:177 -#: lib/claper_web/live/event_live/manage.html.heex:461 +#: lib/claper_web/live/event_live/manage.html.heex:109 +#: lib/claper_web/live/event_live/manage.html.heex:604 #, elixir-autogen, elixir-format msgid "Poll" msgstr "" @@ -427,51 +376,36 @@ msgstr "" msgid "See current poll" msgstr "" -#: lib/claper_web/live/event_live/poll_component.ex:123 -#: lib/claper_web/live/event_live/poll_component.ex:131 +#: 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 "" -#: lib/claper_web/live/event_live/index.html.heex:70 -#, elixir-autogen, elixir-format -msgid "Invited presentations" -msgstr "" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:313 -#: lib/claper_web/live/event_live/event_form_component.html.heex:330 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#: lib/claper_web/live/event_live/event_form_component.html.heex:359 #, elixir-autogen, elixir-format msgid "User email address" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:90 -#, elixir-autogen, elixir-format -msgid "Present/Customize" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:479 -#: lib/claper_web/live/event_live/manage.html.heex:561 -#: lib/claper_web/live/event_live/manage.html.heex:635 +#: lib/claper_web/live/event_live/manage.html.heex:622 +#: lib/claper_web/live/event_live/manage.html.heex:704 +#: lib/claper_web/live/event_live/manage.html.heex:778 #, elixir-autogen, elixir-format msgid "Active" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:164 +#: lib/claper_web/live/event_live/event_form_component.html.heex:177 #, 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:752 +#: lib/claper_web/live/event_live/manage.html.heex:939 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1170 -#, elixir-autogen, elixir-format -msgid "On screen settings" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:139 +#: lib/claper_web/live/event_live/event_card_component.ex:218 #, elixir-autogen, elixir-format msgid "Processing your file..." msgstr "" @@ -481,50 +415,46 @@ msgstr "" msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:113 -#, elixir-autogen, elixir-format -msgid "Start" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:89 +#: lib/claper_web/live/event_live/manage.html.heex:395 #, elixir-autogen, elixir-format msgid "Press F in the presentation window to enable fullscreen" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:316 +#: lib/claper_web/live/event_live/show.html.heex:323 #, elixir-autogen, elixir-format msgid "Ask, comment..." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:710 +#: lib/claper_web/live/event_live/manage.html.heex:885 #: lib/claper_web/live/stat_live/index.html.heex:71 +#: lib/claper_web/live/stat_live/index.html.heex:271 #, elixir-autogen, elixir-format msgid "Messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:487 -#: lib/claper_web/live/event_live/manage.html.heex:569 -#: lib/claper_web/live/event_live/manage.html.heex:643 +#: lib/claper_web/live/event_live/manage.html.heex:630 +#: lib/claper_web/live/event_live/manage.html.heex:712 +#: lib/claper_web/live/event_live/manage.html.heex:786 #, elixir-autogen, elixir-format msgid "Set active" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:325 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "" -#: lib/claper_web/templates/error/404.html.heex:40 +#: lib/claper_web/templates/error/404.html.heex:31 #, elixir-autogen, elixir-format msgid "Oops, page doesn't exist." msgstr "" -#: lib/claper_web/templates/error/500.html.heex:40 +#: 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 "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:275 +#: lib/claper_web/live/event_live/event_form_component.html.heex:304 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "" @@ -541,30 +471,26 @@ msgstr "" msgid "You can change your email by visiting the URL below" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:678 +#: lib/claper_web/live/event_live/manage.html.heex:830 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:797 -#: lib/claper_web/live/event_live/manage.html.heex:826 -#: lib/claper_web/live/event_live/manage.html.heex:972 -#: lib/claper_web/live/event_live/manage.html.heex:1001 +#: 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 "" #: lib/claper_web/live/event_live/show.ex:50 -#: lib/claper_web/live/event_live/show.ex:198 -#: lib/claper_web/live/event_live/show.ex:213 +#: 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 "" -#: lib/claper_web/live/event_live/manage.html.heex:791 -#: lib/claper_web/live/event_live/manage.html.heex:820 -#: lib/claper_web/live/event_live/manage.html.heex:966 -#: lib/claper_web/live/event_live/manage.html.heex:995 +#: 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 "" @@ -658,17 +584,12 @@ msgstr "" msgid "Interactions history" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:271 +#: lib/claper_web/live/stat_live/index.html.heex:275 #, elixir-autogen, elixir-format msgid "No messages has been sent" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:166 -#, elixir-autogen, elixir-format -msgid "Report" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:177 +#: lib/claper_web/live/event_live/event_card_component.ex:255 #, elixir-autogen, elixir-format msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" msgstr "" @@ -690,25 +611,20 @@ msgstr "" msgid "Engagement rate" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:119 +#: lib/claper_web/live/event_live/event_card_component.ex:197 #, elixir-autogen, elixir-format msgid "Error when processing the file" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:71 -#, elixir-autogen, elixir-format -msgid "Error when processing the new file" -msgstr "" - -#: lib/claper_web/live/event_live/join.html.heex:23 -#: lib/claper_web/live/event_live/join.html.heex:44 +#: 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 "" -#: lib/claper_web/live/event_live/join.html.heex:32 -#: lib/claper_web/live/event_live/join.html.heex:53 -#: lib/claper_web/templates/user_session/new.html.heex:66 +#: 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:60 #, elixir-autogen, elixir-format msgid "Login" msgstr "" @@ -718,36 +634,36 @@ msgstr "" msgid "Connect to your account" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:441 +#: lib/claper_web/live/event_live/show.html.heex:448 #, elixir-autogen, elixir-format msgid "Or use the code:" msgstr "" -#: lib/claper_web/templates/user_registration/new.html.heex:51 -#: lib/claper_web/templates/user_session/new.html.heex:77 +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:71 #, elixir-autogen, elixir-format msgid "Create account" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:116 -#: lib/claper_web/templates/user_registration/new.html.heex:42 +#: lib/claper_web/live/user_settings_live/show.html.heex:118 +#: 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:57 +#: lib/claper_web/templates/user_session/new.html.heex:51 #, elixir-autogen, elixir-format msgid "Password" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:45 +#: lib/claper_web/templates/user_session/new.html.heex:39 #, elixir-autogen, elixir-format msgid "Your email address" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:55 +#: lib/claper_web/templates/user_session/new.html.heex:49 #, elixir-autogen, elixir-format msgid "Your password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:42 +#: lib/claper_web/live/user_settings_live/show.ex:44 #, elixir-autogen, elixir-format msgid "Change the password used to access your account." msgstr "" @@ -762,12 +678,12 @@ msgstr "" msgid "New password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:39 +#: lib/claper_web/live/user_settings_live/show.ex:41 #, elixir-autogen, elixir-format msgid "Update your password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:91 +#: lib/claper_web/live/user_settings_live/show.ex:93 #, elixir-autogen, elixir-format msgid "Your password has been updated." msgstr "" @@ -779,7 +695,7 @@ msgid_plural "Field %{count}" msgstr[0] "" msgstr[1] "" -#: lib/claper_web/live/event_live/manage.html.heex:219 +#: lib/claper_web/live/event_live/manage.html.heex:151 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "" @@ -789,39 +705,40 @@ msgstr "" msgid "Current form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:314 +#: lib/claper_web/live/event_live/manage.html.heex:246 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:216 -#: lib/claper_web/live/event_live/manage.html.heex:543 -#: lib/claper_web/live/stat_live/index.html.heex:215 +#: lib/claper_web/live/event_live/manage.html.heex:148 +#: lib/claper_web/live/event_live/manage.html.heex:686 +#: lib/claper_web/live/event_live/manage.html.heex:1134 +#: lib/claper_web/live/stat_live/index.html.heex:217 #, elixir-autogen, elixir-format msgid "Form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:722 +#: lib/claper_web/live/event_live/manage.html.heex:909 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1104 +#: lib/claper_web/live/event_live/manage.html.heex:1107 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.ex:649 +#: lib/claper_web/live/event_live/manage.ex:760 #, elixir-autogen, elixir-format msgid "Name" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:313 +#: lib/claper_web/live/event_live/manage.html.heex:245 #, elixir-autogen, elixir-format msgid "New form" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:225 +#: lib/claper_web/live/stat_live/index.html.heex:227 #, elixir-autogen, elixir-format msgid "No form submission has been sent" msgstr "" @@ -841,7 +758,7 @@ msgstr "" msgid "Text" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1130 +#: lib/claper_web/live/event_live/manage.html.heex:1127 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "" @@ -861,7 +778,7 @@ msgstr "" msgid "Type" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:220 +#: lib/claper_web/live/stat_live/index.html.heex:222 #, elixir-autogen, elixir-format msgid "Export all submissions" msgstr "" @@ -881,80 +798,81 @@ msgstr "" msgid "Multiple answers" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:281 +#: lib/claper_web/live/event_live/manage.html.heex:213 #, elixir-autogen, elixir-format msgid "Import all interactions from another presentation" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:226 +#: lib/claper_web/live/event_live/manage.ex:273 #, elixir-autogen, elixir-format msgid "Interactions import failed" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:219 +#: lib/claper_web/live/event_live/manage.ex:266 #, elixir-autogen, elixir-format msgid "Interactions imported successfully" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:354 +#: lib/claper_web/live/event_live/manage.html.heex:286 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:79 +#: lib/claper_web/live/event_live/event_form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1215 +#: lib/claper_web/live/event_live/manager_settings_component.ex:86 #, elixir-autogen, elixir-format msgid "Attendees settings" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1224 +#: lib/claper_web/live/event_live/manager_settings_component.ex:96 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1179 +#: lib/claper_web/live/event_live/manager_settings_component.ex:21 #, elixir-autogen, elixir-format msgid "Show instructions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1188 +#: lib/claper_web/live/event_live/manager_settings_component.ex:38 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1209 +#: lib/claper_web/live/event_live/manager_settings_component.ex:73 +#: lib/claper_web/live/event_live/manager_settings_component.ex:148 #, elixir-autogen, elixir-format msgid "Show poll results" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:336 +#: lib/claper_web/live/event_live/show.html.heex:343 #, elixir-autogen, elixir-format msgid "Messages deactivated" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:179 -#: lib/claper_web/live/event_live/show.html.heex:200 -#: lib/claper_web/live/event_live/show.html.heex:300 +#: lib/claper_web/live/event_live/show.html.heex:186 +#: lib/claper_web/live/event_live/show.html.heex:207 +#: lib/claper_web/live/event_live/show.html.heex:307 #, elixir-autogen, elixir-format msgid "Anonymous" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:226 +#: lib/claper_web/live/event_live/show.html.heex:233 #, elixir-autogen, elixir-format msgid "Close" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1234 +#: lib/claper_web/live/event_live/manager_settings_component.ex:113 #, elixir-autogen, elixir-format msgid "Enable anonymous messages" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:207 -#: lib/claper_web/live/event_live/show.html.heex:252 +#: lib/claper_web/live/event_live/show.html.heex:214 +#: lib/claper_web/live/event_live/show.html.heex:259 #, elixir-autogen, elixir-format msgid "Enter your name" msgstr "" @@ -964,12 +882,12 @@ msgstr "" msgid "Or go to %{url} and use the code:" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:220 +#: lib/claper_web/live/event_live/show.html.heex:227 #, elixir-autogen, elixir-format msgid "Use your name" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:200 +#: lib/claper_web/live/event_live/show.html.heex:207 #, elixir-autogen, elixir-format msgid "disabled" msgstr "" @@ -979,7 +897,7 @@ msgstr "" msgid "Account creation is disabled" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:250 +#: lib/claper_web/live/event_live/manage.html.heex:182 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "" @@ -989,7 +907,7 @@ msgstr "" msgid "Confirm new password" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:72 +#: lib/claper_web/templates/user_session/new.html.heex:66 #, elixir-autogen, elixir-format msgid "Forgot your password?" msgstr "" @@ -1020,7 +938,7 @@ msgstr "" msgid "Reset your password" msgstr "" -#: lib/claper_web/templates/user_reset_password/new.html.heex:41 +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 #, elixir-autogen, elixir-format msgid "Send link to reset password" msgstr "" @@ -1035,12 +953,12 @@ msgstr "" msgid "Current web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:335 +#: lib/claper_web/live/event_live/manage.html.heex:267 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:334 +#: lib/claper_web/live/event_live/manage.html.heex:266 #, elixir-autogen, elixir-format msgid "New web content" msgstr "" @@ -1065,9 +983,9 @@ msgstr "" msgid "Title" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:248 -#: lib/claper_web/live/event_live/manage.html.heex:618 -#: lib/claper_web/live/stat_live/index.html.heex:257 +#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:761 +#: lib/claper_web/live/stat_live/index.html.heex:259 #, elixir-autogen, elixir-format msgid "Web content" msgstr "" @@ -1077,10 +995,8 @@ msgstr "" msgid "Invalid embed format (should start with )" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:781 -#: lib/claper_web/live/event_live/manage.html.heex:810 -#: lib/claper_web/live/event_live/manage.html.heex:956 -#: lib/claper_web/live/event_live/manage.html.heex:985 +#: 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 "" @@ -1091,25 +1007,23 @@ msgstr "" msgid "Pinned" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:714 +#: lib/claper_web/live/event_live/manage.html.heex:901 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:925 +#: lib/claper_web/live/event_live/manage.html.heex:1061 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1198 +#: lib/claper_web/live/event_live/manager_settings_component.ex:55 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:779 -#: lib/claper_web/live/event_live/manage.html.heex:808 -#: lib/claper_web/live/event_live/manage.html.heex:954 -#: lib/claper_web/live/event_live/manage.html.heex:983 +#: 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 "" @@ -1139,7 +1053,357 @@ msgstr "" msgid "You have been invited to manage an event" msgstr "" -#: lib/claper_web/live/event_live/form_component.ex:103 +#: lib/claper_web/live/event_live/form_component.ex:114 #, elixir-autogen, elixir-format msgid "Saved" msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Access" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:179 +#, elixir-autogen, elixir-format +msgid "All your events and files will be permanently deleted, are you sure?" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:157 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:149 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:171 +#, elixir-autogen, elixir-format +msgid "Be careful, these actions are irreversible" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:168 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:184 +#, elixir-autogen, elixir-format +msgid "Delete account" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:130 +#, elixir-autogen, elixir-format +msgid "Enable message reactions" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:423 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Terminate" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:244 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.ex:132 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:249 +#, elixir-autogen, elixir-format +msgid "Access code" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "" + +#: lib/claper_web/live/event_live/manage.html.heex:873 +#, elixir-autogen, elixir-format +msgid "Attendees interactions" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:76 +#: lib/claper_web/live/event_live/manage.html.heex:327 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:405 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:298 +#, elixir-autogen, elixir-format +msgid "Facilitators" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:77 +#: lib/claper_web/live/event_live/manage.html.heex:328 +#, elixir-autogen, elixir-format +msgid "Finish" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:875 +#, 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:875 +#, elixir-autogen, elixir-format +msgid "Identify users by their unique avatars." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:4 +#: lib/claper_web/live/event_live/index.html.heex:75 +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format +msgid "Next" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "" + +#: lib/claper_web/live/event_live/manage.html.heex:403 +#, elixir-autogen, elixir-format +msgid "Time to launch your presentation!" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1176 +#, 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:1176 +#, 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:118 +#, elixir-autogen, elixir-format +msgid "Your first steps with Claper" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, 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:136 +#, elixir-autogen, elixir-format +msgid "Create event" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:156 +#, elixir-autogen, elixir-format +msgid "Create your first event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:88 +#, 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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "If you have slides, you can navigate through the slides with ease using the arrow keys on your keyboard." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, 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:93 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:165 +#, elixir-autogen, elixir-format +msgid "Invited events" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:24 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:81 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:241 +#: lib/claper_web/live/event_live/index.html.heex:57 +#, elixir-autogen, elixir-format +msgid "Name of your event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, elixir-autogen, elixir-format +msgid "Note: Facilitators do not have the ability to delete your event." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Presentation file (optional)" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:11 +#, elixir-autogen, elixir-format +msgid "Presentation settings" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "" + +#: lib/claper_web/live/event_live/index.ex:73 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format +msgid "Return to your last event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, elixir-autogen, elixir-format +msgid "Select the start date for your event. Future dates are permissible." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:58 +#, elixir-autogen, elixir-format +msgid "Select your presentation (optional)" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:250 +#, 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:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "This section contains all your presentation slides (if you have upload one). You have the option to add interactions to each slide." +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:117 +#, 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:274 +#, elixir-autogen, elixir-format +msgid "When your event will start?" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:528 +#, elixir-autogen, elixir-format +msgid "Your slides and/or interactions" +msgstr "" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "" + +#: lib/claper_web/live/event_live/manage.ex:24 +#: lib/claper_web/live/event_live/presenter.ex:21 +#: lib/claper_web/live/event_live/show.ex:24 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:140 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:137 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.ex:114 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:893 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:980 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1022 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1001 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:126 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "" + +#: 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 "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:96 +#, elixir-autogen, elixir-format +msgid "Your personal informations to access your account" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 3e60550..02a924a 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -8,19 +8,18 @@ msgstr "" "Language: en\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: lib/claper_web/live/user_settings_live/show.ex:48 -#: lib/claper_web/live/user_settings_live/show.html.heex:5 -#: lib/claper_web/templates/layout/_user_menu.html.heex:2 +#: lib/claper_web/live/event_live/manage.html.heex:1174 +#: lib/claper_web/live/user_settings_live/show.ex:50 #, elixir-autogen, elixir-format msgid "Settings" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:650 +#: lib/claper_web/live/event_live/manage.ex:761 #: lib/claper_web/live/form_live/form_component.html.heex:37 #: lib/claper_web/live/user_settings_live/show.html.heex:34 -#: lib/claper_web/templates/user_registration/new.html.heex:34 -#: lib/claper_web/templates/user_reset_password/new.html.heex:33 -#: lib/claper_web/templates/user_session/new.html.heex:47 +#: 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:41 #, elixir-autogen, elixir-format msgid "Email" msgstr "" @@ -30,20 +29,20 @@ msgstr "" msgid "Join the Claper experience" msgstr "" -#: lib/claper_web/templates/user_registration/new.html.heex:24 +#: 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:24 +#: 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 "" -#: lib/claper_web/live/user_settings_live/show.html.heex:108 -#: lib/claper_web/live/user_settings_live/show.html.heex:121 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#: lib/claper_web/live/user_settings_live/show.html.heex:127 #, elixir-autogen, elixir-format msgid "Change" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:239 +#: lib/claper_web/live/event_live/event_form_component.html.heex:257 #, elixir-autogen, elixir-format msgid "Code" msgstr "" @@ -53,7 +52,7 @@ msgstr "" msgid "Email address" msgstr "" -#: lib/claper_web/templates/layout/_user_menu.html.heex:8 +#: lib/claper_web/templates/layout/_user_menu.html.heex:16 #, elixir-autogen, elixir-format msgid "Logout" msgstr "" @@ -73,42 +72,36 @@ msgstr "" msgid "We sent you an email at" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:96 -#, elixir-autogen, elixir-format -msgid "Your personal informations only visible by you" -msgstr "" - -#: lib/claper_web/live/event_live/show.html.heex:405 +#: lib/claper_web/live/event_live/show.html.heex:412 #, elixir-autogen, elixir-format msgid "days" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:411 +#: lib/claper_web/live/event_live/show.html.heex:418 #, elixir-autogen, elixir-format msgid "hours" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:417 +#: lib/claper_web/live/event_live/show.html.heex:424 #, elixir-autogen, elixir-format msgid "minutes" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:136 +#: lib/claper_web/live/event_live/show.html.heex:143 #, elixir-autogen, elixir-format msgid "Be the first to react !" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:98 -#: lib/claper_web/live/event_live/join.ex:42 -#: lib/claper_web/live/event_live/join.html.heex:106 -#: lib/claper_web/live/event_live/show.html.heex:257 +#: 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/show.html.heex:264 #, elixir-autogen, elixir-format msgid "Join" msgstr "" -#: lib/claper_web/live/event_live/index.ex:82 -#: lib/claper_web/live/event_live/join.html.heex:26 -#: lib/claper_web/live/event_live/join.html.heex:47 +#: lib/claper_web/live/event_live/index.ex:156 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "" @@ -119,38 +112,22 @@ msgstr "" msgid "Host" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:423 +#: lib/claper_web/live/event_live/show.html.heex:430 #, elixir-autogen, elixir-format msgid "seconds" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:61 -#, elixir-autogen, elixir-format -msgid "Create your first presentation" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:50 -#: lib/claper_web/live/event_live/manage.html.heex:81 -#, elixir-autogen, elixir-format -msgid "Finish on" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:30 +#: lib/claper_web/live/event_live/event_card_component.ex:34 #, elixir-autogen, elixir-format msgid "Finished" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:62 +#: lib/claper_web/live/event_live/event_card_component.ex:64 #, elixir-autogen, elixir-format msgid "Finished on" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:20 -#, elixir-autogen, elixir-format -msgid "In progress" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:25 +#: lib/claper_web/live/event_live/event_card_component.ex:29 #, elixir-autogen, elixir-format msgid "Incoming" msgstr "" @@ -160,79 +137,53 @@ msgstr "" msgid "Leave" msgstr "" -#: lib/claper_web/live/event_live/index.html.heex:16 -#, elixir-autogen, elixir-format -msgid "My presentations" -msgstr "" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 -#, elixir-autogen, elixir-format -msgid "Name of your presentation" -msgstr "" - #: lib/claper_web/live/event_live/presenter.html.heex:26 -#: lib/claper_web/live/event_live/show.html.heex:432 +#: lib/claper_web/live/event_live/show.html.heex:439 #, elixir-autogen, elixir-format msgid "Scan to interact in real-time" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:56 +#: lib/claper_web/live/event_live/event_card_component.ex:60 #, elixir-autogen, elixir-format msgid "Starting on" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:206 +#: lib/claper_web/live/event_live/event_form_component.ex:253 #, elixir-autogen, elixir-format msgid "Updated successfully" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:249 -#, elixir-autogen, elixir-format -msgid "When your presentation will be available ?" -msgstr "" - -#: lib/claper_web/live/event_live/join.html.heex:72 -#, elixir-autogen, elixir-format -msgid "Return to your last presentation" -msgstr "" - #: lib/claper_web/templates/user_session/new.html.heex:22 #, elixir-autogen, elixir-format msgid "It's time to empower your presentations." msgstr "" -#: lib/claper_web/templates/error/404.html.heex:44 -#: lib/claper_web/templates/error/500.html.heex:45 -#: lib/claper_web/templates/user_registration/confirm.html.heex:28 +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 #, elixir-autogen, elixir-format msgid "Return to home" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:186 +#: lib/claper_web/live/event_live/event_form_component.ex:197 +#: lib/claper_web/live/event_live/event_form_component.ex:233 #, elixir-autogen, elixir-format msgid "Created successfully" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:24 -#: lib/claper_web/live/event_live/presenter.ex:21 -#: lib/claper_web/live/event_live/show.ex:24 -#, elixir-autogen, elixir-format -msgid "Presentation doesn't exist" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:109 -#: lib/claper_web/live/event_live/event_card_component.ex:129 +#: lib/claper_web/live/event_live/event_card_component.ex:186 +#: lib/claper_web/live/event_live/event_card_component.ex:207 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:65 +#: lib/claper_web/live/event_live/index.ex:139 #, elixir-autogen, elixir-format msgid "Edit" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:51 -#: lib/claper_web/live/event_live/event_form_component.html.heex:18 #: lib/claper_web/live/event_live/event_form_component.html.heex:25 -#: lib/claper_web/live/event_live/index.ex:71 -#: lib/claper_web/live/event_live/index.html.heex:40 +#: lib/claper_web/live/event_live/event_form_component.html.heex:32 +#: lib/claper_web/live/event_live/index.ex:146 +#: lib/claper_web/live/event_live/index.html.heex:64 #: lib/claper_web/live/form_live/form_component.html.heex:98 #: lib/claper_web/live/poll_live/form_component.html.heex:94 #, elixir-autogen, elixir-format @@ -240,11 +191,10 @@ msgid "Create" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:56 -#: lib/claper_web/live/event_live/event_card_component.ex:171 -#: lib/claper_web/live/event_live/event_form_component.html.heex:30 -#: lib/claper_web/live/event_live/manage.html.heex:835 -#: lib/claper_web/live/event_live/manage.html.heex:1010 -#: lib/claper_web/live/event_live/manage.html.heex:1125 +#: lib/claper_web/live/event_live/event_card_component.ex:249 +#: lib/claper_web/live/event_live/event_form_component.html.heex:37 +#: lib/claper_web/live/event_live/manage.html.heex:1122 +#: 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 @@ -254,8 +204,8 @@ msgid "Delete" msgstr "" #: lib/claper_web/live/embed_live/form_component.html.heex:52 -#: lib/claper_web/live/event_live/event_form_component.html.heex:17 #: lib/claper_web/live/event_live/event_form_component.html.heex:24 +#: lib/claper_web/live/event_live/event_form_component.html.heex:31 #: lib/claper_web/live/form_live/form_component.html.heex:99 #: lib/claper_web/live/poll_live/form_component.html.heex:95 #: lib/claper_web/live/user_settings_live/show.html.heex:38 @@ -264,17 +214,17 @@ msgstr "" msgid "Save" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:69 +#: lib/claper_web/live/user_settings_live/show.ex:71 #, elixir-autogen, elixir-format msgid "A link to confirm your email change has been sent to the new address." msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:33 +#: lib/claper_web/live/user_settings_live/show.ex:35 #, elixir-autogen, elixir-format msgid "Change the email address you want associated with your account." msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:30 +#: lib/claper_web/live/user_settings_live/show.ex:32 #, elixir-autogen, elixir-format msgid "Update your email" msgstr "" @@ -316,73 +266,72 @@ msgstr "" msgid "You can log into your account by clicking here." msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:34 +#: lib/claper_web/live/event_live/event_form_component.html.heex:41 #: 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 "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:149 +#: lib/claper_web/live/event_live/event_form_component.html.heex:162 #, elixir-autogen, elixir-format msgid "Presentation attached" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:109 +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 #, elixir-autogen, elixir-format msgid "Presentation uploaded" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:120 -#: lib/claper_web/live/event_live/event_form_component.html.heex:198 -#: lib/claper_web/live/event_live/event_form_component.html.heex:323 -#: lib/claper_web/live/event_live/event_form_component.html.heex:346 +#: lib/claper_web/live/event_live/event_form_component.html.heex:133 +#: lib/claper_web/live/event_live/event_form_component.html.heex:211 +#: lib/claper_web/live/event_live/event_form_component.html.heex:352 +#: lib/claper_web/live/event_live/event_form_component.html.heex:375 #, elixir-autogen, elixir-format msgid "Remove" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:45 -#: lib/claper_web/live/event_live/event_form_component.html.heex:130 +#: lib/claper_web/live/event_live/event_form_component.html.heex:143 #, elixir-autogen, elixir-format msgid "Select your presentation" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:72 +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Upload a file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:76 +#: lib/claper_web/live/event_live/event_form_component.html.heex:89 #, elixir-autogen, elixir-format msgid "or drag and drop" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:257 +#: lib/claper_web/live/event_live/event_form_component.ex:304 #, elixir-autogen, elixir-format msgid "You have selected an incorrect file type" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:256 +#: lib/claper_web/live/event_live/event_form_component.ex:303 #, elixir-autogen, elixir-format msgid "Your file is too large" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:159 +#: lib/claper_web/live/event_live/event_form_component.html.heex:172 #, elixir-autogen, elixir-format msgid "Change file" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:185 +#: lib/claper_web/live/event_live/event_form_component.html.heex:198 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:293 +#: lib/claper_web/live/event_live/manage.html.heex:225 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:292 +#: lib/claper_web/live/event_live/manage.html.heex:224 #, elixir-autogen, elixir-format msgid "New poll" msgstr "" @@ -392,18 +341,18 @@ msgstr "" msgid "Title of your poll" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.ex:258 +#: lib/claper_web/live/event_live/event_form_component.ex:305 #, elixir-autogen, elixir-format msgid "Upload failed" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:112 #, elixir-autogen, elixir-format msgid "Add poll to know opinion of your public." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:177 -#: lib/claper_web/live/event_live/manage.html.heex:461 +#: lib/claper_web/live/event_live/manage.html.heex:109 +#: lib/claper_web/live/event_live/manage.html.heex:604 #, elixir-autogen, elixir-format msgid "Poll" msgstr "" @@ -425,51 +374,36 @@ msgstr "" msgid "See current poll" msgstr "" -#: lib/claper_web/live/event_live/poll_component.ex:123 -#: lib/claper_web/live/event_live/poll_component.ex:131 +#: 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 "" -#: lib/claper_web/live/event_live/index.html.heex:70 -#, elixir-autogen, elixir-format -msgid "Invited presentations" -msgstr "" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:313 -#: lib/claper_web/live/event_live/event_form_component.html.heex:330 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#: lib/claper_web/live/event_live/event_form_component.html.heex:359 #, elixir-autogen, elixir-format msgid "User email address" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:90 -#, elixir-autogen, elixir-format -msgid "Present/Customize" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:479 -#: lib/claper_web/live/event_live/manage.html.heex:561 -#: lib/claper_web/live/event_live/manage.html.heex:635 +#: lib/claper_web/live/event_live/manage.html.heex:622 +#: lib/claper_web/live/event_live/manage.html.heex:704 +#: lib/claper_web/live/event_live/manage.html.heex:778 #, elixir-autogen, elixir-format msgid "Active" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:164 +#: lib/claper_web/live/event_live/event_form_component.html.heex:177 #, 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:752 +#: lib/claper_web/live/event_live/manage.html.heex:939 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1170 -#, elixir-autogen, elixir-format -msgid "On screen settings" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:139 +#: lib/claper_web/live/event_live/event_card_component.ex:218 #, elixir-autogen, elixir-format msgid "Processing your file..." msgstr "" @@ -479,50 +413,46 @@ msgstr "" msgid "This will delete all responses associated and the poll itself, are you sure?" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:113 -#, elixir-autogen, elixir-format -msgid "Start" -msgstr "" - -#: lib/claper_web/live/event_live/manage.html.heex:89 +#: lib/claper_web/live/event_live/manage.html.heex:395 #, elixir-autogen, elixir-format msgid "Press F in the presentation window to enable fullscreen" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:316 +#: lib/claper_web/live/event_live/show.html.heex:323 #, elixir-autogen, elixir-format msgid "Ask, comment..." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:710 +#: lib/claper_web/live/event_live/manage.html.heex:885 #: lib/claper_web/live/stat_live/index.html.heex:71 +#: lib/claper_web/live/stat_live/index.html.heex:271 #, elixir-autogen, elixir-format msgid "Messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:487 -#: lib/claper_web/live/event_live/manage.html.heex:569 -#: lib/claper_web/live/event_live/manage.html.heex:643 +#: lib/claper_web/live/event_live/manage.html.heex:630 +#: lib/claper_web/live/event_live/manage.html.heex:712 +#: lib/claper_web/live/event_live/manage.html.heex:786 #, elixir-autogen, elixir-format msgid "Set active" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:325 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "" -#: lib/claper_web/templates/error/404.html.heex:40 +#: lib/claper_web/templates/error/404.html.heex:31 #, elixir-autogen, elixir-format msgid "Oops, page doesn't exist." msgstr "" -#: lib/claper_web/templates/error/500.html.heex:40 +#: 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 "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:275 +#: lib/claper_web/live/event_live/event_form_component.html.heex:304 #, elixir-autogen, elixir-format msgid "Facilitators can present and manage interactions" msgstr "" @@ -539,30 +469,26 @@ msgstr "" msgid "You can change your email by visiting the URL below" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:678 +#: lib/claper_web/live/event_live/manage.html.heex:830 #, elixir-autogen, elixir-format msgid "Add interaction" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:797 -#: lib/claper_web/live/event_live/manage.html.heex:826 -#: lib/claper_web/live/event_live/manage.html.heex:972 -#: lib/claper_web/live/event_live/manage.html.heex:1001 +#: 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 "" #: lib/claper_web/live/event_live/show.ex:50 -#: lib/claper_web/live/event_live/show.ex:198 -#: lib/claper_web/live/event_live/show.ex:213 +#: 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 "" -#: lib/claper_web/live/event_live/manage.html.heex:791 -#: lib/claper_web/live/event_live/manage.html.heex:820 -#: lib/claper_web/live/event_live/manage.html.heex:966 -#: lib/claper_web/live/event_live/manage.html.heex:995 +#: 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 "" @@ -656,17 +582,12 @@ msgstr "" msgid "Interactions history" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:271 +#: lib/claper_web/live/stat_live/index.html.heex:275 #, elixir-autogen, elixir-format msgid "No messages has been sent" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:166 -#, elixir-autogen, elixir-format -msgid "Report" -msgstr "" - -#: lib/claper_web/live/event_live/event_card_component.ex:177 +#: lib/claper_web/live/event_live/event_card_component.ex:255 #, elixir-autogen, elixir-format msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" msgstr "" @@ -688,25 +609,20 @@ msgstr "" msgid "Engagement rate" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:119 +#: lib/claper_web/live/event_live/event_card_component.ex:197 #, elixir-autogen, elixir-format msgid "Error when processing the file" msgstr "" -#: lib/claper_web/live/event_live/event_card_component.ex:71 -#, elixir-autogen, elixir-format -msgid "Error when processing the new file" -msgstr "" - -#: lib/claper_web/live/event_live/join.html.heex:23 -#: lib/claper_web/live/event_live/join.html.heex:44 +#: 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 "" -#: lib/claper_web/live/event_live/join.html.heex:32 -#: lib/claper_web/live/event_live/join.html.heex:53 -#: lib/claper_web/templates/user_session/new.html.heex:66 +#: 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:60 #, elixir-autogen, elixir-format msgid "Login" msgstr "" @@ -716,36 +632,36 @@ msgstr "" msgid "Connect to your account" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:441 +#: lib/claper_web/live/event_live/show.html.heex:448 #, elixir-autogen, elixir-format msgid "Or use the code:" msgstr "" -#: lib/claper_web/templates/user_registration/new.html.heex:51 -#: lib/claper_web/templates/user_session/new.html.heex:77 +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:71 #, elixir-autogen, elixir-format msgid "Create account" msgstr "" -#: lib/claper_web/live/user_settings_live/show.html.heex:116 -#: lib/claper_web/templates/user_registration/new.html.heex:42 +#: lib/claper_web/live/user_settings_live/show.html.heex:118 +#: 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:57 +#: lib/claper_web/templates/user_session/new.html.heex:51 #, elixir-autogen, elixir-format msgid "Password" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:45 +#: lib/claper_web/templates/user_session/new.html.heex:39 #, elixir-autogen, elixir-format msgid "Your email address" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:55 +#: lib/claper_web/templates/user_session/new.html.heex:49 #, elixir-autogen, elixir-format msgid "Your password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:42 +#: lib/claper_web/live/user_settings_live/show.ex:44 #, elixir-autogen, elixir-format msgid "Change the password used to access your account." msgstr "" @@ -760,12 +676,12 @@ msgstr "" msgid "New password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:39 +#: lib/claper_web/live/user_settings_live/show.ex:41 #, elixir-autogen, elixir-format msgid "Update your password" msgstr "" -#: lib/claper_web/live/user_settings_live/show.ex:91 +#: lib/claper_web/live/user_settings_live/show.ex:93 #, elixir-autogen, elixir-format msgid "Your password has been updated." msgstr "" @@ -777,7 +693,7 @@ msgid_plural "Field %{count}" msgstr[0] "" msgstr[1] "" -#: lib/claper_web/live/event_live/manage.html.heex:219 +#: lib/claper_web/live/event_live/manage.html.heex:151 #, elixir-autogen, elixir-format msgid "Add form to collect data from your public." msgstr "" @@ -787,39 +703,40 @@ msgstr "" msgid "Current form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:314 +#: lib/claper_web/live/event_live/manage.html.heex:246 #, elixir-autogen, elixir-format msgid "Edit form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:216 -#: lib/claper_web/live/event_live/manage.html.heex:543 -#: lib/claper_web/live/stat_live/index.html.heex:215 +#: lib/claper_web/live/event_live/manage.html.heex:148 +#: lib/claper_web/live/event_live/manage.html.heex:686 +#: lib/claper_web/live/event_live/manage.html.heex:1134 +#: lib/claper_web/live/stat_live/index.html.heex:217 #, elixir-autogen, elixir-format msgid "Form" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:722 +#: lib/claper_web/live/event_live/manage.html.heex:909 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1104 +#: lib/claper_web/live/event_live/manage.html.heex:1107 #, elixir-autogen, elixir-format msgid "Form submissions from attendees will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.ex:649 +#: lib/claper_web/live/event_live/manage.ex:760 #, elixir-autogen, elixir-format msgid "Name" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:313 +#: lib/claper_web/live/event_live/manage.html.heex:245 #, elixir-autogen, elixir-format msgid "New form" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:225 +#: lib/claper_web/live/stat_live/index.html.heex:227 #, elixir-autogen, elixir-format msgid "No form submission has been sent" msgstr "" @@ -839,7 +756,7 @@ msgstr "" msgid "Text" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1130 +#: lib/claper_web/live/event_live/manage.html.heex:1127 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "" @@ -859,7 +776,7 @@ msgstr "" msgid "Type" msgstr "" -#: lib/claper_web/live/stat_live/index.html.heex:220 +#: lib/claper_web/live/stat_live/index.html.heex:222 #, elixir-autogen, elixir-format msgid "Export all submissions" msgstr "" @@ -879,80 +796,81 @@ msgstr "" msgid "Multiple answers" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:281 +#: lib/claper_web/live/event_live/manage.html.heex:213 #, elixir-autogen, elixir-format msgid "Import all interactions from another presentation" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:226 +#: lib/claper_web/live/event_live/manage.ex:273 #, elixir-autogen, elixir-format msgid "Interactions import failed" msgstr "" -#: lib/claper_web/live/event_live/manage.ex:219 +#: lib/claper_web/live/event_live/manage.ex:266 #, elixir-autogen, elixir-format msgid "Interactions imported successfully" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:354 +#: lib/claper_web/live/event_live/manage.html.heex:286 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "" -#: lib/claper_web/live/event_live/event_form_component.html.heex:79 +#: lib/claper_web/live/event_live/event_form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1215 +#: lib/claper_web/live/event_live/manager_settings_component.ex:86 #, elixir-autogen, elixir-format msgid "Attendees settings" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1224 +#: lib/claper_web/live/event_live/manager_settings_component.ex:96 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1179 +#: lib/claper_web/live/event_live/manager_settings_component.ex:21 #, elixir-autogen, elixir-format msgid "Show instructions" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1188 +#: lib/claper_web/live/event_live/manager_settings_component.ex:38 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1209 +#: lib/claper_web/live/event_live/manager_settings_component.ex:73 +#: lib/claper_web/live/event_live/manager_settings_component.ex:148 #, elixir-autogen, elixir-format msgid "Show poll results" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:336 +#: lib/claper_web/live/event_live/show.html.heex:343 #, elixir-autogen, elixir-format msgid "Messages deactivated" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:179 -#: lib/claper_web/live/event_live/show.html.heex:200 -#: lib/claper_web/live/event_live/show.html.heex:300 +#: lib/claper_web/live/event_live/show.html.heex:186 +#: lib/claper_web/live/event_live/show.html.heex:207 +#: lib/claper_web/live/event_live/show.html.heex:307 #, elixir-autogen, elixir-format msgid "Anonymous" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:226 +#: lib/claper_web/live/event_live/show.html.heex:233 #, elixir-autogen, elixir-format msgid "Close" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1234 +#: lib/claper_web/live/event_live/manager_settings_component.ex:113 #, elixir-autogen, elixir-format msgid "Enable anonymous messages" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:207 -#: lib/claper_web/live/event_live/show.html.heex:252 +#: lib/claper_web/live/event_live/show.html.heex:214 +#: lib/claper_web/live/event_live/show.html.heex:259 #, elixir-autogen, elixir-format msgid "Enter your name" msgstr "" @@ -962,12 +880,12 @@ msgstr "" msgid "Or go to %{url} and use the code:" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:220 +#: lib/claper_web/live/event_live/show.html.heex:227 #, elixir-autogen, elixir-format msgid "Use your name" msgstr "" -#: lib/claper_web/live/event_live/show.html.heex:200 +#: lib/claper_web/live/event_live/show.html.heex:207 #, elixir-autogen, elixir-format msgid "disabled" msgstr "" @@ -977,7 +895,7 @@ msgstr "" msgid "Account creation is disabled" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:250 +#: lib/claper_web/live/event_live/manage.html.heex:182 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "" @@ -987,7 +905,7 @@ msgstr "" msgid "Confirm new password" msgstr "" -#: lib/claper_web/templates/user_session/new.html.heex:72 +#: lib/claper_web/templates/user_session/new.html.heex:66 #, elixir-autogen, elixir-format msgid "Forgot your password?" msgstr "" @@ -1018,7 +936,7 @@ msgstr "" msgid "Reset your password" msgstr "" -#: lib/claper_web/templates/user_reset_password/new.html.heex:41 +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 #, elixir-autogen, elixir-format msgid "Send link to reset password" msgstr "" @@ -1033,12 +951,12 @@ msgstr "" msgid "Current web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:335 +#: lib/claper_web/live/event_live/manage.html.heex:267 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:334 +#: lib/claper_web/live/event_live/manage.html.heex:266 #, elixir-autogen, elixir-format msgid "New web content" msgstr "" @@ -1063,9 +981,9 @@ msgstr "" msgid "Title" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:248 -#: lib/claper_web/live/event_live/manage.html.heex:618 -#: lib/claper_web/live/stat_live/index.html.heex:257 +#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:761 +#: lib/claper_web/live/stat_live/index.html.heex:259 #, elixir-autogen, elixir-format msgid "Web content" msgstr "" @@ -1075,10 +993,8 @@ msgstr "" msgid "Invalid embed format (should start with )" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:781 -#: lib/claper_web/live/event_live/manage.html.heex:810 -#: lib/claper_web/live/event_live/manage.html.heex:956 -#: lib/claper_web/live/event_live/manage.html.heex:985 +#: 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 "" @@ -1089,25 +1005,23 @@ msgstr "" msgid "Pinned" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:714 +#: lib/claper_web/live/event_live/manage.html.heex:901 #, elixir-autogen, elixir-format msgid "Pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:925 +#: lib/claper_web/live/event_live/manage.html.heex:1061 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:1198 +#: lib/claper_web/live/event_live/manager_settings_component.ex:55 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "" -#: lib/claper_web/live/event_live/manage.html.heex:779 -#: lib/claper_web/live/event_live/manage.html.heex:808 -#: lib/claper_web/live/event_live/manage.html.heex:954 -#: lib/claper_web/live/event_live/manage.html.heex:983 +#: 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 "" @@ -1137,7 +1051,357 @@ msgstr "" msgid "You have been invited to manage an event" msgstr "" -#: lib/claper_web/live/event_live/form_component.ex:103 +#: lib/claper_web/live/event_live/form_component.ex:114 #, elixir-autogen, elixir-format, fuzzy msgid "Saved" msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Access" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:179 +#, elixir-autogen, elixir-format +msgid "All your events and files will be permanently deleted, are you sure?" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:157 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:149 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:171 +#, elixir-autogen, elixir-format +msgid "Be careful, these actions are irreversible" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:168 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:184 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete account" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:130 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable message reactions" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:423 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Terminate" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:244 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.ex:132 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:249 +#, elixir-autogen, elixir-format, fuzzy +msgid "Access code" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "" + +#: lib/claper_web/live/event_live/manage.html.heex:873 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees interactions" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:76 +#: lib/claper_web/live/event_live/manage.html.heex:327 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:405 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:298 +#, elixir-autogen, elixir-format, fuzzy +msgid "Facilitators" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:77 +#: lib/claper_web/live/event_live/manage.html.heex:328 +#, elixir-autogen, elixir-format, fuzzy +msgid "Finish" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:875 +#, 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:875 +#, elixir-autogen, elixir-format +msgid "Identify users by their unique avatars." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:4 +#: lib/claper_web/live/event_live/index.html.heex:75 +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "Next" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "" + +#: lib/claper_web/live/event_live/manage.html.heex:403 +#, elixir-autogen, elixir-format, fuzzy +msgid "Time to launch your presentation!" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1176 +#, 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:1176 +#, 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:118 +#, elixir-autogen, elixir-format +msgid "Your first steps with Claper" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, 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:136 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create event" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:156 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create your first event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:88 +#, 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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "If you have slides, you can navigate through the slides with ease using the arrow keys on your keyboard." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, 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:93 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:165 +#, elixir-autogen, elixir-format, fuzzy +msgid "Invited events" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:24 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:81 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:241 +#: lib/claper_web/live/event_live/index.html.heex:57 +#, elixir-autogen, elixir-format, fuzzy +msgid "Name of your event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, elixir-autogen, elixir-format, fuzzy +msgid "Note: Facilitators do not have the ability to delete your event." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation file (optional)" +msgstr "" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:11 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation settings" +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "" + +#: lib/claper_web/live/event_live/index.ex:73 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Return to your last event" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select the start date for your event. Future dates are permissible." +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:58 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select your presentation (optional)" +msgstr "" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:250 +#, 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:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:529 +#, elixir-autogen, elixir-format, fuzzy +msgid "This section contains all your presentation slides (if you have upload one). You have the option to add interactions to each slide." +msgstr "" + +#: lib/claper_web/live/event_live/index.html.heex:117 +#, 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:274 +#, elixir-autogen, elixir-format, fuzzy +msgid "When your event will start?" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:528 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your slides and/or interactions" +msgstr "" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "" + +#: lib/claper_web/live/event_live/manage.ex:24 +#: lib/claper_web/live/event_live/presenter.ex:21 +#: lib/claper_web/live/event_live/show.ex:24 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:140 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:137 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "" + +#: lib/claper_web/live/user_settings_live/show.ex:114 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "" + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:893 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:980 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1022 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "" + +#: lib/claper_web/live/event_live/manage.html.heex:1001 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "" + +#: lib/claper_web/live/event_live/event_card_component.ex:126 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "" + +#: 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 "" + +#: lib/claper_web/live/user_settings_live/show.html.heex:96 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your personal informations to access your account" +msgstr "" diff --git a/priv/gettext/es/LC_MESSAGES/default.po b/priv/gettext/es/LC_MESSAGES/default.po new file mode 100644 index 0000000..32966f4 --- /dev/null +++ b/priv/gettext/es/LC_MESSAGES/default.po @@ -0,0 +1,1407 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Vim text editor\n" +"Project-Id-Version: Claper\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/claper_web/live/event_live/manage.html.heex:1174 +#: lib/claper_web/live/user_settings_live/show.ex:50 +#, elixir-autogen, elixir-format +msgid "Settings" +msgstr "Configuración" + +#: lib/claper_web/live/event_live/manage.ex:761 +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#: 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:41 +#, elixir-autogen, elixir-format +msgid "Email" +msgstr "Email" + +#: lib/claper_web/templates/user_registration/new.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Join the Claper experience" +msgstr "Únete a la experiencia Claper" + +#: 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 "Uy, comprueba que todos los campos estén correctamente rellenados." + +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#: lib/claper_web/live/user_settings_live/show.html.heex:127 +#, elixir-autogen, elixir-format +msgid "Change" +msgstr "Cambiar" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:257 +#, elixir-autogen, elixir-format +msgid "Code" +msgstr "Código" + +#: lib/claper_web/live/user_settings_live/show.html.heex:103 +#, elixir-autogen, elixir-format +msgid "Email address" +msgstr "Dirección email" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:16 +#, elixir-autogen, elixir-format +msgid "Logout" +msgstr "Salir" + +#: lib/claper_web/live/user_settings_live/show.html.heex:93 +#, elixir-autogen, elixir-format +msgid "Personal informations" +msgstr "Información personal" + +#: 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 "Ya te hemos enviado un email para entrar, vuelve a intentarlo dentro de 5 minutos." + +#: lib/claper_web/templates/user_registration/confirm.html.heex:16 +#, elixir-autogen, elixir-format +msgid "We sent you an email at" +msgstr "Te hemos enviado un email a las " + +#: lib/claper_web/live/event_live/show.html.heex:412 +#, elixir-autogen, elixir-format +msgid "days" +msgstr "días" + +#: lib/claper_web/live/event_live/show.html.heex:418 +#, elixir-autogen, elixir-format +msgid "hours" +msgstr "horas" + +#: lib/claper_web/live/event_live/show.html.heex:424 +#, elixir-autogen, elixir-format +msgid "minutes" +msgstr "minutos" + +#: lib/claper_web/live/event_live/show.html.heex:143 +#, elixir-autogen, elixir-format +msgid "Be the first to react !" +msgstr "¡Sé el primero en reaccionar!" + +#: 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/show.html.heex:264 +#, elixir-autogen, elixir-format +msgid "Join" +msgstr "Unirse" + +#: lib/claper_web/live/event_live/index.ex:156 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 +#, elixir-autogen, elixir-format +msgid "Dashboard" +msgstr "Panel" + +#: 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 "Anfitrión" + +#: lib/claper_web/live/event_live/show.html.heex:430 +#, elixir-autogen, elixir-format +msgid "seconds" +msgstr "segundos" + +#: lib/claper_web/live/event_live/event_card_component.ex:34 +#, elixir-autogen, elixir-format +msgid "Finished" +msgstr "Finalizado" + +#: lib/claper_web/live/event_live/event_card_component.ex:64 +#, elixir-autogen, elixir-format +msgid "Finished on" +msgstr "Finaliza el" + +#: lib/claper_web/live/event_live/event_card_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Incoming" +msgstr "Entrada" + +#: lib/claper_web/live/event_live/show.html.heex:26 +#, elixir-autogen, elixir-format +msgid "Leave" +msgstr "Salir" + +#: lib/claper_web/live/event_live/presenter.html.heex:26 +#: lib/claper_web/live/event_live/show.html.heex:439 +#, elixir-autogen, elixir-format +msgid "Scan to interact in real-time" +msgstr "Escanea para interactuar" + +#: lib/claper_web/live/event_live/event_card_component.ex:60 +#, elixir-autogen, elixir-format +msgid "Starting on" +msgstr "Empieza" + +#: lib/claper_web/live/event_live/event_form_component.ex:253 +#, elixir-autogen, elixir-format +msgid "Updated successfully" +msgstr "Actualizado exitosamente" + +#: lib/claper_web/templates/user_session/new.html.heex:22 +#, elixir-autogen, elixir-format +msgid "It's time to empower your presentations." +msgstr "Es el momento para potenciar tus presentaciones" + +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 +#, elixir-autogen, elixir-format +msgid "Return to home" +msgstr "Volver a principal" + +#: lib/claper_web/live/event_live/event_form_component.ex:197 +#: lib/claper_web/live/event_live/event_form_component.ex:233 +#, elixir-autogen, elixir-format +msgid "Created successfully" +msgstr "Creado exitosamente" + +#: lib/claper_web/live/event_live/event_card_component.ex:186 +#: lib/claper_web/live/event_live/event_card_component.ex:207 +#: lib/claper_web/live/event_live/form_component.ex:97 +#: lib/claper_web/live/event_live/index.ex:139 +#, elixir-autogen, elixir-format +msgid "Edit" +msgstr "Editar" + +#: lib/claper_web/live/embed_live/form_component.html.heex:51 +#: lib/claper_web/live/event_live/event_form_component.html.heex:25 +#: lib/claper_web/live/event_live/event_form_component.html.heex:32 +#: lib/claper_web/live/event_live/index.ex:146 +#: lib/claper_web/live/event_live/index.html.heex:64 +#: lib/claper_web/live/form_live/form_component.html.heex:98 +#: lib/claper_web/live/poll_live/form_component.html.heex:94 +#, elixir-autogen, elixir-format +msgid "Create" +msgstr "Crear" + +#: lib/claper_web/live/embed_live/form_component.html.heex:56 +#: lib/claper_web/live/event_live/event_card_component.ex:249 +#: lib/claper_web/live/event_live/event_form_component.html.heex:37 +#: lib/claper_web/live/event_live/manage.html.heex:1122 +#: 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:99 +#, elixir-autogen, elixir-format +msgid "Delete" +msgstr "Borrar" + +#: lib/claper_web/live/embed_live/form_component.html.heex:52 +#: lib/claper_web/live/event_live/event_form_component.html.heex:24 +#: lib/claper_web/live/event_live/event_form_component.html.heex:31 +#: lib/claper_web/live/form_live/form_component.html.heex:99 +#: lib/claper_web/live/poll_live/form_component.html.heex:95 +#: lib/claper_web/live/user_settings_live/show.html.heex:38 +#: lib/claper_web/live/user_settings_live/show.html.heex:80 +#, elixir-autogen, elixir-format +msgid "Save" +msgstr "Guardar" + +#: lib/claper_web/live/user_settings_live/show.ex:71 +#, elixir-autogen, elixir-format +msgid "A link to confirm your email change has been sent to the new address." +msgstr "Se ha enviado un enlace a tu buzón para confirmar el cambio de email." + +#: lib/claper_web/live/user_settings_live/show.ex:35 +#, elixir-autogen, elixir-format +msgid "Change the email address you want associated with your account." +msgstr "Cambiar la dirección email asociada a tu cuenta." + +#: lib/claper_web/live/user_settings_live/show.ex:32 +#, elixir-autogen, elixir-format +msgid "Update your email" +msgstr "Actualizar tu email" + +#: 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 "Conectar a Claper" + +#: lib/claper_web/templates/user_notifier/magic.html.heex:29 +#, elixir-autogen, elixir-format +msgid "ACCESS TO MY ACCOUNT" +msgstr "ACCESO A MI CUENTA" + +#: lib/claper_web/notifiers/user_notifier.ex:34 +#, elixir-autogen, elixir-format +msgid "Update email instructions" +msgstr "Instrucciones de actualización de correo" + +#: lib/claper_web/templates/user_notifier/change.html.heex:29 +#, elixir-autogen, elixir-format +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/magic.html.heex:32 +#, elixir-autogen, elixir-format +msgid "If you didn't create an account with us, please ignore this." +msgstr "Si no has creado una cuenta con nosotros, por favor ignora ésto." + +#: 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 "Puedes entrar en tu cuenta haciendo clic aquí." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:41 +#: 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 "¿Estás seguro/a?" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:162 +#, elixir-autogen, elixir-format +msgid "Presentation attached" +msgstr "Presentación adjuntada" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 +#, elixir-autogen, elixir-format +msgid "Presentation uploaded" +msgstr "Presentación subida" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:133 +#: lib/claper_web/live/event_live/event_form_component.html.heex:211 +#: lib/claper_web/live/event_live/event_form_component.html.heex:352 +#: lib/claper_web/live/event_live/event_form_component.html.heex:375 +#, elixir-autogen, elixir-format +msgid "Remove" +msgstr "Borrar" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:143 +#, elixir-autogen, elixir-format +msgid "Select your presentation" +msgstr "Selecciona tu presentación" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 +#, elixir-autogen, elixir-format +msgid "Upload a file" +msgstr "Subir un fichero" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:89 +#, elixir-autogen, elixir-format +msgid "or drag and drop" +msgstr "o arrastra" + +#: lib/claper_web/live/event_live/event_form_component.ex:304 +#, elixir-autogen, elixir-format +msgid "You have selected an incorrect file type" +msgstr "Has seleccionado un tipo de fichero incorrecto" + +#: lib/claper_web/live/event_live/event_form_component.ex:303 +#, elixir-autogen, elixir-format +msgid "Your file is too large" +msgstr "Tu fichero es demasiado grande" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:172 +#, elixir-autogen, elixir-format +msgid "Change file" +msgstr "Cambiar fichero" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:198 +#, elixir-autogen, elixir-format +msgid "Presentation replaced" +msgstr "Presentación sustituida" + +#: lib/claper_web/live/event_live/manage.html.heex:225 +#, elixir-autogen, elixir-format +msgid "Edit poll" +msgstr "Editar votación" + +#: lib/claper_web/live/event_live/manage.html.heex:224 +#, elixir-autogen, elixir-format +msgid "New poll" +msgstr "Nueva votación" + +#: lib/claper_web/live/poll_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your poll" +msgstr "Título de tu votación" + +#: lib/claper_web/live/event_live/event_form_component.ex:305 +#, elixir-autogen, elixir-format +msgid "Upload failed" +msgstr "Subida fallida" + +#: lib/claper_web/live/event_live/manage.html.heex:112 +#, 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:109 +#: lib/claper_web/live/event_live/manage.html.heex:604 +#, elixir-autogen, elixir-format +msgid "Poll" +msgstr "Votación" + +#: lib/claper_web/live/poll_live/form_component.html.heex:35 +#, elixir-format, ex-autogen +msgid "Choice %{count}" +msgid_plural "Choice %{count}" +msgstr[0] "Opción %{count}" +msgstr[1] "Opciones %{count}" + +#: lib/claper_web/live/event_live/poll_component.ex:47 +#, elixir-autogen, elixir-format +msgid "Current poll" +msgstr "Votación actual" + +#: lib/claper_web/live/event_live/poll_component.ex:28 +#, elixir-autogen, elixir-format +msgid "See current poll" +msgstr "Ver la votación actual" + +#: 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 "Votar" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#: lib/claper_web/live/event_live/event_form_component.html.heex:359 +#, elixir-autogen, elixir-format +msgid "User email address" +msgstr "Dirección email del usuario" + +#: lib/claper_web/live/event_live/manage.html.heex:622 +#: lib/claper_web/live/event_live/manage.html.heex:704 +#: lib/claper_web/live/event_live/manage.html.heex:778 +#, elixir-autogen, elixir-format +msgid "Active" +msgstr "Activa" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:177 +#, 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:939 +#, elixir-autogen, elixir-format +msgid "Messages from attendees will appear here." +msgstr "Los mensajes de los asistentes aparecerán aquí." + +#: lib/claper_web/live/event_live/event_card_component.ex:218 +#, elixir-autogen, elixir-format +msgid "Processing your file..." +msgstr "Procesando tu fichero..." + +#: lib/claper_web/live/poll_live/form_component.html.heex:106 +#, 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?" + +#: lib/claper_web/live/event_live/manage.html.heex:395 +#, elixir-autogen, elixir-format +msgid "Press F in the presentation window to enable fullscreen" +msgstr "Pulsa F en la ventana de presentación para activar el modo pantalla completa" + +#: lib/claper_web/live/event_live/show.html.heex:323 +#, elixir-autogen, elixir-format +msgid "Ask, comment..." +msgstr "Pregunta, deja comentarios..." + +#: lib/claper_web/live/event_live/manage.html.heex:885 +#: lib/claper_web/live/stat_live/index.html.heex:71 +#: lib/claper_web/live/stat_live/index.html.heex:271 +#, elixir-autogen, elixir-format +msgid "Messages" +msgstr "Mensajes" + +#: lib/claper_web/live/event_live/manage.html.heex:630 +#: lib/claper_web/live/event_live/manage.html.heex:712 +#: lib/claper_web/live/event_live/manage.html.heex:786 +#, elixir-autogen, elixir-format +msgid "Set active" +msgstr "Activar" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:325 +#, elixir-autogen, elixir-format +msgid "Add facilitator" +msgstr "Añadir colaborador" + +#: lib/claper_web/templates/error/404.html.heex:31 +#, elixir-autogen, elixir-format +msgid "Oops, page doesn't exist." +msgstr "Uy, la página no existe." + +#: 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 "El sitio está en mantenimiento, ¡volveremos muy pronto!" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:304 +#, elixir-autogen, elixir-format +msgid "Facilitators can present and manage interactions" +msgstr "Los colaboradores pueden presentar y gestionar las interacciones" + +#: 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/magic.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 "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:830 +#, elixir-autogen, elixir-format +msgid "Add interaction" +msgstr "Añadir interacción" + +#: 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 "Bloquear este usuario borrará todos sus mensajes y él no será capaz de unirse de nuevo, ¿estás seguro?" + +#: lib/claper_web/live/event_live/show.ex:50 +#: 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 "Has sido excluido/a de este evento" + +#: 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 "Excluir" + +#: 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 ", pulsa en el enlace proporcionado para conectar (¡comprueba tu bandeja de correo no deseado!)" + +#: 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 "" + +#: 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 "Espera breves minutos a que tu fichero sea procesado" + +#: 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 "Elige un nombre para tu evento, un código para que los asistentes se puedan unir y el periodo en el que tus asistentes podrían empezar a interactuar" + +#: 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 "Pulsa Empezar para abrir tu presentación y mueve la ventana a la pantalla grande" + +#: 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 "Pulsa Presentar/Personalizar para añadir interacción a tus diapositivas" + +#: 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 "¡Enhorabuena! Has dado el primer paso para mejorar tus presentaciones. Aquí tienes los siguientes pasos para poner en marcha presentaciones mejoradas con Claper:" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:69 +#, elixir-autogen, elixir-format +msgid "Enjoy ! ✨" +msgstr "¡ Diviértete ! ✨" + +#: 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 "Te hemos enviado un correo, pulsa en el enlace que te hemos proporcionado para conectar (¡comprueba la bandeja de correo no deseado!)" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:17 +#, elixir-autogen, elixir-format +msgid "Welcome !" +msgstr "¡ Bienvenido/a !" + +#: lib/claper_web/templates/user_notifier/welcome.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Click on the create button on your dashboard" +msgstr "Pulsa el botón crear en tu panel" + +#: lib/claper_web/notifiers/user_notifier.ex:23 +#, elixir-autogen, elixir-format +msgid "Next steps to boost your presentations" +msgstr "Siguientes pasos para potenciar tus presentaciones" + +#: lib/claper_web/live/stat_live/index.html.heex:78 +#, elixir-autogen, elixir-format +msgid "from %{count} people" +msgid_plural "from %{count} peoples" +msgstr[0] "de %{count} persona" +msgstr[1] "de %{count} personas" + +#: lib/claper_web/live/stat_live/index.html.heex:115 +#, elixir-autogen, elixir-format +msgid "from %{count} poll" +msgid_plural "from %{count} polls" +msgstr[0] "de %{count} votación" +msgstr[1] "de %{count} votaciones" + +#: lib/claper_web/live/stat_live/index.html.heex:108 +#, elixir-autogen, elixir-format +msgid "Average voters" +msgstr "Media de votantes" + +#: lib/claper_web/live/stat_live/index.html.heex:15 +#, elixir-autogen, elixir-format +msgid "Event" +msgstr "Evento" + +#: lib/claper_web/live/stat_live/index.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Interactions history" +msgstr "Historial de interacciones" + +#: lib/claper_web/live/stat_live/index.html.heex:275 +#, elixir-autogen, elixir-format +msgid "No messages has been sent" +msgstr "No se han enviado mensajes" + +#: lib/claper_web/live/event_live/event_card_component.ex:255 +#, elixir-autogen, elixir-format +msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" +msgstr "Esto borrará todos los datos relativos a tu evento, y no se puede deshacer. ¿Estás seguro/a?" + +#: lib/claper_web/live/stat_live/index.html.heex:45 +#, elixir-autogen, elixir-format +msgid "attendee" +msgid_plural "attendees" +msgstr[0] "asistente" +msgstr[1] "asistentes" + +#: lib/claper_web/live/stat_live/index.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Audience peak" +msgstr "Pico de audiencia" + +#: lib/claper_web/live/stat_live/index.html.heex:146 +#, elixir-autogen, elixir-format +msgid "Engagement rate" +msgstr "Nivel de participación" + +#: lib/claper_web/live/event_live/event_card_component.ex:197 +#, elixir-autogen, elixir-format +msgid "Error when processing the file" +msgstr "" + +#: 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 "Acerca de" + +#: 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:60 +#, elixir-autogen, elixir-format +msgid "Login" +msgstr "Iniciar sesión" + +#: lib/claper_web/templates/user_session/new.html.heex:25 +#, elixir-autogen, elixir-format +msgid "Connect to your account" +msgstr "Conecta con tu cuenta" + +#: lib/claper_web/live/event_live/show.html.heex:448 +#, elixir-autogen, elixir-format +msgid "Or use the code:" +msgstr "O usa el código:" + +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:71 +#, elixir-autogen, elixir-format +msgid "Create account" +msgstr "Crear cuenta" + +#: lib/claper_web/live/user_settings_live/show.html.heex:118 +#: 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:51 +#, elixir-autogen, elixir-format +msgid "Password" +msgstr "Contraseña" + +#: lib/claper_web/templates/user_session/new.html.heex:39 +#, elixir-autogen, elixir-format +msgid "Your email address" +msgstr "Tu dirección email" + +#: lib/claper_web/templates/user_session/new.html.heex:49 +#, elixir-autogen, elixir-format +msgid "Your password" +msgstr "Tu contraseña" + +#: lib/claper_web/live/user_settings_live/show.ex:44 +#, elixir-autogen, elixir-format +msgid "Change the password used to access your account." +msgstr "Cambiar la contraseña usada para acceder a tu cuenta." + +#: lib/claper_web/live/user_settings_live/show.html.heex:70 +#, elixir-autogen, elixir-format +msgid "Current password" +msgstr "Contraseña actual" + +#: lib/claper_web/live/user_settings_live/show.html.heex:76 +#, elixir-autogen, elixir-format +msgid "New password" +msgstr "Contraseña nueva" + +#: lib/claper_web/live/user_settings_live/show.ex:41 +#, elixir-autogen, elixir-format +msgid "Update your password" +msgstr "Actualizar tu contraseña" + +#: lib/claper_web/live/user_settings_live/show.ex:93 +#, elixir-autogen, elixir-format +msgid "Your password has been updated." +msgstr "Tu contraseña ha sido actualizada." + +#: lib/claper_web/live/form_live/form_component.html.heex:30 +#, 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:151 +#, elixir-autogen, elixir-format +msgid "Add form to collect data from your public." +msgstr "Añadir formulario para recopilar datos del público." + +#: lib/claper_web/live/event_live/form_component.ex:51 +#, elixir-autogen, elixir-format +msgid "Current form" +msgstr "Formulario actual" + +#: lib/claper_web/live/event_live/manage.html.heex:246 +#, elixir-autogen, elixir-format +msgid "Edit form" +msgstr "Editar formulario" + +#: lib/claper_web/live/event_live/manage.html.heex:148 +#: lib/claper_web/live/event_live/manage.html.heex:686 +#: lib/claper_web/live/event_live/manage.html.heex:1134 +#: lib/claper_web/live/stat_live/index.html.heex:217 +#, elixir-autogen, elixir-format +msgid "Form" +msgstr "Formulario" + +#: lib/claper_web/live/event_live/manage.html.heex:909 +#, elixir-autogen, elixir-format +msgid "Form submissions" +msgstr "Envíos de formulario" + +#: lib/claper_web/live/event_live/manage.html.heex:1107 +#, 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:760 +#, elixir-autogen, elixir-format +msgid "Name" +msgstr "Nombre" + +#: lib/claper_web/live/event_live/manage.html.heex:245 +#, elixir-autogen, elixir-format +msgid "New form" +msgstr "Nuevo formulario" + +#: lib/claper_web/live/stat_live/index.html.heex:227 +#, elixir-autogen, elixir-format +msgid "No form submission has been sent" +msgstr "No se ha enviado ningún formulario" + +#: lib/claper_web/live/event_live/form_component.ex:32 +#, elixir-autogen, elixir-format +msgid "See current form" +msgstr "Ver formulario actual" + +#: lib/claper_web/live/event_live/form_component.ex:97 +#, elixir-autogen, elixir-format +msgid "Submit" +msgstr "Enviar" + +#: lib/claper_web/live/form_live/form_component.html.heex:37 +#, elixir-autogen, elixir-format +msgid "Text" +msgstr "Texto" + +#: lib/claper_web/live/event_live/manage.html.heex:1127 +#, 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 +#, 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?" + +#: lib/claper_web/live/form_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title of your form" +msgstr "Título de tu formulario" + +#: lib/claper_web/live/form_live/form_component.html.heex:40 +#, elixir-autogen, elixir-format +msgid "Type" +msgstr "Tipo" + +#: lib/claper_web/live/stat_live/index.html.heex:222 +#, elixir-autogen, elixir-format +msgid "Export all submissions" +msgstr "Exportar todos los envíos" + +#: lib/claper_web/live/event_live/poll_component.ex:52 +#, elixir-autogen, elixir-format +msgid "Select one option" +msgstr "Seleccione una opción" + +#: lib/claper_web/live/event_live/poll_component.ex:50 +#, elixir-autogen, elixir-format +msgid "Select one or multiple options" +msgstr "Seleccione una o varias opciones" + +#: lib/claper_web/live/poll_live/form_component.html.heex:24 +#, elixir-autogen, elixir-format +msgid "Multiple answers" +msgstr "Respuestas múltiples" + +#: lib/claper_web/live/event_live/manage.html.heex:213 +#, elixir-autogen, elixir-format +msgid "Import all interactions from another presentation" +msgstr "Importar todas las interacciones de otra presentación" + +#: lib/claper_web/live/event_live/manage.ex:273 +#, elixir-autogen, elixir-format +msgid "Interactions import failed" +msgstr "La importación de interacciones ha fallado" + +#: lib/claper_web/live/event_live/manage.ex:266 +#, elixir-autogen, elixir-format +msgid "Interactions imported successfully" +msgstr "Interacciones importadas con éxito" + +#: lib/claper_web/live/event_live/manage.html.heex:286 +#, elixir-autogen, elixir-format +msgid "Select presentation" +msgstr "Seleccionar presentación" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:92 +#, elixir-autogen, elixir-format +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:86 +#, elixir-autogen, elixir-format +msgid "Attendees settings" +msgstr "Ajustes de asistentes" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:96 +#, elixir-autogen, elixir-format +msgid "Enable messages" +msgstr "Activar mensajes" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:21 +#, elixir-autogen, elixir-format +msgid "Show instructions" +msgstr "Mostrar instrucciones" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:38 +#, elixir-autogen, elixir-format +msgid "Show messages" +msgstr "Mostrar mensajes" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:73 +#: lib/claper_web/live/event_live/manager_settings_component.ex:148 +#, elixir-autogen, elixir-format +msgid "Show poll results" +msgstr "Mostrar resultados de votaciones" + +#: lib/claper_web/live/event_live/show.html.heex:343 +#, elixir-autogen, elixir-format +msgid "Messages deactivated" +msgstr "Mensajes desactivados" + +#: lib/claper_web/live/event_live/show.html.heex:186 +#: lib/claper_web/live/event_live/show.html.heex:207 +#: lib/claper_web/live/event_live/show.html.heex:307 +#, elixir-autogen, elixir-format +msgid "Anonymous" +msgstr "Anónimo" + +#: lib/claper_web/live/event_live/show.html.heex:233 +#, elixir-autogen, elixir-format +msgid "Close" +msgstr "Cerrar" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:113 +#, elixir-autogen, elixir-format +msgid "Enable anonymous messages" +msgstr "Activar mensajes anónimos" + +#: lib/claper_web/live/event_live/show.html.heex:214 +#: lib/claper_web/live/event_live/show.html.heex:259 +#, elixir-autogen, elixir-format +msgid "Enter your name" +msgstr "Teclea tu nombre" + +#: lib/claper_web/live/event_live/presenter.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Or go to %{url} and use the code:" +msgstr "O ve a %{url} y usa el código:" + +#: lib/claper_web/live/event_live/show.html.heex:227 +#, elixir-autogen, elixir-format +msgid "Use your name" +msgstr "Utiliza tu nombre" + +#: lib/claper_web/live/event_live/show.html.heex:207 +#, elixir-autogen, elixir-format +msgid "disabled" +msgstr "desactivada" + +#: lib/claper_web/controllers/user_registration_controller.ex:14 +#, elixir-autogen, elixir-format +msgid "Account creation is disabled" +msgstr "La creación de cuentas está desactivada" + +#: lib/claper_web/live/event_live/manage.html.heex:182 +#, elixir-autogen, elixir-format +msgid "Add a Youtube video or any web content." +msgstr "Agregar vídeo de Youtube o cualquier contenido web." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:51 +#, elixir-autogen, elixir-format +msgid "Confirm new password" +msgstr "Confirmar nueva contraseña" + +#: lib/claper_web/templates/user_session/new.html.heex:66 +#, elixir-autogen, elixir-format +msgid "Forgot your password?" +msgstr "¿Contraseña olvidada?" + +#: 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 "Si tu email está en nuestro sistema, en breve recibirás instrucciones para restablecer tu contraseña." + +#: lib/claper_web/templates/user_reset_password/edit.html.heex:42 +#, elixir-autogen, elixir-format +msgid "Password confirmation" +msgstr "Confirmación de contraseña" + +#: lib/claper_web/controllers/user_reset_password_controller.ex:44 +#, elixir-autogen, elixir-format +msgid "Password updated successfully." +msgstr "Contraseña actualizada con éxito." + +#: 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 "El enlace de restablecimiento de contraseña es inválido o ha caducado." + +#: 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 "Restablecer tu contraseña" + +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 +#, elixir-autogen, elixir-format +msgid "Send link to reset password" +msgstr "Enviar enlace para restablecer contraseña" + +#: lib/claper_web/live/embed_live/form_component.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Attendee can view the web content on their device" +msgstr "Los asistentes puede ver el contenido web en su dispositivo" + +#: lib/claper_web/live/event_live/embed_component.ex:59 +#, elixir-autogen, elixir-format +msgid "Current web content" +msgstr "Contenido actual" + +#: lib/claper_web/live/event_live/manage.html.heex:267 +#, elixir-autogen, elixir-format +msgid "Edit web content" +msgstr "Editar contenido web" + +#: lib/claper_web/live/event_live/manage.html.heex:266 +#, elixir-autogen, elixir-format +msgid "New web content" +msgstr "Nuevo contenido web" + +#: lib/claper_web/live/event_live/embed_component.ex:36 +#, elixir-autogen, elixir-format +msgid "See current web content" +msgstr "Ver contenido" + +#: lib/claper_web/live/embed_live/form_component.html.heex:25 +#, elixir-autogen, elixir-format +msgid "The iframe component" +msgstr "El componente iframe" + +#: lib/claper_web/live/embed_live/form_component.html.heex:62 +#, elixir-autogen, elixir-format +msgid "This will delete the web content, are you sure?" +msgstr "Esto borrará el contenido web, ¿estás seguro/a?" + +#: lib/claper_web/live/embed_live/form_component.html.heex:14 +#, elixir-autogen, elixir-format +msgid "Title" +msgstr "Título" + +#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:761 +#: lib/claper_web/live/stat_live/index.html.heex:259 +#, elixir-autogen, elixir-format +msgid "Web content" +msgstr "Contenido" + +#: lib/claper/embeds/embed.ex:38 +#, elixir-autogen, elixir-format +msgid "Invalid embed format (should start with )" +msgstr "Formato embebido inválido (debe comenzar con )" + +#: 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 "Anclar" + +#: 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 "Anclado" + +#: lib/claper_web/live/event_live/manage.html.heex:901 +#, elixir-autogen, elixir-format +msgid "Pinned messages" +msgstr "Mensajes anclados" + +#: lib/claper_web/live/event_live/manage.html.heex:1061 +#, 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:55 +#, elixir-autogen, elixir-format +msgid "Show only pinned messages" +msgstr "Mostrar sólo mensajes anclados" + +#: 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 "Desanclar" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:35 +#, elixir-autogen, elixir-format +msgid "Login or create account" +msgstr "Entrar o crear cuenta" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:22 +#, elixir-autogen, elixir-format +msgid "Someone invited you to manage the event: %{name}" +msgstr "Alguien te ha invitado a gestionar el evento: %{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 "Para aceptar la invitación, por favor entra o crea una cuenta con este correo: %{email}" + +#: lib/claper_web/templates/leader_notifier/invitation.html.heex:17 +#, elixir-autogen, elixir-format +msgid "You have been invited" +msgstr "Has sido invitado/a" + +#: lib/claper_web/notifiers/leader_notifier.ex:12 +#, elixir-autogen, elixir-format +msgid "You have been invited to manage an event" +msgstr "Has sido invitado/a a gestionar un evento" + +#: lib/claper_web/live/event_live/form_component.ex:114 +#, elixir-autogen, elixir-format, fuzzy +msgid "Saved" +msgstr "Guardado" + +#: lib/claper_web/live/event_live/event_card_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Access" +msgstr "Acceso" + +#: lib/claper_web/live/user_settings_live/show.html.heex:179 +#, 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?" + +#: lib/claper_web/live/event_live/event_card_component.ex:157 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "¿Estás seguro de que quieres finalizar este evento? Esta acción no puede deshacerse." + +#: lib/claper_web/live/event_live/event_card_component.ex:149 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "Sala de asistentes" + +#: lib/claper_web/live/user_settings_live/show.html.heex:171 +#, 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:168 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "Zona de peligro" + +#: lib/claper_web/live/user_settings_live/show.html.heex:184 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete account" +msgstr "Borrar cuenta" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:130 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable message reactions" +msgstr "Activar reacciones a mensajes" + +#: lib/claper_web/live/event_live/manage.html.heex:423 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "Abrir presentación" + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Terminate" +msgstr "Terminar" + +#: lib/claper_web/live/event_live/event_card_component.ex:244 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "Informe de visualización" + +#: lib/claper_web/live/user_settings_live/show.ex:132 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "Tu cuenta ha sido borrada" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:249 +#, elixir-autogen, elixir-format, fuzzy +msgid "Access code" +msgstr "Código de acceso" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:873 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees interactions" +msgstr "Interacciones de asistentes" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:76 +#: lib/claper_web/live/event_live/manage.html.heex:327 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "Atrás" + +#: lib/claper_web/live/event_live/manage.html.heex:405 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window." +msgstr "Pulsa aquí para abrir la ventana de presentación." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:298 +#, elixir-autogen, elixir-format, fuzzy +msgid "Facilitators" +msgstr "Colaboradores" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:77 +#: lib/claper_web/live/event_live/manage.html.heex:328 +#, elixir-autogen, elixir-format, fuzzy +msgid "Finish" +msgstr "Finalizar" + +#: lib/claper_web/live/event_live/manage.html.heex:875 +#, 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:875 +#, 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:4 +#: lib/claper_web/live/event_live/index.html.heex:75 +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "Next" +msgstr "Siguiente" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:403 +#, 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:1176 +#, 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:1176 +#, 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:118 +#, 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:265 +#, 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:136 +#, elixir-autogen, elixir-format, fuzzy +msgid "Create event" +msgstr "Crear evento" + +#: lib/claper_web/live/event_live/index.html.heex:156 +#, 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:264 +#, elixir-autogen, elixir-format +msgid "Event start date" +msgstr "Fecha de inicio del evento" + +#: lib/claper_web/live/event_live/index.html.heex:88 +#, 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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "If you have slides, you can navigate through the slides with ease using the arrow keys on your keyboard." +msgstr "Si tienes diapositivas, puedes navegar a través de ellas fácilmente usando las teclas de flecha de tu teclado." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, 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:93 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "¿ Tienes prisa ?" + +#: lib/claper_web/live/event_live/index.html.heex:165 +#, elixir-autogen, elixir-format, fuzzy +msgid "Invited events" +msgstr "Eventos invitados" + +#: lib/claper_web/live/event_live/event_card_component.ex:24 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "En vivo" + +#: lib/claper_web/live/event_live/index.html.heex:81 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "Mis eventos" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:241 +#: lib/claper_web/live/event_live/index.html.heex:57 +#, 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:299 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation file (optional)" +msgstr "Fichero de presentación (opcional)" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:11 +#, elixir-autogen, elixir-format, fuzzy +msgid "Presentation settings" +msgstr "Ajustes de presentación" + +#: lib/claper_web/live/event_live/index.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "Evento rápido" + +#: lib/claper_web/live/event_live/index.ex:73 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "Evento rápido creado con éxito" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format, fuzzy +msgid "Return to your last event" +msgstr "Volver a tu último evento" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:58 +#, elixir-autogen, elixir-format, fuzzy +msgid "Select your presentation (optional)" +msgstr "Selecciona tu presentación (opcional)" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:250 +#, 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:193 +#, elixir-autogen, elixir-format +msgid "This event has been terminated" +msgstr "Este evento ha sido terminado" + +#: lib/claper_web/live/event_live/manage.html.heex:529 +#, elixir-autogen, elixir-format, fuzzy +msgid "This section contains all your presentation slides (if you have upload one). You have the option to add interactions to each slide." +msgstr "Esta sección contiene todas las diapositivas de tu presentación (si has subido una). Tienes la opción de añadir interacciones a cada diapositiva." + +#: lib/claper_web/live/event_live/index.html.heex:117 +#, 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:274 +#, elixir-autogen, elixir-format, fuzzy +msgid "When your event will start?" +msgstr "¿Cuándo empezará tu evento?" + +#: lib/claper_web/live/event_live/manage.html.heex:528 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your slides and/or interactions" +msgstr "Tus diapositivas y/o interacciones" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "Crea tu siguiente presentación con" + +#: lib/claper_web/live/event_live/manage.ex:24 +#: lib/claper_web/live/event_live/presenter.ex:21 +#: lib/claper_web/live/event_live/show.ex:24 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "El evento no existe" + +#: lib/claper_web/live/user_settings_live/show.html.heex:140 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "Personaliza tu cuenta" + +#: lib/claper_web/live/user_settings_live/show.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "Idioma" + +#: lib/claper_web/live/user_settings_live/show.html.heex:137 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "Preferencias" + +#: lib/claper_web/live/user_settings_live/show.ex:114 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "Tus preferencias han sido actualizadas." + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "Pregunta" + +#: lib/claper_web/live/event_live/manage.html.heex:893 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "Preguntas" + +#: lib/claper_web/live/event_live/manage.html.heex:980 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "Las preguntas aparecerán aquí." + +#: lib/claper_web/live/event_live/manage.html.heex:1022 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "Ordenar por fecha" + +#: lib/claper_web/live/event_live/manage.html.heex:1001 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "Ordenar por popularidad" + +#: lib/claper_web/live/event_live/event_card_component.ex:126 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "Gestor de evento" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "Documentación" + +#: 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 "Mi cuenta" + +#: lib/claper_web/live/user_settings_live/show.html.heex:96 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your personal informations to access your account" +msgstr "Tus información personal para acceder a tu cuenta" diff --git a/priv/gettext/es/LC_MESSAGES/errors.po b/priv/gettext/es/LC_MESSAGES/errors.po new file mode 100644 index 0000000..9e575ff --- /dev/null +++ b/priv/gettext/es/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: es\n" + +## From Ecto.Changeset.cast/4 +msgid "can't be blank" +msgstr "no puede dejarse en blanco" + +## From Ecto.Changeset.unique_constraint/3 +msgid "has already been taken" +msgstr "ya ha sido tomado" + +## From Ecto.Changeset.put_change/3 +msgid "is invalid" +msgstr "es inválido" + +## From Ecto.Changeset.validate_acceptance/3 +msgid "must be accepted" +msgstr "debe ser aceptado" + +## From Ecto.Changeset.validate_format/3 +msgid "has invalid format" +msgstr "tiene un formato inválido" + +## From Ecto.Changeset.validate_subset/3 +msgid "has an invalid entry" +msgstr "tiene una entrada inválida" + +## From Ecto.Changeset.validate_exclusion/3 +msgid "is reserved" +msgstr "está reservado" + +## From Ecto.Changeset.validate_confirmation/3 +msgid "does not match confirmation" +msgstr "no cuadra con la confirmación" + +## From Ecto.Changeset.no_assoc_constraint/3 +msgid "is still associated with this entry" +msgstr "está todavía asociado con esta entrada" + +msgid "are still associated with this entry" +msgstr "están todavía asociados con esta entrada" + +msgid "should be %{count} character(s)" +msgid_plural "should be %{count} character(s)" +msgstr[0] "debe tener %{count} carácteres de longitud" +msgstr[1] "deben tener %{count} carácteres de longitud" + +## From Ecto.Changeset.validate_length/3 +msgid "should have %{count} item(s)" +msgid_plural "should have %{count} item(s)" +msgstr[0] "debe tener %{count} elementos" +msgstr[1] "deben tener %{count} elementos" + +msgid "should be at least %{count} character(s)" +msgid_plural "should be at least %{count} character(s)" +msgstr[0] "debe tener al menos %{count} carácteres" +msgstr[1] "deben tener al menos %{count} carácteres" + +msgid "should have at least %{count} item(s)" +msgid_plural "should have at least %{count} item(s)" +msgstr[0] "debe tener al menos %{count} elementos" +msgstr[1] "deben tener al menos %{count} elementos" + +msgid "should be at most %{count} character(s)" +msgid_plural "should be at most %{count} character(s)" +msgstr[0] "debe tener como mucho %{count} carácteres" +msgstr[1] "deben tener como mucho %{count} carácteres" + +msgid "should have at most %{count} item(s)" +msgid_plural "should have at most %{count} item(s)" +msgstr[0] "debe tener como mucho %{count} elementos" +msgstr[1] "deben tener como mucho %{count} elementos" + +## From Ecto.Changeset.validate_number/3 +msgid "must be less than %{number}" +msgstr "debe ser menor que %{number}" + +msgid "must be greater than %{number}" +msgstr "debe ser mayor que %{number}" + +msgid "must be less than or equal to %{number}" +msgstr "debe ser menor o igual que %{number}" + +msgid "must be greater than or equal to %{number}" +msgstr "debe ser mayor o igual que %{number}" + +msgid "must be equal to %{number}" +msgstr "debe ser igual a %{number}" diff --git a/priv/gettext/fr/LC_MESSAGES/default.po b/priv/gettext/fr/LC_MESSAGES/default.po index 2f38c79..7af0940 100644 --- a/priv/gettext/fr/LC_MESSAGES/default.po +++ b/priv/gettext/fr/LC_MESSAGES/default.po @@ -8,19 +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/user_settings_live/show.ex:48 -#: lib/claper_web/live/user_settings_live/show.html.heex:5 -#: lib/claper_web/templates/layout/_user_menu.html.heex:2 +#: lib/claper_web/live/event_live/manage.html.heex:1174 +#: lib/claper_web/live/user_settings_live/show.ex:50 #, elixir-autogen, elixir-format msgid "Settings" msgstr "Paramètres" -#: lib/claper_web/live/event_live/manage.ex:650 +#: lib/claper_web/live/event_live/manage.ex:761 #: lib/claper_web/live/form_live/form_component.html.heex:37 #: lib/claper_web/live/user_settings_live/show.html.heex:34 -#: lib/claper_web/templates/user_registration/new.html.heex:34 -#: lib/claper_web/templates/user_reset_password/new.html.heex:33 -#: lib/claper_web/templates/user_session/new.html.heex:47 +#: 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:41 #, elixir-autogen, elixir-format msgid "Email" msgstr "Email" @@ -30,20 +29,20 @@ msgstr "Email" msgid "Join the Claper experience" msgstr "Rejoignez l'expérience Claper" -#: lib/claper_web/templates/user_registration/new.html.heex:24 +#: 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:24 +#: 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 "Oups, vérifiez que tous les champs sont remplis correctement." -#: lib/claper_web/live/user_settings_live/show.html.heex:108 -#: lib/claper_web/live/user_settings_live/show.html.heex:121 +#: lib/claper_web/live/user_settings_live/show.html.heex:112 +#: lib/claper_web/live/user_settings_live/show.html.heex:127 #, elixir-autogen, elixir-format msgid "Change" msgstr "Changer" -#: lib/claper_web/live/event_live/event_form_component.html.heex:239 +#: lib/claper_web/live/event_live/event_form_component.html.heex:257 #, elixir-autogen, elixir-format msgid "Code" msgstr "Code" @@ -53,7 +52,7 @@ msgstr "Code" msgid "Email address" msgstr "Adresse email" -#: lib/claper_web/templates/layout/_user_menu.html.heex:8 +#: lib/claper_web/templates/layout/_user_menu.html.heex:16 #, elixir-autogen, elixir-format msgid "Logout" msgstr "Déconnexion" @@ -73,42 +72,36 @@ msgstr "Nous vous avons déjà envoyé un email pour vous connecter, veuillez r msgid "We sent you an email at" msgstr "Nous vous avons envoyé un email à" -#: lib/claper_web/live/user_settings_live/show.html.heex:96 -#, elixir-autogen, elixir-format -msgid "Your personal informations only visible by you" -msgstr "Vos informations personnelles ne sont visibles que par vous" - -#: lib/claper_web/live/event_live/show.html.heex:405 +#: lib/claper_web/live/event_live/show.html.heex:412 #, elixir-autogen, elixir-format msgid "days" msgstr "jours" -#: lib/claper_web/live/event_live/show.html.heex:411 +#: lib/claper_web/live/event_live/show.html.heex:418 #, elixir-autogen, elixir-format msgid "hours" msgstr "heures" -#: lib/claper_web/live/event_live/show.html.heex:417 +#: lib/claper_web/live/event_live/show.html.heex:424 #, elixir-autogen, elixir-format msgid "minutes" msgstr "minutes" -#: lib/claper_web/live/event_live/show.html.heex:136 +#: lib/claper_web/live/event_live/show.html.heex:143 #, elixir-autogen, elixir-format msgid "Be the first to react !" msgstr "Soyez le premier à réagir !" -#: lib/claper_web/live/event_live/event_card_component.ex:98 -#: lib/claper_web/live/event_live/join.ex:42 -#: lib/claper_web/live/event_live/join.html.heex:106 -#: lib/claper_web/live/event_live/show.html.heex:257 +#: 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/show.html.heex:264 #, elixir-autogen, elixir-format msgid "Join" msgstr "Rejoindre" -#: lib/claper_web/live/event_live/index.ex:82 -#: lib/claper_web/live/event_live/join.html.heex:26 -#: lib/claper_web/live/event_live/join.html.heex:47 +#: lib/claper_web/live/event_live/index.ex:156 +#: lib/claper_web/live/event_live/join.html.heex:31 +#: lib/claper_web/live/event_live/join.html.heex:54 #, elixir-autogen, elixir-format msgid "Dashboard" msgstr "Tableau de bord" @@ -119,38 +112,22 @@ msgstr "Tableau de bord" msgid "Host" msgstr "Animateur" -#: lib/claper_web/live/event_live/show.html.heex:423 +#: lib/claper_web/live/event_live/show.html.heex:430 #, elixir-autogen, elixir-format msgid "seconds" msgstr "secondes" -#: lib/claper_web/live/event_live/index.html.heex:61 -#, elixir-autogen, elixir-format -msgid "Create your first presentation" -msgstr "Créez votre première présentation" - -#: lib/claper_web/live/event_live/event_card_component.ex:50 -#: lib/claper_web/live/event_live/manage.html.heex:81 -#, elixir-autogen, elixir-format -msgid "Finish on" -msgstr "Termine le" - -#: lib/claper_web/live/event_live/event_card_component.ex:30 +#: lib/claper_web/live/event_live/event_card_component.ex:34 #, elixir-autogen, elixir-format msgid "Finished" msgstr "Terminé" -#: lib/claper_web/live/event_live/event_card_component.ex:62 +#: lib/claper_web/live/event_live/event_card_component.ex:64 #, elixir-autogen, elixir-format msgid "Finished on" msgstr "Terminé le" -#: lib/claper_web/live/event_live/event_card_component.ex:20 -#, elixir-autogen, elixir-format -msgid "In progress" -msgstr "En cours" - -#: lib/claper_web/live/event_live/event_card_component.ex:25 +#: lib/claper_web/live/event_live/event_card_component.ex:29 #, elixir-autogen, elixir-format msgid "Incoming" msgstr "À venir" @@ -160,79 +137,53 @@ msgstr "À venir" msgid "Leave" msgstr "Quitter l'événement" -#: lib/claper_web/live/event_live/index.html.heex:16 -#, elixir-autogen, elixir-format -msgid "My presentations" -msgstr "Mes présentations" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:228 -#, elixir-autogen, elixir-format -msgid "Name of your presentation" -msgstr "Nom de votre présentation" - #: lib/claper_web/live/event_live/presenter.html.heex:26 -#: lib/claper_web/live/event_live/show.html.heex:432 +#: lib/claper_web/live/event_live/show.html.heex:439 #, elixir-autogen, elixir-format msgid "Scan to interact in real-time" msgstr "Scannez pour interagir en temps réel" -#: lib/claper_web/live/event_live/event_card_component.ex:56 +#: lib/claper_web/live/event_live/event_card_component.ex:60 #, elixir-autogen, elixir-format msgid "Starting on" msgstr "Commence le" -#: lib/claper_web/live/event_live/event_form_component.ex:206 +#: lib/claper_web/live/event_live/event_form_component.ex:253 #, elixir-autogen, elixir-format msgid "Updated successfully" msgstr "Mis à jour avec succès" -#: lib/claper_web/live/event_live/event_form_component.html.heex:249 -#, elixir-autogen, elixir-format -msgid "When your presentation will be available ?" -msgstr "Quand votre présentation sera-t-elle accessible ?" - -#: lib/claper_web/live/event_live/join.html.heex:72 -#, elixir-autogen, elixir-format -msgid "Return to your last presentation" -msgstr "Revenir à votre dernier événement" - #: lib/claper_web/templates/user_session/new.html.heex:22 #, elixir-autogen, elixir-format msgid "It's time to empower your presentations." msgstr "C'est le moment de propulser vos présentations." -#: lib/claper_web/templates/error/404.html.heex:44 -#: lib/claper_web/templates/error/500.html.heex:45 -#: lib/claper_web/templates/user_registration/confirm.html.heex:28 +#: lib/claper_web/templates/error/404.html.heex:36 +#: lib/claper_web/templates/error/500.html.heex:37 +#: lib/claper_web/templates/user_registration/confirm.html.heex:29 #, elixir-autogen, elixir-format msgid "Return to home" msgstr "Retourner à l'accueil" -#: lib/claper_web/live/event_live/event_form_component.ex:186 +#: lib/claper_web/live/event_live/event_form_component.ex:197 +#: lib/claper_web/live/event_live/event_form_component.ex:233 #, elixir-autogen, elixir-format msgid "Created successfully" msgstr "Mis à jour avec succès" -#: lib/claper_web/live/event_live/manage.ex:24 -#: lib/claper_web/live/event_live/presenter.ex:21 -#: lib/claper_web/live/event_live/show.ex:24 -#, elixir-autogen, elixir-format -msgid "Presentation doesn't exist" -msgstr "La présentation n'existe pas" - -#: lib/claper_web/live/event_live/event_card_component.ex:109 -#: lib/claper_web/live/event_live/event_card_component.ex:129 +#: lib/claper_web/live/event_live/event_card_component.ex:186 +#: lib/claper_web/live/event_live/event_card_component.ex:207 #: lib/claper_web/live/event_live/form_component.ex:97 -#: lib/claper_web/live/event_live/index.ex:65 +#: lib/claper_web/live/event_live/index.ex:139 #, elixir-autogen, elixir-format msgid "Edit" msgstr "Modifier" #: lib/claper_web/live/embed_live/form_component.html.heex:51 -#: lib/claper_web/live/event_live/event_form_component.html.heex:18 #: lib/claper_web/live/event_live/event_form_component.html.heex:25 -#: lib/claper_web/live/event_live/index.ex:71 -#: lib/claper_web/live/event_live/index.html.heex:40 +#: lib/claper_web/live/event_live/event_form_component.html.heex:32 +#: lib/claper_web/live/event_live/index.ex:146 +#: lib/claper_web/live/event_live/index.html.heex:64 #: lib/claper_web/live/form_live/form_component.html.heex:98 #: lib/claper_web/live/poll_live/form_component.html.heex:94 #, elixir-autogen, elixir-format @@ -240,11 +191,10 @@ msgid "Create" msgstr "Créer" #: lib/claper_web/live/embed_live/form_component.html.heex:56 -#: lib/claper_web/live/event_live/event_card_component.ex:171 -#: lib/claper_web/live/event_live/event_form_component.html.heex:30 -#: lib/claper_web/live/event_live/manage.html.heex:835 -#: lib/claper_web/live/event_live/manage.html.heex:1010 -#: lib/claper_web/live/event_live/manage.html.heex:1125 +#: lib/claper_web/live/event_live/event_card_component.ex:249 +#: lib/claper_web/live/event_live/event_form_component.html.heex:37 +#: lib/claper_web/live/event_live/manage.html.heex:1122 +#: 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 @@ -254,8 +204,8 @@ msgid "Delete" msgstr "Supprimer" #: lib/claper_web/live/embed_live/form_component.html.heex:52 -#: lib/claper_web/live/event_live/event_form_component.html.heex:17 #: lib/claper_web/live/event_live/event_form_component.html.heex:24 +#: lib/claper_web/live/event_live/event_form_component.html.heex:31 #: lib/claper_web/live/form_live/form_component.html.heex:99 #: lib/claper_web/live/poll_live/form_component.html.heex:95 #: lib/claper_web/live/user_settings_live/show.html.heex:38 @@ -264,17 +214,17 @@ msgstr "Supprimer" msgid "Save" msgstr "Sauvegarder" -#: lib/claper_web/live/user_settings_live/show.ex:69 +#: lib/claper_web/live/user_settings_live/show.ex:71 #, elixir-autogen, elixir-format msgid "A link to confirm your email change has been sent to the new address." msgstr "Un lien pour confirmer votre changement d'email a été envoyé à la nouvelle adresse." -#: lib/claper_web/live/user_settings_live/show.ex:33 +#: lib/claper_web/live/user_settings_live/show.ex:35 #, elixir-autogen, elixir-format msgid "Change the email address you want associated with your account." msgstr "Modifiez l'email que vous souhaitez associer à votre compte." -#: lib/claper_web/live/user_settings_live/show.ex:30 +#: lib/claper_web/live/user_settings_live/show.ex:32 #, elixir-autogen, elixir-format msgid "Update your email" msgstr "Changer votre email" @@ -316,73 +266,72 @@ msgstr "Si vous n'avez pas créé de compte chez nous, veuillez ignorer ceci." msgid "You can log into your account by clicking here." msgstr "Vous pouvez vous connecter à votre compte en cliquant ici." -#: lib/claper_web/live/event_live/event_form_component.html.heex:34 +#: lib/claper_web/live/event_live/event_form_component.html.heex:41 #: 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 "Êtes-vous sûr?" -#: lib/claper_web/live/event_live/event_form_component.html.heex:149 +#: lib/claper_web/live/event_live/event_form_component.html.heex:162 #, elixir-autogen, elixir-format msgid "Presentation attached" msgstr "Présentation jointe" -#: lib/claper_web/live/event_live/event_form_component.html.heex:109 +#: lib/claper_web/live/event_live/event_form_component.html.heex:122 #, elixir-autogen, elixir-format msgid "Presentation uploaded" msgstr "Présentation chargée" -#: lib/claper_web/live/event_live/event_form_component.html.heex:120 -#: lib/claper_web/live/event_live/event_form_component.html.heex:198 -#: lib/claper_web/live/event_live/event_form_component.html.heex:323 -#: lib/claper_web/live/event_live/event_form_component.html.heex:346 +#: lib/claper_web/live/event_live/event_form_component.html.heex:133 +#: lib/claper_web/live/event_live/event_form_component.html.heex:211 +#: lib/claper_web/live/event_live/event_form_component.html.heex:352 +#: lib/claper_web/live/event_live/event_form_component.html.heex:375 #, elixir-autogen, elixir-format msgid "Remove" msgstr "Supprimer" -#: lib/claper_web/live/event_live/event_form_component.html.heex:45 -#: lib/claper_web/live/event_live/event_form_component.html.heex:130 +#: lib/claper_web/live/event_live/event_form_component.html.heex:143 #, elixir-autogen, elixir-format msgid "Select your presentation" msgstr "Sélectionnez votre présentation" -#: lib/claper_web/live/event_live/event_form_component.html.heex:72 +#: lib/claper_web/live/event_live/event_form_component.html.heex:85 #, elixir-autogen, elixir-format msgid "Upload a file" msgstr "Chargez un fichier" -#: lib/claper_web/live/event_live/event_form_component.html.heex:76 +#: lib/claper_web/live/event_live/event_form_component.html.heex:89 #, elixir-autogen, elixir-format msgid "or drag and drop" msgstr "ou glisser-déposer" -#: lib/claper_web/live/event_live/event_form_component.ex:257 +#: lib/claper_web/live/event_live/event_form_component.ex:304 #, elixir-autogen, elixir-format msgid "You have selected an incorrect file type" msgstr "Vous avez sélectionné un type de fichier incorrect" -#: lib/claper_web/live/event_live/event_form_component.ex:256 +#: lib/claper_web/live/event_live/event_form_component.ex:303 #, elixir-autogen, elixir-format msgid "Your file is too large" msgstr "Votre fichier est trop volumineux" -#: lib/claper_web/live/event_live/event_form_component.html.heex:159 +#: lib/claper_web/live/event_live/event_form_component.html.heex:172 #, elixir-autogen, elixir-format msgid "Change file" msgstr "Changer le fichier" -#: lib/claper_web/live/event_live/event_form_component.html.heex:185 +#: lib/claper_web/live/event_live/event_form_component.html.heex:198 #, elixir-autogen, elixir-format msgid "Presentation replaced" msgstr "Présentation remplacée" -#: lib/claper_web/live/event_live/manage.html.heex:293 +#: lib/claper_web/live/event_live/manage.html.heex:225 #, elixir-autogen, elixir-format msgid "Edit poll" msgstr "Modifier le sondage" -#: lib/claper_web/live/event_live/manage.html.heex:292 +#: lib/claper_web/live/event_live/manage.html.heex:224 #, elixir-autogen, elixir-format msgid "New poll" msgstr "Nouveau sondage" @@ -392,18 +341,18 @@ msgstr "Nouveau sondage" msgid "Title of your poll" msgstr "Titre de votre sondage" -#: lib/claper_web/live/event_live/event_form_component.ex:258 +#: lib/claper_web/live/event_live/event_form_component.ex:305 #, elixir-autogen, elixir-format msgid "Upload failed" msgstr "Échec du chargement" -#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:112 #, 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:177 -#: lib/claper_web/live/event_live/manage.html.heex:461 +#: lib/claper_web/live/event_live/manage.html.heex:109 +#: lib/claper_web/live/event_live/manage.html.heex:604 #, elixir-autogen, elixir-format msgid "Poll" msgstr "Sondage" @@ -426,51 +375,36 @@ msgstr "Sondage actuel" msgid "See current poll" msgstr "Voir le sondage" -#: lib/claper_web/live/event_live/poll_component.ex:123 -#: lib/claper_web/live/event_live/poll_component.ex:131 +#: 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 "Voter" -#: lib/claper_web/live/event_live/index.html.heex:70 -#, elixir-autogen, elixir-format -msgid "Invited presentations" -msgstr "Présentations invitées" - -#: lib/claper_web/live/event_live/event_form_component.html.heex:313 -#: lib/claper_web/live/event_live/event_form_component.html.heex:330 +#: lib/claper_web/live/event_live/event_form_component.html.heex:342 +#: lib/claper_web/live/event_live/event_form_component.html.heex:359 #, elixir-autogen, elixir-format msgid "User email address" msgstr "Adresse email" -#: lib/claper_web/live/event_live/event_card_component.ex:90 -#, elixir-autogen, elixir-format -msgid "Present/Customize" -msgstr "Présenter/Personnaliser" - -#: lib/claper_web/live/event_live/manage.html.heex:479 -#: lib/claper_web/live/event_live/manage.html.heex:561 -#: lib/claper_web/live/event_live/manage.html.heex:635 +#: lib/claper_web/live/event_live/manage.html.heex:622 +#: lib/claper_web/live/event_live/manage.html.heex:704 +#: lib/claper_web/live/event_live/manage.html.heex:778 #, elixir-autogen, elixir-format msgid "Active" msgstr "Actif" -#: lib/claper_web/live/event_live/event_form_component.html.heex:164 +#: lib/claper_web/live/event_live/event_form_component.html.heex:177 #, 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:752 +#: lib/claper_web/live/event_live/manage.html.heex:939 #, elixir-autogen, elixir-format msgid "Messages from attendees will appear here." msgstr "Les messages des participants apparaîtront ici." -#: lib/claper_web/live/event_live/manage.html.heex:1170 -#, elixir-autogen, elixir-format -msgid "On screen settings" -msgstr "Paramètres écran" - -#: lib/claper_web/live/event_live/event_card_component.ex:139 +#: lib/claper_web/live/event_live/event_card_component.ex:218 #, elixir-autogen, elixir-format msgid "Processing your file..." msgstr "Traitement de votre fichier..." @@ -480,50 +414,46 @@ msgstr "Traitement de votre fichier..." 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 ?" -#: lib/claper_web/live/event_live/manage.html.heex:113 -#, elixir-autogen, elixir-format -msgid "Start" -msgstr "Démarrer" - -#: lib/claper_web/live/event_live/manage.html.heex:89 +#: lib/claper_web/live/event_live/manage.html.heex:395 #, elixir-autogen, elixir-format msgid "Press F in the presentation window to enable fullscreen" msgstr "Appuyez sur F dans la fenêtre de présentation pour activer le plein écran" -#: lib/claper_web/live/event_live/show.html.heex:316 +#: lib/claper_web/live/event_live/show.html.heex:323 #, elixir-autogen, elixir-format msgid "Ask, comment..." msgstr "Questionnez, commentez..." -#: lib/claper_web/live/event_live/manage.html.heex:710 +#: lib/claper_web/live/event_live/manage.html.heex:885 #: lib/claper_web/live/stat_live/index.html.heex:71 +#: lib/claper_web/live/stat_live/index.html.heex:271 #, elixir-autogen, elixir-format msgid "Messages" msgstr "Messages" -#: lib/claper_web/live/event_live/manage.html.heex:487 -#: lib/claper_web/live/event_live/manage.html.heex:569 -#: lib/claper_web/live/event_live/manage.html.heex:643 +#: lib/claper_web/live/event_live/manage.html.heex:630 +#: lib/claper_web/live/event_live/manage.html.heex:712 +#: lib/claper_web/live/event_live/manage.html.heex:786 #, elixir-autogen, elixir-format msgid "Set active" msgstr "Activer" -#: lib/claper_web/live/event_live/event_form_component.html.heex:295 +#: lib/claper_web/live/event_live/event_form_component.html.heex:325 #, elixir-autogen, elixir-format msgid "Add facilitator" msgstr "Ajouter un animateur" -#: lib/claper_web/templates/error/404.html.heex:40 +#: lib/claper_web/templates/error/404.html.heex:31 #, elixir-autogen, elixir-format msgid "Oops, page doesn't exist." msgstr "Oups, la page n'existe pas." -#: lib/claper_web/templates/error/500.html.heex:40 +#: 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 "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:275 +#: lib/claper_web/live/event_live/event_form_component.html.heex:304 #, elixir-autogen, elixir-format, fuzzy msgid "Facilitators can present and manage interactions" msgstr "Les animateurs peuvent présenter et gérer les interactions" @@ -540,30 +470,26 @@ msgstr "Si vous rencontrez des difficultés avec le bouton ci-dessus, copiez et 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:678 +#: lib/claper_web/live/event_live/manage.html.heex:830 #, elixir-autogen, elixir-format, fuzzy msgid "Add interaction" msgstr "Ajouter une interaction" -#: lib/claper_web/live/event_live/manage.html.heex:797 -#: lib/claper_web/live/event_live/manage.html.heex:826 -#: lib/claper_web/live/event_live/manage.html.heex:972 -#: lib/claper_web/live/event_live/manage.html.heex:1001 +#: 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 "Bloquer cet utilisateur supprimera tous ses messages et il ne pourra pas rejoindre à nouveau, confirmer ?" #: lib/claper_web/live/event_live/show.ex:50 -#: lib/claper_web/live/event_live/show.ex:198 -#: lib/claper_web/live/event_live/show.ex:213 +#: 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 "Vous avez été banni de cet événement" -#: lib/claper_web/live/event_live/manage.html.heex:791 -#: lib/claper_web/live/event_live/manage.html.heex:820 -#: lib/claper_web/live/event_live/manage.html.heex:966 -#: lib/claper_web/live/event_live/manage.html.heex:995 +#: 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 "Bannir" @@ -659,17 +585,12 @@ msgstr "Événement" msgid "Interactions history" msgstr "Historique des interactions" -#: lib/claper_web/live/stat_live/index.html.heex:271 +#: lib/claper_web/live/stat_live/index.html.heex:275 #, elixir-autogen, elixir-format msgid "No messages has been sent" msgstr "Aucun message n'a été envoyé" -#: lib/claper_web/live/event_live/event_card_component.ex:166 -#, elixir-autogen, elixir-format -msgid "Report" -msgstr "Rapport" - -#: lib/claper_web/live/event_live/event_card_component.ex:177 +#: lib/claper_web/live/event_live/event_card_component.ex:255 #, elixir-autogen, elixir-format msgid "This will delete all data related to your event, this cannot be undone. Confirm ?" msgstr "Cette opération supprimera toutes les données relatives à votre événement, elle ne peut être annulée. Confirmer ?" @@ -692,25 +613,20 @@ msgstr "Pic d'audience" msgid "Engagement rate" msgstr "Taux d'engagement" -#: lib/claper_web/live/event_live/event_card_component.ex:119 +#: lib/claper_web/live/event_live/event_card_component.ex:197 #, elixir-autogen, elixir-format msgid "Error when processing the file" msgstr "Erreur lors du traitement du fichier" -#: lib/claper_web/live/event_live/event_card_component.ex:71 -#, elixir-autogen, elixir-format -msgid "Error when processing the new file" -msgstr "Erreur lors du traitement du nouveau fichier" - -#: lib/claper_web/live/event_live/join.html.heex:23 -#: lib/claper_web/live/event_live/join.html.heex:44 +#: 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 "A propos" -#: lib/claper_web/live/event_live/join.html.heex:32 -#: lib/claper_web/live/event_live/join.html.heex:53 -#: lib/claper_web/templates/user_session/new.html.heex:66 +#: 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:60 #, elixir-autogen, elixir-format msgid "Login" msgstr "Connexion" @@ -720,36 +636,36 @@ msgstr "Connexion" msgid "Connect to your account" msgstr "Connectez-vous à votre compte" -#: lib/claper_web/live/event_live/show.html.heex:441 +#: lib/claper_web/live/event_live/show.html.heex:448 #, elixir-autogen, elixir-format msgid "Or use the code:" msgstr "Ou utilisez le code:" -#: lib/claper_web/templates/user_registration/new.html.heex:51 -#: lib/claper_web/templates/user_session/new.html.heex:77 +#: lib/claper_web/templates/user_registration/new.html.heex:46 +#: lib/claper_web/templates/user_session/new.html.heex:71 #, elixir-autogen, elixir-format, fuzzy msgid "Create account" msgstr "Créer un compte" -#: lib/claper_web/live/user_settings_live/show.html.heex:116 -#: lib/claper_web/templates/user_registration/new.html.heex:42 +#: lib/claper_web/live/user_settings_live/show.html.heex:118 +#: 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:57 +#: lib/claper_web/templates/user_session/new.html.heex:51 #, elixir-autogen, elixir-format msgid "Password" msgstr "Mot de passe" -#: lib/claper_web/templates/user_session/new.html.heex:45 +#: lib/claper_web/templates/user_session/new.html.heex:39 #, elixir-autogen, elixir-format, fuzzy msgid "Your email address" msgstr "Adresse email" -#: lib/claper_web/templates/user_session/new.html.heex:55 +#: lib/claper_web/templates/user_session/new.html.heex:49 #, elixir-autogen, elixir-format msgid "Your password" msgstr "Votre mot de passe" -#: lib/claper_web/live/user_settings_live/show.ex:42 +#: lib/claper_web/live/user_settings_live/show.ex:44 #, elixir-autogen, elixir-format msgid "Change the password used to access your account." msgstr "Changez le mot de passe utilisé pour accéder à votre compte." @@ -764,12 +680,12 @@ msgstr "Mot de passe actuel" msgid "New password" msgstr "Nouveau mot de passe" -#: lib/claper_web/live/user_settings_live/show.ex:39 +#: lib/claper_web/live/user_settings_live/show.ex:41 #, elixir-autogen, elixir-format, fuzzy msgid "Update your password" msgstr "Changer votre email" -#: lib/claper_web/live/user_settings_live/show.ex:91 +#: lib/claper_web/live/user_settings_live/show.ex:93 #, elixir-autogen, elixir-format, fuzzy msgid "Your password has been updated." msgstr "Votre mot de passe a été mis à jour." @@ -782,7 +698,7 @@ msgstr[0] "Champ %{count}" msgstr[1] "Champ %{count}" msgstr[2] "Champ %{count}" -#: lib/claper_web/live/event_live/manage.html.heex:219 +#: lib/claper_web/live/event_live/manage.html.heex:151 #, 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." @@ -792,39 +708,40 @@ msgstr "Ajoutez un formulaire pour recueillir les données de votre public." msgid "Current form" msgstr "Sondage actuel" -#: lib/claper_web/live/event_live/manage.html.heex:314 +#: lib/claper_web/live/event_live/manage.html.heex:246 #, elixir-autogen, elixir-format, fuzzy msgid "Edit form" msgstr "Modifier" -#: lib/claper_web/live/event_live/manage.html.heex:216 -#: lib/claper_web/live/event_live/manage.html.heex:543 -#: lib/claper_web/live/stat_live/index.html.heex:215 +#: lib/claper_web/live/event_live/manage.html.heex:148 +#: lib/claper_web/live/event_live/manage.html.heex:686 +#: lib/claper_web/live/event_live/manage.html.heex:1134 +#: lib/claper_web/live/stat_live/index.html.heex:217 #, elixir-autogen, elixir-format msgid "Form" msgstr "Formulaire" -#: lib/claper_web/live/event_live/manage.html.heex:722 +#: lib/claper_web/live/event_live/manage.html.heex:909 #, elixir-autogen, elixir-format msgid "Form submissions" msgstr "Soumissions de formulaire" -#: lib/claper_web/live/event_live/manage.html.heex:1104 +#: lib/claper_web/live/event_live/manage.html.heex:1107 #, 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:649 +#: lib/claper_web/live/event_live/manage.ex:760 #, elixir-autogen, elixir-format msgid "Name" msgstr "Nom" -#: lib/claper_web/live/event_live/manage.html.heex:313 +#: lib/claper_web/live/event_live/manage.html.heex:245 #, elixir-autogen, elixir-format msgid "New form" msgstr "Nouveau formulaire" -#: lib/claper_web/live/stat_live/index.html.heex:225 +#: lib/claper_web/live/stat_live/index.html.heex:227 #, elixir-autogen, elixir-format msgid "No form submission has been sent" msgstr "Aucun formulaire n'a été envoyé" @@ -844,7 +761,7 @@ msgstr "Soumettre" msgid "Text" msgstr "Texte" -#: lib/claper_web/live/event_live/manage.html.heex:1130 +#: lib/claper_web/live/event_live/manage.html.heex:1127 #, elixir-autogen, elixir-format msgid "This cannot be undone, confirm ?" msgstr "Cela ne peut pas être annulé, confirmez-vous ?" @@ -864,7 +781,7 @@ msgstr "Titre de votre formulaire" msgid "Type" msgstr "Type" -#: lib/claper_web/live/stat_live/index.html.heex:220 +#: lib/claper_web/live/stat_live/index.html.heex:222 #, elixir-autogen, elixir-format, fuzzy msgid "Export all submissions" msgstr "Exporter toutes les soumissions" @@ -884,80 +801,81 @@ msgstr "Sélectionner une ou plusieurs options" msgid "Multiple answers" msgstr "Réponses multiples" -#: lib/claper_web/live/event_live/manage.html.heex:281 +#: lib/claper_web/live/event_live/manage.html.heex:213 #, elixir-autogen, elixir-format msgid "Import all interactions from another presentation" msgstr "Importer toutes les interactions d'une autre présentation" -#: lib/claper_web/live/event_live/manage.ex:226 +#: lib/claper_web/live/event_live/manage.ex:273 #, elixir-autogen, elixir-format msgid "Interactions import failed" msgstr "Échec de l'importation d'interactions" -#: lib/claper_web/live/event_live/manage.ex:219 +#: lib/claper_web/live/event_live/manage.ex:266 #, elixir-autogen, elixir-format msgid "Interactions imported successfully" msgstr "Interactions importées avec succès" -#: lib/claper_web/live/event_live/manage.html.heex:354 +#: lib/claper_web/live/event_live/manage.html.heex:286 #, elixir-autogen, elixir-format msgid "Select presentation" msgstr "Sélectionnez la présentation" -#: lib/claper_web/live/event_live/event_form_component.html.heex:79 +#: lib/claper_web/live/event_live/event_form_component.html.heex:92 #, elixir-autogen, elixir-format msgid "PDF, PPT, PPTX up to %{size} MB" msgstr "PDF, PPT, PPTX jusqu'à %{size} MB" -#: lib/claper_web/live/event_live/manage.html.heex:1215 +#: lib/claper_web/live/event_live/manager_settings_component.ex:86 #, elixir-autogen, elixir-format msgid "Attendees settings" msgstr "Paramètres participants" -#: lib/claper_web/live/event_live/manage.html.heex:1224 +#: lib/claper_web/live/event_live/manager_settings_component.ex:96 #, elixir-autogen, elixir-format msgid "Enable messages" msgstr "Activer messages" -#: lib/claper_web/live/event_live/manage.html.heex:1179 +#: lib/claper_web/live/event_live/manager_settings_component.ex:21 #, elixir-autogen, elixir-format msgid "Show instructions" msgstr "Afficher instructions" -#: lib/claper_web/live/event_live/manage.html.heex:1188 +#: lib/claper_web/live/event_live/manager_settings_component.ex:38 #, elixir-autogen, elixir-format msgid "Show messages" msgstr "Afficher messages" -#: lib/claper_web/live/event_live/manage.html.heex:1209 +#: lib/claper_web/live/event_live/manager_settings_component.ex:73 +#: lib/claper_web/live/event_live/manager_settings_component.ex:148 #, elixir-autogen, elixir-format msgid "Show poll results" msgstr "Afficher résultats sondage" -#: lib/claper_web/live/event_live/show.html.heex:336 +#: lib/claper_web/live/event_live/show.html.heex:343 #, elixir-autogen, elixir-format msgid "Messages deactivated" msgstr "Messages désactivés" -#: lib/claper_web/live/event_live/show.html.heex:179 -#: lib/claper_web/live/event_live/show.html.heex:200 -#: lib/claper_web/live/event_live/show.html.heex:300 +#: lib/claper_web/live/event_live/show.html.heex:186 +#: lib/claper_web/live/event_live/show.html.heex:207 +#: lib/claper_web/live/event_live/show.html.heex:307 #, elixir-autogen, elixir-format msgid "Anonymous" msgstr "Anonyme" -#: lib/claper_web/live/event_live/show.html.heex:226 +#: lib/claper_web/live/event_live/show.html.heex:233 #, elixir-autogen, elixir-format msgid "Close" msgstr "Fermer" -#: lib/claper_web/live/event_live/manage.html.heex:1234 +#: lib/claper_web/live/event_live/manager_settings_component.ex:113 #, elixir-autogen, elixir-format, fuzzy msgid "Enable anonymous messages" msgstr "Activer messages anonymes" -#: lib/claper_web/live/event_live/show.html.heex:207 -#: lib/claper_web/live/event_live/show.html.heex:252 +#: lib/claper_web/live/event_live/show.html.heex:214 +#: lib/claper_web/live/event_live/show.html.heex:259 #, elixir-autogen, elixir-format msgid "Enter your name" msgstr "Entrer votre nom" @@ -967,12 +885,12 @@ msgstr "Entrer votre nom" msgid "Or go to %{url} and use the code:" msgstr "Ou allez sur %{url} et utilisez le code:" -#: lib/claper_web/live/event_live/show.html.heex:220 +#: lib/claper_web/live/event_live/show.html.heex:227 #, elixir-autogen, elixir-format msgid "Use your name" msgstr "Utiliser votre nom" -#: lib/claper_web/live/event_live/show.html.heex:200 +#: lib/claper_web/live/event_live/show.html.heex:207 #, elixir-autogen, elixir-format msgid "disabled" msgstr "désactivé" @@ -982,7 +900,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:250 +#: lib/claper_web/live/event_live/manage.html.heex:182 #, elixir-autogen, elixir-format msgid "Add a Youtube video or any web content." msgstr "Ajoutez une vidéo Youtube ou tout autre contenu web." @@ -992,7 +910,7 @@ msgstr "Ajoutez une vidéo Youtube ou tout autre contenu web." msgid "Confirm new password" msgstr "Confirmer le nouveau mot de passe" -#: lib/claper_web/templates/user_session/new.html.heex:72 +#: lib/claper_web/templates/user_session/new.html.heex:66 #, elixir-autogen, elixir-format msgid "Forgot your password?" msgstr "Mot de passe oublié ?" @@ -1023,7 +941,7 @@ msgstr "Le lien de réinitialisation du mot de passe n'est pas valide ou a expir msgid "Reset your password" msgstr "Changer votre mot de passe" -#: lib/claper_web/templates/user_reset_password/new.html.heex:41 +#: lib/claper_web/templates/user_reset_password/new.html.heex:36 #, elixir-autogen, elixir-format msgid "Send link to reset password" msgstr "Envoyer le lien pour réinitialiser le mot de passe" @@ -1038,12 +956,12 @@ msgstr "Le participant peut voir le contenu web sur son appareil" msgid "Current web content" msgstr "Contenu web actuel" -#: lib/claper_web/live/event_live/manage.html.heex:335 +#: lib/claper_web/live/event_live/manage.html.heex:267 #, elixir-autogen, elixir-format msgid "Edit web content" msgstr "Modifier le contenu web" -#: lib/claper_web/live/event_live/manage.html.heex:334 +#: lib/claper_web/live/event_live/manage.html.heex:266 #, elixir-autogen, elixir-format msgid "New web content" msgstr "Nouveau contenu web" @@ -1068,9 +986,9 @@ msgstr "Cela supprimera le contenu web, êtes-vous sûr?" msgid "Title" msgstr "Titre" -#: lib/claper_web/live/event_live/manage.html.heex:248 -#: lib/claper_web/live/event_live/manage.html.heex:618 -#: lib/claper_web/live/stat_live/index.html.heex:257 +#: lib/claper_web/live/event_live/manage.html.heex:180 +#: lib/claper_web/live/event_live/manage.html.heex:761 +#: lib/claper_web/live/stat_live/index.html.heex:259 #, elixir-autogen, elixir-format msgid "Web content" msgstr "Contenu web" @@ -1080,10 +998,8 @@ msgstr "Contenu web" msgid "Invalid embed format (should start with )" msgstr "Format d'intégration invalide (doit commencer par )" -#: lib/claper_web/live/event_live/manage.html.heex:781 -#: lib/claper_web/live/event_live/manage.html.heex:810 -#: lib/claper_web/live/event_live/manage.html.heex:956 -#: lib/claper_web/live/event_live/manage.html.heex:985 +#: 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 "Épingler" @@ -1094,25 +1010,23 @@ msgstr "Épingler" msgid "Pinned" msgstr "Épinglé" -#: lib/claper_web/live/event_live/manage.html.heex:714 +#: lib/claper_web/live/event_live/manage.html.heex:901 #, elixir-autogen, elixir-format, fuzzy msgid "Pinned messages" msgstr "Messages épinglés" -#: lib/claper_web/live/event_live/manage.html.heex:925 +#: lib/claper_web/live/event_live/manage.html.heex:1061 #, elixir-autogen, elixir-format msgid "Pinned messages will appear here." msgstr "Les messages épinglés apparaîtront ici." -#: lib/claper_web/live/event_live/manage.html.heex:1198 +#: lib/claper_web/live/event_live/manager_settings_component.ex:55 #, elixir-autogen, elixir-format msgid "Show only pinned messages" msgstr "Afficher uniquement les messages épinglés" -#: lib/claper_web/live/event_live/manage.html.heex:779 -#: lib/claper_web/live/event_live/manage.html.heex:808 -#: lib/claper_web/live/event_live/manage.html.heex:954 -#: lib/claper_web/live/event_live/manage.html.heex:983 +#: 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 "Détacher" @@ -1142,7 +1056,357 @@ msgstr "Vous avez été invité" msgid "You have been invited to manage an event" msgstr "Vous avez été invité à gérer un événement" -#: lib/claper_web/live/event_live/form_component.ex:103 +#: lib/claper_web/live/event_live/form_component.ex:114 #, elixir-autogen, elixir-format, fuzzy msgid "Saved" msgstr "Enregistré" + +#: lib/claper_web/live/event_live/event_card_component.ex:85 +#, elixir-autogen, elixir-format +msgid "Access" +msgstr "Accès" + +#: lib/claper_web/live/user_settings_live/show.html.heex:179 +#, 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 ?" + +#: lib/claper_web/live/event_live/event_card_component.ex:157 +#, elixir-autogen, elixir-format +msgid "Are you sure you want to terminate this event? This action cannot be undone." +msgstr "Êtes-vous sûr de vouloir terminer cet événement ? Cette action est irréversible." + +#: lib/claper_web/live/event_live/event_card_component.ex:149 +#, elixir-autogen, elixir-format +msgid "Attendees room" +msgstr "Salle des participants" + +#: lib/claper_web/live/user_settings_live/show.html.heex:171 +#, 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:168 +#, elixir-autogen, elixir-format +msgid "Danger zone" +msgstr "Zone de danger" + +#: lib/claper_web/live/user_settings_live/show.html.heex:184 +#, elixir-autogen, elixir-format, fuzzy +msgid "Delete account" +msgstr "Supprimer le compte" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:130 +#, elixir-autogen, elixir-format, fuzzy +msgid "Enable message reactions" +msgstr "Activer les réactions aux messages" + +#: lib/claper_web/live/event_live/manage.html.heex:423 +#, elixir-autogen, elixir-format +msgid "Open presentation" +msgstr "Ouvrir la présentation" + +#: lib/claper_web/live/event_live/event_card_component.ex:175 +#, elixir-autogen, elixir-format +msgid "Terminate" +msgstr "Terminer" + +#: lib/claper_web/live/event_live/event_card_component.ex:244 +#, elixir-autogen, elixir-format +msgid "View report" +msgstr "Voir le rapport" + +#: lib/claper_web/live/user_settings_live/show.ex:132 +#, elixir-autogen, elixir-format +msgid "Your account has been deleted." +msgstr "Votre compte a été supprimé." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:249 +#, elixir-autogen, elixir-format, fuzzy +msgid "Access code" +msgstr "Code d'accès" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:873 +#, elixir-autogen, elixir-format, fuzzy +msgid "Attendees interactions" +msgstr "Interactions des participants" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:5 +#: lib/claper_web/live/event_live/index.html.heex:76 +#: lib/claper_web/live/event_live/manage.html.heex:327 +#, elixir-autogen, elixir-format +msgid "Back" +msgstr "Retour" + +#: lib/claper_web/live/event_live/manage.html.heex:405 +#, elixir-autogen, elixir-format +msgid "Click here to open the presentation window." +msgstr "Cliquez ici pour ouvrir la fenêtre de présentation." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:298 +#, elixir-autogen, elixir-format, fuzzy +msgid "Facilitators" +msgstr "Animateurs" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:6 +#: lib/claper_web/live/event_live/index.html.heex:77 +#: lib/claper_web/live/event_live/manage.html.heex:328 +#, elixir-autogen, elixir-format, fuzzy +msgid "Finish" +msgstr "Finir" + +#: lib/claper_web/live/event_live/manage.html.heex:875 +#, 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:875 +#, 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:4 +#: lib/claper_web/live/event_live/index.html.heex:75 +#: lib/claper_web/live/event_live/manage.html.heex:326 +#, elixir-autogen, elixir-format, fuzzy +msgid "Next" +msgstr "Suivant" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:54 +#, 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 "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:403 +#, 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:1176 +#, 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:1176 +#, 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:118 +#, 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:265 +#, 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:136 +#, elixir-autogen, elixir-format +msgid "Create event" +msgstr "Créer un événement" + +#: lib/claper_web/live/event_live/index.html.heex:156 +#, 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:264 +#, 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:88 +#, 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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "If you have slides, you can navigate through the slides with ease using the arrow keys on your keyboard." +msgstr "Si vous avez des diapositives, vous pouvez naviguer facilement entre les diapositives en utilisant les touches fléchées de votre clavier." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:299 +#, 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:93 +#, elixir-autogen, elixir-format +msgid "In a hurry ?" +msgstr "Pressé ?" + +#: lib/claper_web/live/event_live/index.html.heex:165 +#, elixir-autogen, elixir-format +msgid "Invited events" +msgstr "Événements invités" + +#: lib/claper_web/live/event_live/event_card_component.ex:24 +#, elixir-autogen, elixir-format +msgid "Live" +msgstr "En direct" + +#: lib/claper_web/live/event_live/index.html.heex:81 +#, elixir-autogen, elixir-format +msgid "My events" +msgstr "Mes événements" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:241 +#: lib/claper_web/live/event_live/index.html.heex:57 +#, 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:299 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:55 +#, elixir-autogen, elixir-format +msgid "Presentation file (optional)" +msgstr "Fichier de présentation (facultatif)" + +#: lib/claper_web/live/event_live/manager_settings_component.ex:11 +#, elixir-autogen, elixir-format +msgid "Presentation settings" +msgstr "Paramètres de présentation" + +#: lib/claper_web/live/event_live/index.html.heex:111 +#, elixir-autogen, elixir-format +msgid "Quick event" +msgstr "Événement rapide" + +#: lib/claper_web/live/event_live/index.ex:73 +#, elixir-autogen, elixir-format +msgid "Quick event created successfully" +msgstr "Événement rapide créé avec succès" + +#: lib/claper_web/live/event_live/join.html.heex:104 +#, elixir-autogen, elixir-format +msgid "Return to your last event" +msgstr "Retourner à votre dernier événement" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:265 +#, 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." + +#: lib/claper_web/live/event_live/event_form_component.html.heex:58 +#, elixir-autogen, elixir-format +msgid "Select your presentation (optional)" +msgstr "Sélectionnez votre présentation (facultatif)" + +#: lib/claper_web/live/event_live/event_form_component.html.heex:250 +#, 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: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/manage.html.heex:529 +#, elixir-autogen, elixir-format +msgid "This section contains all your presentation slides (if you have upload one). You have the option to add interactions to each slide." +msgstr "Cette section contient toutes vos diapositives de présentation (si vous en avez téléchargé une). Vous avez la possibilité d'ajouter des interactions à chaque diapositive." + +#: lib/claper_web/live/event_live/index.html.heex:117 +#, 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:274 +#, elixir-autogen, elixir-format +msgid "When your event will start?" +msgstr "Quand votre événement commencera-t-il ?" + +#: lib/claper_web/live/event_live/manage.html.heex:528 +#, elixir-autogen, elixir-format +msgid "Your slides and/or interactions" +msgstr "Vos diapositives et/ou interactions" + +#: lib/claper_web/live/event_live/show.html.heex:38 +#, elixir-autogen, elixir-format +msgid "Create your next presentation with" +msgstr "Créez votre prochaine présentation avec" + +#: lib/claper_web/live/event_live/manage.ex:24 +#: lib/claper_web/live/event_live/presenter.ex:21 +#: lib/claper_web/live/event_live/show.ex:24 +#, elixir-autogen, elixir-format +msgid "Event doesn't exist" +msgstr "L'événement n'existe pas" + +#: lib/claper_web/live/user_settings_live/show.html.heex:140 +#, elixir-autogen, elixir-format +msgid "Customize your account" +msgstr "Personnalisez votre compte" + +#: lib/claper_web/live/user_settings_live/show.html.heex:158 +#, elixir-autogen, elixir-format +msgid "Language" +msgstr "Langue" + +#: lib/claper_web/live/user_settings_live/show.html.heex:137 +#, elixir-autogen, elixir-format +msgid "Preferences" +msgstr "Préférences" + +#: lib/claper_web/live/user_settings_live/show.ex:114 +#, elixir-autogen, elixir-format +msgid "Your preferences have been updated." +msgstr "Vos préférences ont été mises à jour." + +#: lib/claper_web/live/event_live/manageable_post_component.ex:29 +#, elixir-autogen, elixir-format +msgid "Question" +msgstr "Question" + +#: lib/claper_web/live/event_live/manage.html.heex:893 +#, elixir-autogen, elixir-format +msgid "Questions" +msgstr "Questions" + +#: lib/claper_web/live/event_live/manage.html.heex:980 +#, elixir-autogen, elixir-format +msgid "Questions will appear here." +msgstr "Les questions apparaîtront ici." + +#: lib/claper_web/live/event_live/manage.html.heex:1022 +#, elixir-autogen, elixir-format +msgid "Sort by date" +msgstr "Trier par date" + +#: lib/claper_web/live/event_live/manage.html.heex:1001 +#, elixir-autogen, elixir-format +msgid "Sort by popularity" +msgstr "Trier par popularité" + +#: lib/claper_web/live/event_live/event_card_component.ex:126 +#, elixir-autogen, elixir-format +msgid "Event manager" +msgstr "Gestionnaire d'événement" + +#: lib/claper_web/templates/layout/_user_menu.html.heex:12 +#, elixir-autogen, elixir-format +msgid "Documentation" +msgstr "Documentation" + +#: 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 "Mon compte" + +#: lib/claper_web/live/user_settings_live/show.html.heex:96 +#, elixir-autogen, elixir-format, fuzzy +msgid "Your personal informations to access your account" +msgstr "Vos informations personnelles pour accéder à votre compte" diff --git a/priv/repo/migrations/20240323140827_add_message_reaction_enabled_to_presentation_states.exs b/priv/repo/migrations/20240323140827_add_message_reaction_enabled_to_presentation_states.exs new file mode 100644 index 0000000..b8dc802 --- /dev/null +++ b/priv/repo/migrations/20240323140827_add_message_reaction_enabled_to_presentation_states.exs @@ -0,0 +1,9 @@ +defmodule Claper.Repo.Migrations.AddMessageReactionEnabledToPresentationStates do + use Ecto.Migration + + def change do + alter table(:presentation_states) do + add :message_reaction_enabled, :boolean, default: true + end + end +end diff --git a/priv/repo/migrations/20240405111550_add_show_poll_results_enabled_to_presentation_states.exs b/priv/repo/migrations/20240405111550_add_show_poll_results_enabled_to_presentation_states.exs new file mode 100644 index 0000000..0617362 --- /dev/null +++ b/priv/repo/migrations/20240405111550_add_show_poll_results_enabled_to_presentation_states.exs @@ -0,0 +1,9 @@ +defmodule Claper.Repo.Migrations.AddShowPollResultsEnabledToPresentationStates do + use Ecto.Migration + + def change do + alter table(:presentation_states) do + add :show_poll_results_enabled, :boolean, default: true + end + end +end diff --git a/priv/repo/migrations/20240407090614_add_locale_to_users.exs b/priv/repo/migrations/20240407090614_add_locale_to_users.exs new file mode 100644 index 0000000..e057fe2 --- /dev/null +++ b/priv/repo/migrations/20240407090614_add_locale_to_users.exs @@ -0,0 +1,9 @@ +defmodule Claper.Repo.Migrations.AddTimezoneAndLocaleToUsers do + use Ecto.Migration + + def change do + alter table(:users) do + add :locale, :string + end + end +end diff --git a/reset-db.sh b/reset-db.sh index e3370b6..b7cba8e 100755 --- a/reset-db.sh +++ b/reset-db.sh @@ -1,6 +1,6 @@ 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:9 +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_test.exs b/test/claper/accounts_test.exs index f54377a..6c16566 100644 --- a/test/claper/accounts_test.exs +++ b/test/claper/accounts_test.exs @@ -191,7 +191,14 @@ defmodule Claper.AccountsTest do end test "does not update email if token expired", %{user: user, token: token} do - {1, nil} = Repo.update_all(UserToken, set: [inserted_at: ~N[2020-01-01 00:00:00]]) + context = "change:#{user.email}" + + {1, nil} = + from(ut in UserToken, + where: ut.user_id == ^user.id and ut.context == ^context + ) + |> Repo.update_all(set: [inserted_at: ~N[2020-01-01 00:00:00]]) + assert Accounts.update_user_email(user, token) == :error assert Repo.get!(User, user.id).email == user.email assert Repo.get_by(UserToken, user_id: user.id) @@ -235,8 +242,11 @@ defmodule Claper.AccountsTest do refute Accounts.get_user_by_session_token("oops") end - test "does not return user for expired token", %{token: token} do - {1, nil} = Repo.update_all(UserToken, set: [inserted_at: ~N[2020-01-01 00:00:00]]) + test "does not return user for expired token", %{user: user, token: token} do + {1, nil} = + from(ut in UserToken, where: ut.user_id == ^user.id and ut.context == "session") + |> Repo.update_all(set: [inserted_at: ~N[2020-01-01 00:00:00]]) + refute Accounts.get_user_by_session_token(token) end end @@ -296,7 +306,10 @@ defmodule Claper.AccountsTest do end test "does not confirm email if token expired", %{user: user, token: token} do - {1, nil} = Repo.update_all(UserToken, set: [inserted_at: ~N[2020-01-01 00:00:00]]) + {1, nil} = + from(ut in UserToken, where: ut.user_id == ^user.id and ut.context == "confirm") + |> Repo.update_all(set: [inserted_at: ~N[2020-01-01 00:00:00]]) + assert Accounts.confirm_user(token) == :error refute Repo.get!(User, user.id).confirmed_at assert Repo.get_by(UserToken, user_id: user.id) diff --git a/test/claper_web/controllers/user_auth_test.exs b/test/claper_web/controllers/user_auth_test.exs index 7f88a7d..062e72f 100644 --- a/test/claper_web/controllers/user_auth_test.exs +++ b/test/claper_web/controllers/user_auth_test.exs @@ -131,8 +131,10 @@ defmodule ClaperWeb.UserAuthTest do test "redirects if user is not authenticated", %{conn: conn} do conn = conn |> fetch_flash() |> UserAuth.require_authenticated_user([]) assert conn.halted - assert redirected_to(conn) == Routes.user_session_path(conn, :new) - assert get_flash(conn, :error) == "You must log in to access this page." + assert redirected_to(conn) == ~p"/users/log_in" + + assert Phoenix.Flash.get(conn.assigns.flash, :error) == + "You must log in to access this page." end test "stores the path to redirect to on GET", %{conn: conn} do diff --git a/test/claper_web/controllers/user_confirmation_controller_test.exs b/test/claper_web/controllers/user_confirmation_controller_test.exs index 5b863b5..9d3a26b 100644 --- a/test/claper_web/controllers/user_confirmation_controller_test.exs +++ b/test/claper_web/controllers/user_confirmation_controller_test.exs @@ -13,12 +13,12 @@ defmodule ClaperWeb.UserConfirmationControllerTest do @tag :capture_log test "sends a new confirmation token", %{conn: conn, user: user} do conn = - post(conn, Routes.user_confirmation_path(conn, :create), %{ + post(conn, ~p"/users/confirm", %{ "user" => %{"email" => user.email} }) assert redirected_to(conn) == "/" - assert get_flash(conn, :info) =~ "If your email is in our system" + assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "If your email is in our system" assert Repo.get_by!(Accounts.UserToken, user_id: user.id).context == "confirm" end @@ -26,24 +26,28 @@ defmodule ClaperWeb.UserConfirmationControllerTest do Repo.update!(Accounts.User.confirm_changeset(user)) conn = - post(conn, Routes.user_confirmation_path(conn, :create), %{ + post(conn, ~p"/users/confirm", %{ "user" => %{"email" => user.email} }) assert redirected_to(conn) == "/" - assert get_flash(conn, :info) =~ "If your email is in our system" + assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "If your email is in our system" refute Repo.get_by(Accounts.UserToken, user_id: user.id) end test "does not send confirmation token if email is invalid", %{conn: conn} do conn = - post(conn, Routes.user_confirmation_path(conn, :create), %{ + post(conn, ~p"/users/confirm", %{ "user" => %{"email" => "unknown@example.com"} }) assert redirected_to(conn) == "/" - assert get_flash(conn, :info) =~ "If your email is in our system" - assert Repo.all(Accounts.UserToken) == [] + assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "If your email is in our system" + + assert from(ut in Accounts.UserToken, + where: ut.context == "confirm" + ) + |> Repo.all() == [] end end @@ -54,32 +58,41 @@ defmodule ClaperWeb.UserConfirmationControllerTest do Accounts.deliver_user_confirmation_instructions(user, url) end) - conn = post(conn, Routes.user_confirmation_path(conn, :update, token)) + conn = post(conn, ~p"/users/confirm/#{token}") assert redirected_to(conn) == "/" - assert get_flash(conn, :info) =~ "User confirmed successfully" + assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "User confirmed successfully" assert Accounts.get_user!(user.id).confirmed_at refute get_session(conn, :user_token) - assert Repo.all(Accounts.UserToken) == [] + + assert from(ut in Accounts.UserToken, + where: ut.context == "confirm" + ) + |> Repo.all() == [] # When not logged in - conn = post(conn, Routes.user_confirmation_path(conn, :update, token)) + conn = post(conn, ~p"/users/confirm/#{token}") assert redirected_to(conn) == "/" - assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired" + + assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ + "User confirmation link is invalid or it has expired" # When logged in conn = build_conn() |> log_in_user(user) - |> post(Routes.user_confirmation_path(conn, :update, token)) + |> post(~p"/users/confirm/#{token}") assert redirected_to(conn) == "/" - refute get_flash(conn, :error) + refute Phoenix.Flash.get(conn.assigns.flash, :error) end test "does not confirm email with invalid token", %{conn: conn, user: user} do - conn = post(conn, Routes.user_confirmation_path(conn, :update, "oops")) + conn = post(conn, ~p"/users/confirm/#{"oops"}") assert redirected_to(conn) == "/" - assert get_flash(conn, :error) =~ "User confirmation link is invalid or it has expired" + + assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ + "User confirmation link is invalid or it has expired" + refute Accounts.get_user!(user.id).confirmed_at end end diff --git a/test/claper_web/controllers/user_session_controller_test.exs b/test/claper_web/controllers/user_session_controller_test.exs index 9f47404..5d98881 100644 --- a/test/claper_web/controllers/user_session_controller_test.exs +++ b/test/claper_web/controllers/user_session_controller_test.exs @@ -9,26 +9,26 @@ defmodule ClaperWeb.UserSessionControllerTest do describe "GET /users/log_in" do test "renders log in page", %{conn: conn} do - conn = get(conn, Routes.user_session_path(conn, :new)) + conn = get(conn, ~p"/users/log_in") response = html_response(conn, 200) assert response =~ "Your email address" end test "redirects if already logged in", %{conn: conn, user: user} do - conn = conn |> log_in_user(user) |> get(Routes.user_session_path(conn, :new)) + conn = conn |> log_in_user(user) |> get(~p"/users/log_in") assert redirected_to(conn) == "/events" end end describe "DELETE /users/log_out" do test "logs the user out", %{conn: conn, user: user} do - conn = conn |> log_in_user(user) |> delete(Routes.user_session_path(conn, :delete)) + conn = conn |> log_in_user(user) |> delete(~p"/users/log_out") assert redirected_to(conn) == "/" refute get_session(conn, :user_token) end test "succeeds even if the user is not logged in", %{conn: conn} do - conn = delete(conn, Routes.user_session_path(conn, :delete)) + conn = delete(conn, ~p"/users/log_out") assert redirected_to(conn) == "/" refute get_session(conn, :user_token) end diff --git a/test/claper_web/live/components/event_card_component_test.exs b/test/claper_web/live/components/event_card_component_test.exs new file mode 100644 index 0000000..ede1002 --- /dev/null +++ b/test/claper_web/live/components/event_card_component_test.exs @@ -0,0 +1,53 @@ +defmodule ClaperWeb.EventCardComponentTest do + use ClaperWeb.ConnCase + + import Phoenix.LiveViewTest + import Claper.{PresentationsFixtures, EventsFixtures} + + @spec create_event(Claper.Accounts.User.t(), NaiveDateTime.t(), NaiveDateTime.t()) :: + Claper.Presentations.PresentationFile.t() + defp create_event(user, started_at, expired_at \\ nil) do + event = event_fixture(%{user: user, started_at: started_at, expired_at: expired_at}) + presentation_file = presentation_file_fixture(%{event: event}, [:event]) + presentation_state_fixture(%{presentation_file: presentation_file}) + presentation_file + end + + describe "EventCardComponent" do + setup [:register_and_log_in_user] + + test "renders incoming for future event", %{conn: conn, user: user} do + create_event(user, NaiveDateTime.add(NaiveDateTime.utc_now(), 7200, :second)) + {:ok, _view, html} = live(conn, "/events") + assert html =~ "Incoming" + end + + test "renders live for current event", %{conn: conn, user: user} do + create_event(user, NaiveDateTime.utc_now()) + {:ok, _view, html} = live(conn, "/events") + assert html =~ "Live" + end + + test "renders finished for expired event", %{conn: conn, user: user} do + create_event( + user, + NaiveDateTime.add(NaiveDateTime.utc_now(), -7200, :second), + NaiveDateTime.add(NaiveDateTime.utc_now(), -10, :second) + ) + + {:ok, _view, html} = live(conn, "/events") + assert html =~ "Finished" + end + + test "renders finished for expired event before starting", %{conn: conn, user: user} do + create_event( + user, + NaiveDateTime.add(NaiveDateTime.utc_now(), 7200, :second), + NaiveDateTime.utc_now() + ) + + {:ok, _view, html} = live(conn, "/events") + assert html =~ "Finished" + end + end +end diff --git a/test/claper_web/live/event_live_test.exs b/test/claper_web/live/event_live_test.exs index 5357f26..a7dd595 100644 --- a/test/claper_web/live/event_live_test.exs +++ b/test/claper_web/live/event_live_test.exs @@ -16,34 +16,34 @@ defmodule ClaperWeb.EventLiveTest do setup [:register_and_log_in_user, :create_event] test "lists all events", %{conn: conn, presentation_file: presentation_file} do - {:ok, _index_live, html} = live(conn, Routes.event_index_path(conn, :index)) + {:ok, _index_live, html} = live(conn, ~p"/events") - assert html =~ "presentations" + assert html =~ "events" assert html =~ presentation_file.event.name end test "updates event in listing", %{conn: conn, presentation_file: presentation_file} do - {:ok, index_live, _html} = live(conn, Routes.event_index_path(conn, :index)) + {:ok, index_live, _html} = live(conn, ~p"/events") assert index_live |> element("#event-#{presentation_file.event.uuid} a", "Edit") |> render_click() =~ "Edit" - assert_patch(index_live, Routes.event_index_path(conn, :edit, presentation_file.event.uuid)) + assert_patch(index_live, ~p"/events/#{presentation_file.event.uuid}/edit") - {:ok, _, html} = + {:ok, conn} = index_live |> form("#event-form", event: @update_attrs) |> render_submit() - |> follow_redirect(conn, Routes.event_index_path(conn, :index)) + |> follow_redirect(conn, ~p"/events") - assert html =~ "Updated successfully" - assert html =~ "some updated name" + assert html_response(conn, 200) =~ "Updated successfully" + assert html_response(conn, 200) =~ "some updated name" end test "deletes event in listing", %{conn: conn, presentation_file: presentation_file} do - {:ok, index_live, _html} = live(conn, Routes.event_index_path(conn, :index)) + {:ok, index_live, _html} = live(conn, ~p"/events") assert index_live |> element("#event-#{presentation_file.event.uuid} a", "Edit") @@ -54,9 +54,9 @@ defmodule ClaperWeb.EventLiveTest do index_live |> element(~s{a[phx-value-id=#{presentation_file.event.uuid}]}) |> render_click() - |> follow_redirect(conn, Routes.event_index_path(conn, :index)) + |> follow_redirect(conn, ~p"/events") - {:ok, index_live, _html} = live(conn, Routes.event_index_path(conn, :index)) + {:ok, index_live, _html} = live(conn, ~p"/events") refute has_element?(index_live, "#event-#{presentation_file.event.uuid}") end @@ -67,9 +67,9 @@ defmodule ClaperWeb.EventLiveTest do test "displays event", %{conn: conn, presentation_file: presentation_file} do {:ok, _show_live, html} = - live(conn, Routes.event_show_path(conn, :show, presentation_file.event.code)) + live(conn, ~p"/e/#{presentation_file.event.code}") - assert html =~ "Be the first to react" + assert html =~ "Be the first to react !" assert html =~ presentation_file.event.name end end diff --git a/test/claper_web/live/post_live_test.exs b/test/claper_web/live/post_live_test.exs index 47bd6fe..ad467cf 100644 --- a/test/claper_web/live/post_live_test.exs +++ b/test/claper_web/live/post_live_test.exs @@ -16,7 +16,7 @@ defmodule ClaperWeb.PostLiveTest do test "list posts", %{conn: conn, presentation_file: presentation_file} do {:ok, _index_live, html} = - live(conn, Routes.event_show_path(conn, :show, presentation_file.event.code)) + live(conn, ~p"/e/#{presentation_file.event.code}") assert html =~ "some body" end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 0cc461f..f1b830a 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -19,10 +19,13 @@ defmodule ClaperWeb.ConnCase do using do quote do + use ClaperWeb, :verified_routes + # Import conveniences for testing with connections import Plug.Conn import Phoenix.ConnTest import ClaperWeb.ConnCase + import Ecto.Query alias ClaperWeb.Router.Helpers, as: Routes diff --git a/test/support/fixtures/events_fixtures.ex b/test/support/fixtures/events_fixtures.ex index 600c7a2..d391c8e 100644 --- a/test/support/fixtures/events_fixtures.ex +++ b/test/support/fixtures/events_fixtures.ex @@ -22,8 +22,7 @@ defmodule Claper.EventsFixtures do uuid: Ecto.UUID.generate(), user_id: assoc.user.id, started_at: NaiveDateTime.utc_now(), - # add 2 hours - expired_at: NaiveDateTime.add(NaiveDateTime.utc_now(), 7200, :second) + expired_at: nil }) |> Claper.Events.create_event()