Kaynağa Gözat

feat: tela de login

ebagabee 1 ay önce
ebeveyn
işleme
d4cff86d1a

BIN
public/images/background.png


+ 1 - 1
quasar.config.js

@@ -107,7 +107,7 @@ export default defineConfig((ctx) => {
     framework: {
       lang: "pt-BR",
       config: {
-        dark: "auto",
+        dark: "false",
         notify: {
           position: "top-right",
         },

+ 1 - 21
src/App.vue

@@ -3,7 +3,7 @@
 </template>
 
 <script setup>
-import { Cookies, useQuasar } from "quasar";
+import { Cookies } from "quasar";
 import { watch } from "vue";
 import { useI18n } from "vue-i18n";
 
@@ -13,26 +13,6 @@ defineOptions({
 
 const { locale } = useI18n();
 
-const $q = useQuasar();
-const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
-  ? "dark"
-  : "light";
-
-const theme = Cookies.get("theme") || systemTheme;
-
-$q.dark.set(theme == "dark");
-
-watch(
-  () => $q.dark.isActive,
-  (value) => {
-    Cookies.set("theme", value ? "dark" : "light", {
-      expires: 365,
-      sameSite: "Lax",
-      path: "/",
-    });
-  },
-);
-
 watch(
   () => locale.value,
   (value) => {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 6 - 0
src/assets/images/logo.svg


+ 0 - 2
src/boot/defaultPropsComponents.js

@@ -21,14 +21,12 @@ export default defineBoot(() => {
   });
   SetComponentDefaults(QInput, {
     rounded: true,
-    dark: true,
     standout: true,
     dense: true,
   });
   SetComponentDefaults(QSelect, {
     rounded: true,
     standout: true,
-    dark: true,
     dense: true,
   });
   SetComponentDefaults(QCard, {

+ 11 - 7
src/components/defaults/DefaultInput.vue

@@ -1,16 +1,12 @@
 <template>
   <div class="column" :class="attrs.class" :style="attrs.style">
-    <div v-if="label || $slots.label" class="q-pl-xs">
-      <slot name="label">
-        <span>{{ label }}</span>
-      </slot>
-      <span v-if="required" class="text-negative q-ml-xs">*</span>
-    </div>
     <div class="col">
       <q-input
         ref="inputRef"
         v-model="model"
         v-bind="inputAttrs"
+        :label
+        label-color="dark"
         :error="!!error"
         :error-message="errorMessage"
         :rules
@@ -22,6 +18,10 @@
         <template v-for="(_, slotName) in $slots" #[slotName]>
           <slot :name="slotName" />
         </template>
+
+        <template #append>
+          <q-icon v-if="icon" :name="icon" size="sm" color="secondary" />
+        </template>
       </q-input>
     </div>
   </div>
@@ -41,11 +41,15 @@ defineOptions({
   inheritAttrs: false,
 });
 
-const { label, nativeInputClass, inputClass, rules } = defineProps({
+const { label, nativeInputClass, inputClass, rules, icon } = defineProps({
   label: {
     type: String,
     default: "",
   },
+  icon: {
+    type: String,
+    default: "",
+  },
   rules: {
     type: Array,
     default: () => [],

+ 4 - 4
src/components/defaults/DefaultPasswordInput.vue

@@ -4,22 +4,22 @@
     v-bind="$attrs"
     :type="!seePassword ? 'password' : 'text'"
   >
-     <template #append>
+    <template #append>
       <q-icon
-        :name="seePassword ? 'mdi-eye-off' : 'mdi-eye'"
+        :name="seePassword ? 'mdi-lock-open-outline' : 'mdi-lock-outline'"
         class="cursor-pointer q-ml-md"
+        color="secondary"
         @click="seePassword = !seePassword"
       />
     </template>
   </DefaultInput>
 </template>
 <script setup>
-import DefaultInput from "./DefaultInput.vue"
+import DefaultInput from "./DefaultInput.vue";
 
 const password = defineModel({ type: String });
 const seePassword = defineModel("seePassword", {
   default: false,
   type: Boolean,
 });
-
 </script>

+ 11 - 53
src/css/app.scss

@@ -1,5 +1,10 @@
 @use "sass:map";
 @use "src/css/quasar.variables.scss";
+@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Rethink+Sans:ital,wght@0,400..800;1,400..800&display=swap');
+
+body {
+  font-family: "Inter", sans-serif;
+}
 
 .flex-grow {
   flex-grow: 1;
@@ -57,28 +62,7 @@ body.body--light {
     }
   }
 
-  background: #{map.get($colors, "page")} !important;
-
-  .q-list--dark,
-  .q-item--dark:not(.q-item--active) {
-    color: black;
-  }
-
-  .q-field--dark {
-    .q-field__control:not(.text-negative) {
-      .q-field__marginal {
-        color: rgba(0, 0, 0, 0.54);
-      }
-      & ~ .q-field__bottom {
-        color: rgba(0, 0, 0, 0.54);
-      }
-    }
-    &:not(.q-field--highlighted)
-      .q-field__control:not(.text-negative)
-      .q-field__label {
-      color: rgba(0, 0, 0, 0.54);
-    }
-  }
+  background: #{map.get($colors, "background")} !important;
 
   .card-ring {
     box-shadow: 0 0 0 1px #c0c0c0c0 !important;
@@ -89,21 +73,6 @@ body.body--light {
   }
 }
 
-body.body--dark {
-  background: #{map.get($colors-dark, "page")};
-
-  .q-drawer:has(.detached-container) {
-    background: #{map.get($colors-dark, "surface")} !important;
-  }
-
-  .q-menu {
-    background: #{map.get($colors-dark, "surface")};
-  }
-
-  .card-ring {
-    box-shadow: 0 0 0 1px #505050 !important;
-  }
-}
 
 .q-card__actions .q-btn {
   padding: 10px 16px;
@@ -139,22 +108,6 @@ input[type="number"]::-webkit-outer-spin-button {
   background: #fff !important;
 }
 
-.q-field--dark .q-field__native {
-  color: black;
-}
-
-.q-field--dark .q-field__native,
-.q-field--dark .q-field__prefix,
-.q-field--dark .q-field__suffix,
-.q-field--dark .q-field__input {
-  color: black;
-}
-
-.q-field--dark:not(.q-field--highlighted) .q-field__label,
-.q-field--dark .q-field__marginal,
-.q-field--dark {
-  color: black;
-}
 
 .q-field--standout.q-field--rounded .q-field__control {
   border-radius: 8px;
@@ -174,3 +127,8 @@ input[type="number"]::-webkit-outer-spin-button {
     }
   }
 }
+
+.q-field--standout.q-field--highlighted .q-field__native {
+  color: $secondary;
+}
+

+ 51 - 153
src/css/quasar.variables.scss

@@ -1,150 +1,59 @@
-// Quasar SCSS Variables with Material Design Color System
-// --------------------------------------------------
+$primary: #003e29; 
+$secondary: #ff8340; 
+$accent: #e91e63;
 
-// Primary Theme Colors
-$primary: #1976d2; // Material Blue 700
-$secondary: #9c27b0; // Material Purple 500
-$accent: #e91e63; // Material Pink 500
+$positive: #2e7d32;
+$negative: #d32f2f;
+$info: #0288d1;
+$warning: #ed6c02;
 
-// Dark Theme Base Colors
-$dark: #1d1d1d;
-
-// Status Colors
-$positive: #2e7d32; // Material Green 800
-$negative: #d32f2f; // Material Red 700
-$info: #0288d1; // Material Light Blue 700
-$warning: #ed6c02; // Material Orange 800
-
-// Extended Color System with Light/Dark Variants
 $colors: (
-  // Primary Colors and Variants
-  "primary": #1976d2,
-  // Base - Blue 700
-  "primary-light": #42a5f5,
-  // Light - Blue 400
-  "primary-dark": #1565c0,
-
-  // Dark - Blue 800
-  // Secondary Colors and Variants
-  "secondary": #9c27b0,
-  // Base - Purple 500
-  "secondary-light": #ba68c8,
-  // Light - Purple 300
-  "secondary-dark": #7b1fa2,
-
-  // Terceary Colors and Variants
-  "terciary": #ff9800,
-  // Base - Orange 500
-  "terciary-light": #ffb74d,
-  // Light - Orange 300
-  "terciary-dark": #f57c00,
-
-  // Dark - Purple 700
-  // Background Colors
-  "page": #f1f1f1,
-
-  // Surface Colors
-  "surface": #ffffff,
-  "surface-light": #f5f5f5,
-  "surface-dark": #f1f1f1,
-
-  //text color
-  "text": #000000,
-
-  // Status Colors with Variants
-  "success": #2e7d32,
-  // Green 800
-  "success-light": #4caf50,
-  // Green 500
-  "success-dark": #1b5e20,
-
-  // Green 900
-  "error": #d32f2f,
-  // Red 700
-  "error-light": #ef5350,
-  // Red 400
-  "error-dark": #c62828,
-
-  // Red 800
-  "warning": #ed6c02,
-  // Orange 800
-  "warning-light": #ff9800,
-  // Orange 500
-  "warning-dark": #e65100,
-
-  // Orange 900
-  "info": #0288d1,
-  // Light Blue 700
-  "info-light": #03a9f4,
-  // Light Blue 500
-  "info-dark": #01579b
+  "primary": #003e29,
+  "primary-2": #406e5f,
+  "primary-3": #809f94,
+  "primary-4": #c0cfca,
+
+  
+  "secondary": #ff8340,
+  "secondary-2": #ffa270,
+  "secondary-3": #ffc1a0,
+  "secondary-4": #ffe0d0,
+
+  "terciary": #ace4e4,
+  "terciary-2": #c1ebeb,
+  "terciary-3": #d6f2f2,
+  "terciary-4": #eaf8f8,
+
+  "background": #ececf0,
+  "background-2": #f1f1f4,
+  "background-3": #f6f6f8,
+  "background-4": #fafafb,
+
+  "suface": #ffffff,
+
+  "stroke": #c9c9c9,
+  "stroke-2": #d7d7d7,
+  "stroke-3": #e4e4e4,
+  "stroke-4": #f2f2f2,
+
+  "alert": #e6cc00,
+  "alert-2": #edd940,
+  "alert-3": #f3e580,
+  "alert-4": #f9f2c0,
+
+  "approved": #00e339,
+  "approved-2": #40ea6b,
+  "approved-3": #80f19c,
+  "approved-4": #c0f8ce,
+
+  "declined": #ff383c,
+  "declined-2": #ff6a6d,
+  "declined-3": #ff9c9e,
+  "declined-4": #ffcecf,
+
+  "warning": #BF6A02,
 );
 
-// Dark Theme Color Overrides
-$colors-dark: (
-  // Primary Colors and Variants
-  "primary": #1976d2,
-  // Base - Blue 700
-  "primary-light": #42a5f5,
-  // Blue 50
-  "primary-dark": #1565c0,
-
-  "dark": #1d1d1d,
-
-  // Blue 400
-  // Secondary Colors - Lighter in Dark Mode
-  "secondary": #ce93d8,
-  // Purple 200
-  "secondary-light": #f3e5f5,
-  // Purple 50
-  "secondary-dark": #ab47bc,
-
-  //Terceary Colors - Lighter in Dark Mode
-  "terciary": #ffd191,
-  // Yellow 200
-  "terciary-light": #ffecb3,
-  // Yellow 50
-  "terciary-dark": #ffab40,
-
-  "page": #121212,
-
-  "surface": #1d1d1d,
-  "surface-light": #333333,
-  "surface-dark": #121212,
-
-  "text": #ffffff,
-
-  // Black Background
-  // Status Colors - Adjusted for Dark Mode
-  "success": #66bb6a,
-  // Green 400
-  "success-light": #81c784,
-  // Green 300
-  "success-dark": #388e3c,
-
-  // Green 700
-  "error": #f44336,
-  // Red 500
-  "error-light": #e57373,
-  // Red 300
-  "error-dark": #d32f2f,
-
-  // Red 700
-  "warning": #ffa726,
-  // Orange 400
-  "warning-light": #ffb74d,
-  // Orange 300
-  "warning-dark": #f57c00,
-
-  // Orange 700
-  "info": #29b6f6,
-  // Light Blue 400
-  "info-light": #4fc3f7,
-  // Light Blue 300
-  "info-dark": #0288d1 // Light Blue 700
-);
-
-// Generate color utility classes for light theme
 @each $name, $color in $colors {
   .text-#{$name} {
     color: $color !important;
@@ -154,14 +63,3 @@ $colors-dark: (
   }
 }
 
-// Generate color utility classes for dark theme
-.body--dark {
-  @each $name, $color in $colors-dark {
-    .text-#{$name} {
-      color: $color !important;
-    }
-    .bg-#{$name} {
-      background: $color !important;
-    }
-  }
-}

+ 2 - 0
src/layouts/LoginLayout.vue

@@ -5,3 +5,5 @@
     </q-page-container>
   </q-layout>
 </template>
+
+<script setup></script>

+ 48 - 27
src/pages/login/LoginPage.vue

@@ -1,18 +1,38 @@
 <template>
-  <q-page class="column">
+  <q-page class="column justify-center items-center login-page">
     <div
       flat
-      class="column justify-around items-center flex-grow full-width full-height z-top frosted-glass"
+      class="column justify-center items-center flex-grow full-width z-top bg-background"
+      style="
+        max-width: 659px;
+        max-height: 738px;
+        width: 100%;
+        height: 100%;
+        border-radius: 15px;
+      "
     >
-      <div class="column flex-center full-width q-px-md">
-        <q-img :src="Logo" style="max-width: 650px" />
-        <div class="text-h5 q-mt-xl">{{ $t("auth.login") }}</div>
+      <div class="column flex-center full-width">
+        <q-img
+          :src="Logo"
+          style="max-width: 611px; max-height: 171px; height: 100%; width: 100%"
+        />
+        <div class="text-h4 q-mt-xl text-primary" style="font-weight: 400">
+          Faça seu Login
+        </div>
+
+        <div
+          class="items-center full-width q-px-lg q-mt-xl"
+          style="display: flex; gap: 12px"
+        >
+          <div class="bg-primary" style="height: 1px; flex: 1"></div>
+          <q-icon name="mdi-chevron-down" size="lg" color="warning" />
+          <div class="bg-primary" style="height: 1px; flex: 1"></div>
+        </div>
       </div>
 
       <q-form
         ref="formRef"
-        class="full-width q-pa-md q-pb-xl"
-        style="max-width: 400px"
+        class="full-width q-px-lg column q-gutter-y-md q-mt-xs"
         autocorrect="off"
         autocapitalize="off"
         autocomplete="off"
@@ -24,28 +44,31 @@
           v-model:error="validationErrors.email"
           type="email"
           lazy-rules
-          autofocus
+          style="color: red"
+          icon="mdi-account"
           :label="$t('common.terms.email')"
           :rules="[inputRules.required, inputRules.email]"
         />
+
         <DefaultPasswordInput
           v-model="form.password"
           v-model:error="validationErrors.password"
           :rules="[inputRules.required, inputRules.min(6)]"
           :label="$t('common.terms.password')"
         />
-        <q-checkbox
-          v-model="checkbox"
-          size="xs"
-          label="Lembrar email"
-          class="q-mb-md"
-          style="margin-left: -6px"
-        />
+
+        <span
+          class="q-ma-xs text-body2 text-primary cursor-pointer"
+          style="letter-spacing: 0.25px"
+          @click="$router.push({ name: 'ForgotMyPasswordPage' })"
+          >Esqueceu sua senha?</span
+        >
+
         <div>
           <q-btn
-            class="full-width"
-            color="primary"
-            :label="$t('auth.sign-in')"
+            class="full-width q-mt-md"
+            color="primary-2"
+            label="Entrar"
             size="md"
             padding="sm"
             type="submit"
@@ -56,10 +79,8 @@
             </template>
           </q-btn>
         </div>
-        <div style="height: 160px"></div>
       </q-form>
     </div>
-    <WavePattern class="absolute-top" />
   </q-page>
 </template>
 
@@ -71,10 +92,9 @@ import { useRouter } from "vue-router";
 import { useInputRules } from "src/composables/useInputRules";
 import { useSubmitHandler } from "src/composables/useSubmitHandler";
 
-import Logo from "src/assets/logo.png";
+import Logo from "src/assets/images/logo.svg";
 import DefaultInput from "src/components/defaults/DefaultInput.vue";
 import DefaultPasswordInput from "src/components/defaults/DefaultPasswordInput.vue";
-import WavePattern from "./component/WavePattern.vue";
 
 const router = useRouter();
 const $q = useQuasar();
@@ -102,10 +122,12 @@ const checkbox = ref(false);
 
 const onSubmit = async () => {
   await submitForm(() => login(form.value.email, form.value.password));
+
   const email_storage = $q.cookies.get("email");
   if (email_storage && !checkbox.value) {
     $q.cookies.remove("email");
   }
+
   if (checkbox.value) {
     $q.cookies.set("email", form.value.email, {
       path: "/",
@@ -125,10 +147,9 @@ onBeforeMount(() => {
 
 <style lang="scss" scoped>
 .login-page {
-  position: relative;
-}
-
-.frosted-glass {
-  backdrop-filter: blur(60px);
+  background-image: url("images/background.png");
+  background-size: cover;
+  background-repeat: no-repeat;
+  background-position: center;
 }
 </style>

+ 0 - 231
src/pages/login/component/WavePattern.vue

@@ -1,231 +0,0 @@
-<template>
-  <div class="overflow-hidden full-height" v-bind="$attrs">
-    <div class="element-with-wave"></div>
-  </div>
-</template>
-<style lang="scss" scoped>
-@use "sass:map";
-@use "src/css/quasar.variables.scss";
-
-.element-with-wave {
-  position: relative;
-  background: rgba(map.get($colors-dark, "primary"), 1) !important;
-  margin-top: 60dvh;
-  width: 100%;
-  height: 100dvh;
-  transform: translateZ(0);
-}
-
-.element-with-wave::before {
-  content: "";
-  position: absolute;
-  top: -240px;
-  left: 0;
-  width: 100%;
-  height: 240px;
-  background-color: rgba(map.get($colors-dark, "primary"), 1) !important;
-  will-change: clip-path;
-  animation: organic-swell 20s ease-in-out infinite alternate;
-  clip-path: polygon(
-    0% 100%,
-    0% 50%,
-    5% 45%,
-    10% 55%,
-    18% 40%,
-    25% 60%,
-    33% 45%,
-    42% 60%,
-    50% 40%,
-    58% 60%,
-    67% 45%,
-    75% 60%,
-    82% 40%,
-    91% 60%,
-    100% 50%,
-    100% 100%
-  );
-}
-
-@keyframes organic-swell {
-  0% {
-    clip-path: polygon(
-      0% 100%,
-      0% 50%,
-      5% 45%,
-      10% 55%,
-      18% 40%,
-      25% 60%,
-      33% 45%,
-      42% 60%,
-      50% 40%,
-      58% 60%,
-      67% 45%,
-      75% 60%,
-      82% 40%,
-      91% 60%,
-      100% 50%,
-      100% 100%
-    );
-  }
-  12.5% {
-    clip-path: polygon(
-      0% 100%,
-      0% 10%,
-      5% 20%,
-      10% 15%,
-      18% 30%,
-      25% 40%,
-      33% 35%,
-      42% 50%,
-      50% 55%,
-      58% 65%,
-      67% 60%,
-      75% 70%,
-      82% 65%,
-      91% 75%,
-      100% 60%,
-      100% 100%
-    );
-  }
-  25% {
-    clip-path: polygon(
-      0% 100%,
-      0% 40%,
-      5% 30%,
-      10% 50%,
-      18% 20%,
-      25% 30%,
-      33% 15%,
-      42% 40%,
-      50% 50%,
-      58% 60%,
-      67% 55%,
-      75% 65%,
-      82% 60%,
-      91% 70%,
-      100% 55%,
-      100% 100%
-    );
-  }
-  37.5% {
-    clip-path: polygon(
-      0% 100%,
-      0% 30%,
-      5% 25%,
-      10% 35%,
-      18% 20%,
-      25% 25%,
-      33% 20%,
-      42% 30%,
-      50% 20%,
-      58% 35%,
-      67% 25%,
-      75% 30%,
-      82% 20%,
-      91% 35%,
-      100% 30%,
-      100% 100%
-    );
-  }
-  50% {
-    clip-path: polygon(
-      0% 100%,
-      0% 60%,
-      5% 70%,
-      10% 60%,
-      18% 50%,
-      25% 40%,
-      33% 30%,
-      42% 10%,
-      50% 20%,
-      58% 30%,
-      67% 40%,
-      75% 50%,
-      82% 60%,
-      91% 70%,
-      100% 60%,
-      100% 100%
-    );
-  }
-  62.5% {
-    clip-path: polygon(
-      0% 100%,
-      0% 80%,
-      5% 75%,
-      10% 85%,
-      18% 70%,
-      25% 80%,
-      33% 65%,
-      42% 75%,
-      50% 60%,
-      58% 50%,
-      67% 35%,
-      75% 25%,
-      82% 40%,
-      91% 20%,
-      100% 30%,
-      100% 100%
-    );
-  }
-  75% {
-    clip-path: polygon(
-      0% 100%,
-      0% 70%,
-      5% 85%,
-      10% 75%,
-      18% 90%,
-      25% 80%,
-      33% 85%,
-      42% 70%,
-      50% 80%,
-      58% 75%,
-      67% 85%,
-      75% 80%,
-      82% 90%,
-      91% 75%,
-      100% 80%,
-      100% 100%
-    );
-  }
-  87.5% {
-    clip-path: polygon(
-      0% 100%,
-      0% 55%,
-      5% 50%,
-      10% 55%,
-      18% 50%,
-      25% 55%,
-      33% 50%,
-      42% 55%,
-      50% 50%,
-      58% 55%,
-      67% 50%,
-      75% 55%,
-      82% 50%,
-      91% 55%,
-      100% 50%,
-      100% 100%
-    );
-  }
-  100% {
-    clip-path: polygon(
-      0% 100%,
-      0% 45%,
-      5% 40%,
-      10% 50%,
-      18% 35%,
-      25% 55%,
-      33% 40%,
-      42% 55%,
-      50% 35%,
-      58% 55%,
-      67% 40%,
-      75% 55%,
-      82% 35%,
-      91% 55%,
-      100% 45%,
-      100% 100%
-    );
-  }
-}
-</style>

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor