Skip to content

Commit

Permalink
Created a password tooltip component
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedy00 committed Oct 19, 2023
1 parent 5e78953 commit a2fdd60
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 3 deletions.
11 changes: 10 additions & 1 deletion frontend/components/form/FormTextField.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<template>
<div
class="flex items-center pl-[12px] pr-[10px] py-2 max-h-[40px] space-x-2 text-left border rounded select-none border-light-interactive dark:border-dark-interactive text-light-special-text dark:text-dark-special-text"
:class="{
'border-red-600': error,
}"
>
<input
@input="updateValue"
@blur="emit('blured')"
@focus="emit('focused')"
:id="uuid"
class="w-full h-5 bg-transparent outline-none placeholder:text-light-special-text dark:placeholder:text-dark-special-text"
:value="modelValue"
Expand Down Expand Up @@ -33,19 +38,23 @@ export interface Props {
inputType?: string;
isIconVisible?: boolean;
icons?: string[];
error?: boolean;
}
// FIXME: Type Issue
// @ts-ignore
const props = withDefaults(defineProps<Props>(), {
placeholder: "",
modelValue: "",
inputType: "text",
isIconVisible: false,
error: false,
});
const emit = defineEmits(["update:modelValue"]);
const { updateValue } = useFormInput({ value: props?.modelValue }, emit, false);
const uuid = uuidv4();
const refInputType = ref(props?.inputType);
const refInputType = ref<string | undefined>(props?.inputType);
const changeInputType = () => {
refInputType.value = refInputType.value === "password" ? "text" : "password";
};
Expand Down
17 changes: 17 additions & 0 deletions frontend/components/tooltip/TooltipPassword.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<Tooltip class="transition ease-in-out delay-150 min-w-[200px] md:min-w-[300px] py-2 bg-[#e3e3e3] z-20">
<span class="mb-4 px-2">{{ $t("pages.auth.sign-up.index.password-rules-message") }}</span>
<div v-for="(rule, index) in rules" :key="`password-rule-${index}`" class="flex items-center space-x-2 px-2">
<Icon :name="rule.isValid ? 'bi:check-circle-fill' : 'bi:x-circle-fill'" size="1.1em" :style="{color: rule.isValid ? '#198754' : '#BA3D3B'}" />
<span class="truncate">{{ $t(`pages.auth.sign-up.index.${rule.message}`) }}</span>
</div>
</Tooltip>
</template>
<script setup lang="ts">
import { PasswordRules } from "~/types/password-rules";
defineProps<{
rules: PasswordRules[]
}>();
</script>
10 changes: 10 additions & 0 deletions frontend/composables/usePasswordRules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function usePasswordRules() {
const ruleFunctions = {
"number-of-chars": (value: string) => value.length >= 12,
"capital-letters": (value: string) => /[A-Z]/.test(value),
"lower-case-letters": (value: string) => /[a-z]/.test(value),
"contains-numbers": (value: string) => /[0-9]/.test(value),
"contains-special-chars": (value: string) => /[^a-zA-Z0-9]/.test(value)
};
return { ruleFunctions }
}
8 changes: 7 additions & 1 deletion frontend/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,13 @@
"have-account": "Already have an account?",
"i-am-human": "I am human",
"read-terms-of-service": "I have read and agree to the",
"terms-of-service": "terms of service"
"terms-of-service": "terms of service",
"password-rules-message": "For your security and that of the community, please choose a password that you've never used before",
"number-of-chars": "At least 12 characters",
"capital-letters": "Contains capital letters",
"lower-case-letters": "Contains lower case letters",
"contains-numbers": "Contains numbers",
"contains-special-chars": "Contains special characters(!#$^*)"
}
}
},
Expand Down
32 changes: 31 additions & 1 deletion frontend/pages/auth/sign-up.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@
<div>
<FormTextField
@update:model-value="passwordValue = $event"
@input="checkRules"
@blured="isBlured = true; isFocused = false"
@focused="isFocused = true; isBlured = false"
:placeholder="$t('pages.auth.sign-up.index.enter-password')"
:is-icon-visible="true"
input-type="password"
:model-value="passwordValue"
:icons="['bi:info-circle', 'bi:eye-fill']"
:error="!isAllRulesValid && isBlured"
/>
</div>
<TooltipPassword
v-if="!!passwordValue?.length && !isAllRulesValid && (!isBlured || isFocused)"
:rules="rules"
/>
<div>
<FormTextField
@update:model-value="confirmPasswordValue = $event"
Expand Down Expand Up @@ -63,7 +71,6 @@
:label="$t('pages.auth.sign-up.index.read-terms-of-service')"
:modelValue="hasRed"
value="yes"
:error="hasRedError"
/>

<NuxtLink
Expand All @@ -84,6 +91,9 @@
</template>

<script setup lang="ts">
import usePasswordRules from "~/composables/usePasswordRules";
import { PasswordRules } from "~/types/password-rules";
definePageMeta({
layout: "auth",
});
Expand All @@ -92,6 +102,8 @@ const userNameValue = ref("");
const passwordValue = ref("");
const confirmPasswordValue = ref("");
const hasRed = ref(false);
const isBlured = ref(false)
const isFocused = ref(false)
const isPasswordMatch = computed(() => {
if (passwordValue.value === "" || confirmPasswordValue.value === "") {
Expand All @@ -100,5 +112,23 @@ const isPasswordMatch = computed(() => {
return passwordValue.value === confirmPasswordValue.value;
});
const rules = ref<PasswordRules[]>(passwordRules)
const { ruleFunctions } = usePasswordRules()
const checkRules = (value: { target: { value: string } }): void => {
const actualValue = value.target.value;
rules.value.forEach(rule => {
if (ruleFunctions[rule.message]) {
rule.isValid = ruleFunctions[rule.message](actualValue);
}
});
};
// Checks the rules to make the tooltip invisible when the rules are valid
const isAllRulesValid = computed(() => {
return rules.value.every(rule => rule.isValid)
})
const signUp = () => {};
</script>
4 changes: 4 additions & 0 deletions frontend/types/password-rules.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PasswordRules {
isValid: boolean;
message: string;
}
22 changes: 22 additions & 0 deletions frontend/utils/passwordRules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const passwordRules = [
{
isValid: false,
message: "number-of-chars"
},
{
isValid: false,
message: "capital-letters"
},
{
isValid: false,
message: "lower-case-letters"
},
{
isValid: false,
message: "contains-numbers"
},
{
isValid: false,
message: "contains-special-chars"
}
]

0 comments on commit a2fdd60

Please sign in to comment.