Procházet zdrojové kódy

feat: adicionada seleção de idiomas na pagina de login + ajuste responsividade na tela de login

Gustavo Zanatta před 4 týdny
rodič
revize
f55f5e5d01

+ 92 - 0
src/components/LocaleFlagSwitcher.vue

@@ -0,0 +1,92 @@
+<template>
+  <div class="locale-flags row items-center no-wrap">
+    <button
+      v-for="lang in languages"
+      :key="lang.code"
+      type="button"
+      class="locale-flags__btn"
+      :class="{ 'locale-flags__btn--active': currentLocaleBase === lang.code }"
+      :title="lang.label"
+      :aria-label="lang.label"
+      @click="changeLocale(lang.code)"
+    >
+      <svg viewBox="0 0 24 16" class="locale-flags__flag">
+        <template v-if="lang.code === 'pt'">
+          <rect width="24" height="16" fill="#009b3a" />
+          <polygon points="12,1.8 22.2,8 12,14.2 1.8,8" fill="#fedf00" />
+          <circle cx="12" cy="8" r="3.4" fill="#002776" />
+        </template>
+
+        <template v-else-if="lang.code === 'en'">
+          <rect width="24" height="16" fill="#fff" />
+          <rect v-for="i in 7" :key="i" :y="(i - 1) * 2.46" width="24" height="1.23" fill="#b22234" />
+          <rect width="10" height="8.6" fill="#3c3b6e" />
+        </template>
+
+        <template v-else>
+          <rect width="24" height="16" fill="#aa151b" />
+          <rect y="4" width="24" height="8" fill="#f1bf00" />
+        </template>
+      </svg>
+    </button>
+  </div>
+</template>
+
+<script setup>
+import { computed } from "vue";
+import { useI18n } from "vue-i18n";
+
+const { locale } = useI18n();
+
+const languages = [
+  { code: "pt", label: "Português" },
+  { code: "en", label: "English" },
+  { code: "es", label: "Español" },
+];
+
+const currentLocaleBase = computed(() =>
+  locale.value?.split("-")[0].toLowerCase()
+);
+
+const changeLocale = (code) => {
+  locale.value = code;
+};
+</script>
+
+<style lang="scss" scoped>
+.locale-flags {
+  position: fixed;
+  top: calc(16px + env(safe-area-inset-top));
+  right: 16px;
+  z-index: 2000;
+  gap: 8px;
+}
+
+.locale-flags__btn {
+  padding: 0;
+  border: 2px solid rgba(255, 255, 255, 0.7);
+  border-radius: 4px;
+  background: transparent;
+  line-height: 0;
+  cursor: pointer;
+  opacity: 0.65;
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
+  transition: opacity 0.2s, transform 0.2s, border-color 0.2s;
+
+  &:hover {
+    opacity: 1;
+    transform: scale(1.08);
+  }
+
+  &--active {
+    opacity: 1;
+    border-color: #fff;
+  }
+}
+
+.locale-flags__flag {
+  display: block;
+  width: 30px;
+  height: 20px;
+}
+</style>

+ 6 - 0
src/layouts/LoginLayout.vue

@@ -1,7 +1,13 @@
 <template>
   <q-layout view="hHh lpR fFf">
+    <LocaleFlagSwitcher />
+
     <q-page-container>
       <router-view />
     </q-page-container>
   </q-layout>
 </template>
+
+<script setup>
+import LocaleFlagSwitcher from "src/components/LocaleFlagSwitcher.vue";
+</script>

+ 11 - 0
src/pages/login/FirstAccessFormPage.vue

@@ -425,6 +425,7 @@ onBeforeMount(async () => {
 
 .login-logo {
   width: 300px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -487,4 +488,14 @@ onBeforeMount(async () => {
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>

+ 11 - 0
src/pages/login/FirstAccessPage.vue

@@ -151,6 +151,7 @@ const goBack = () => router.push({ name: "LoginPage" });
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -186,4 +187,14 @@ const goBack = () => router.push({ name: "LoginPage" });
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>

+ 11 - 0
src/pages/login/ForgotPasswordPage.vue

@@ -132,6 +132,7 @@ const goBack = () => router.push({ name: "LoginPage" });
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -167,4 +168,14 @@ const goBack = () => router.push({ name: "LoginPage" });
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>

+ 30 - 1
src/pages/login/LoginPage.vue

@@ -16,7 +16,10 @@
             :class="{ 'type-tab--active': selectedTipo === tipo.value }"
             @click="selectedTipo = tipo.value"
           >
-            <div class="column items-center">
+            <div
+              class="items-center"
+              :class="$q.screen.lt.sm ? 'row no-wrap q-gutter-sm' : 'column'"
+            >
               <q-icon :name="tipo.icon" size="22px" />
               <span class="type-tab-label">{{ $t(tipo.label) }}</span>
             </div>
@@ -193,6 +196,7 @@ onBeforeMount(() => {
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-subtitle {
@@ -261,4 +265,29 @@ onBeforeMount(() => {
 }
 
 
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+
+  .type-tabs {
+    flex-direction: column;
+    gap: 8px;
+  }
+
+  .type-tab {
+    width: 100%;
+    min-height: 48px;
+    padding: 8px 16px;
+  }
+
+  .type-tab-label {
+    font-size: 13px;
+  }
+}
 </style>

+ 11 - 0
src/pages/login/ResetPasswordPage.vue

@@ -149,6 +149,7 @@ const goBack = () => router.push({ name: "LoginPage" });
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -177,4 +178,14 @@ const goBack = () => router.push({ name: "LoginPage" });
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>

+ 11 - 0
src/pages/login/VerifyCodePage.vue

@@ -173,6 +173,7 @@ const goBack    = () => router.push({ name: "LoginPage" });
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -274,4 +275,14 @@ const goBack    = () => router.push({ name: "LoginPage" });
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>

+ 11 - 0
src/pages/login/VerifyEmailPage.vue

@@ -100,6 +100,7 @@ const goBack = () => router.push({ name: "LoginPage" });
 
 .login-logo {
   width: 380px;
+  max-width: 100%;
 }
 
 .login-title {
@@ -151,4 +152,14 @@ const goBack = () => router.push({ name: "LoginPage" });
     text-decoration: underline;
   }
 }
+
+@media (max-width: 599px) {
+  .fields-card {
+    padding: 52px 16px 20px;
+  }
+
+  .login-logo {
+    width: 240px;
+  }
+}
 </style>