This commit is contained in:
nasir@endelospay.com 2024-06-06 04:00:35 +05:00
parent 0f9c7cec8e
commit 0d229f62f1
5 changed files with 418 additions and 285 deletions

View File

@ -34,4 +34,5 @@ export const PROVIDER_MEETING_LIST_API = MAIN_DOMAIN + "/api/admin/get-meeting-h
export const ADMIN_LOGIN_DETAIL = MAIN_DOMAIN + "/api/admin/admin-details"
export const ADMIN_GET_SITE_SETTING = MAIN_DOMAIN + "/api/admin/site-settings"
export const ADMIN_UPDATE_SITE_SETTING = MAIN_DOMAIN + "/api/admin/update-settings/"
export const ADMIN_UPDATE_PASSWORD = MAIN_DOMAIN + "/api/admin/password-update"

View File

@ -160,6 +160,9 @@
"Providers": "Providers",
"Labs": "Labs",
"Medicines": "Medicines",
"Profile": "Profile",
"Security": "Security",
"Site Setting": "Site Setting",
"5": "5",
"10": "10",
"20": "20",

View File

@ -3,6 +3,8 @@ import { createStore } from 'vuex';
import {
ADMIN_GET_SITE_SETTING,
ADMIN_LOGIN_DETAIL,
ADMIN_UPDATE_PASSWORD,
ADMIN_UPDATE_SITE_SETTING,
APPOINTMENT_DETAILS_API,
LABS_DELETE_API,
LABS_LIST_API,
@ -583,6 +585,53 @@ export default createStore({
console.error('Error:', error);
});
},
async siteSettingUpdate({ commit }, payload) {
commit('setLoading', true)
await axios.post(ADMIN_UPDATE_SITE_SETTING+payload.id, {
plan_main_title: payload.plan_main_title,
plan_description: payload.plan_description,
header_title: payload.header_title,
footer_text: payload.footer_text,
domain_name: payload.domain_name,
logo:payload.logo,
favicon:payload.favicon//imageBase64.value
}, {
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${localStorage.getItem('admin_access_token')}`,
}
}) .then(response => {
commit('setLoading', false)
console.log('Response:', response.data);
})
.catch(error => {
commit('setLoading', false)
console.error('Error:', error);
});
},
async adminPasswordUpadate({ commit }, payload) {
commit('setLoading', true)
await axios.post(ADMIN_UPDATE_PASSWORD, {
password: payload.password,
new_password : payload.new_password ,
confirm_password : payload.confirm_password ,
}, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('admin_access_token')}`,
}
}) .then(response => {
commit('setLoading', false)
console.log('Response:', response.data);
})
.catch(error => {
commit('setLoading', false)
console.error('Error:', error);
});
},
},
getters: {
getIsLoading(state){

View File

@ -1,14 +1,16 @@
<script setup>
import sittingGirlWithLaptopDark from '@images/illustrations/sitting-girl-with-laptop-dark.png';
import sittingGirlWithLaptopLight from '@images/illustrations/sitting-girl-with-laptop-light.png';
import { useStore } from 'vuex';
const store = useStore();
const refVForm = ref(null)
const isCurrentPasswordVisible = ref(false)
const isNewPasswordVisible = ref(false)
const isConfirmPasswordVisible = ref(false)
const currentPassword = ref('')
const newPassword = ref('')
const confirmPassword = ref('')
const passwordConfirmationTarget = computed(() => newPassword.value);
const passwordRequirements = [
'Minimum 8 characters long - the more, the better',
'At least one lowercase character',
@ -117,7 +119,28 @@ const recentDevices = [
},
},
]
const save = async () => {
const { valid } = await refVForm.value.validate()
console.log(valid)
if (valid) {
try {
await store.dispatch('adminPasswordUpadate',{
password: currentPassword.value,
new_password : newPassword.value,
confirm_password : confirmPassword.value,
})
} catch (error) {
console.error(error)
}
currentPassword.value = null
newPassword.value = null
confirmPassword.value = null
}
}
const sittingGirlImg = useGenerateImageVariant(sittingGirlWithLaptopLight, sittingGirlWithLaptopDark)
const isOneTimePasswordDialogVisible = ref(false)
</script>
@ -130,7 +153,7 @@ const isOneTimePasswordDialogVisible = ref(false)
<VCardItem class="pb-6">
<VCardTitle>Change Password</VCardTitle>
</VCardItem>
<VForm>
<VForm ref="refVForm">
<VCardText class="pt-0">
<!-- 👉 Current Password -->
<VRow>
@ -147,6 +170,7 @@ const isOneTimePasswordDialogVisible = ref(false)
label="Current Password"
placeholder="············"
@click:append-inner="isCurrentPasswordVisible = !isCurrentPasswordVisible"
/>
</VCol>
</VRow>
@ -166,6 +190,8 @@ const isOneTimePasswordDialogVisible = ref(false)
autocomplete="on"
placeholder="············"
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
:rules="[passwordValidator]"
/>
</VCol>
@ -173,6 +199,7 @@ const isOneTimePasswordDialogVisible = ref(false)
cols="12"
md="6"
>
<!-- 👉 confirm password -->
<VTextField
v-model="confirmPassword"
@ -182,6 +209,7 @@ const isOneTimePasswordDialogVisible = ref(false)
label="Confirm New Password"
placeholder="············"
@click:append-inner="isConfirmPasswordVisible = !isConfirmPasswordVisible"
:rules="[value => confirmedValidator(value, passwordConfirmationTarget)]"
/>
</VCol>
</VRow>
@ -214,7 +242,7 @@ const isOneTimePasswordDialogVisible = ref(false)
<!-- 👉 Action Buttons -->
<div class="d-flex flex-wrap gap-4">
<VBtn>Save changes</VBtn>
<VBtn @click="save">Save changes</VBtn>
<VBtn
type="reset"
@ -363,7 +391,7 @@ const isOneTimePasswordDialogVisible = ref(false)
</VCol>
<!-- SECTION Recent Devices -->
<VCol cols="12">
<VCol cols="12" style="display: none;">
<!-- 👉 Table -->
<VCard
title="Recent Devices"
@ -396,6 +424,6 @@ const isOneTimePasswordDialogVisible = ref(false)
</VRow>
<!-- SECTION Enable One time password -->
<TwoFactorAuthDialog v-model:isDialogVisible="isOneTimePasswordDialogVisible" />
<TwoFactorAuthDialog v-model:isDialogVisible="isOneTimePasswordDialogVisible" style="display: none;"/>
<!-- !SECTION -->
</template>

View File

@ -1,31 +1,25 @@
<script setup>
import avatar1 from '@images/avatars/avatar-1.png';
import { useStore } from 'vuex';
const store = useStore();
const accountData = {
avatarImg: avatar1,
favicon:'',
firstName: 'john',
lastName: 'Doe',
email: 'johnDoe@example.com',
org: 'ThemeSelection',
phone: '+1 (917) 543-9876',
address: '123 Main St, New York, NY 10001',
state: 'New York',
zip: '10001',
country: ['USA'],
language: ['English'],
timezone: '(GMT-11:00) International Date Line West',
currency: 'USD',
domain_name: '',
footer_text: '',
header_title: '',
logo: '',
plan_description: '',
plan_main_title:'',
id:'',
}
const refVForm = ref(null)
const refInputEl = ref()
const refInputElFavicon = ref()
const isConfirmDialogOpen = ref(false)
const accountDataLocal = ref(structuredClone(accountData))
const isAccountDeactivated = ref(false)
const validateAccountDeactivation = [v => !!v || 'Please confirm account deactivation']
const imageBase64 = ref(null)
const faviconBase64 = ref(null)
const resetForm = () => {
accountDataLocal.value = structuredClone(accountData)
}
@ -38,8 +32,11 @@ const changeAvatar = file => {
if (files && files.length) {
fileReader.readAsDataURL(files[0])
fileReader.onload = () => {
if (typeof fileReader.result === 'string')
accountDataLocal.value.avatarImg = fileReader.result
if (typeof fileReader.result === 'string') {
accountDataLocal.value.logo = fileReader.result
}
imageBase64.value = fileReader.result.split(',')[1]
}
}
}
@ -49,18 +46,17 @@ const changeAvatarFavicon = file => {
if (files && files.length) {
fileReader.readAsDataURL(files[0])
fileReader.onload = () => {
if (typeof fileReader.result === 'string')
accountDataLocal.value.favicon = fileReader.result
if (typeof fileReader.result === 'string') {
accountDataLocal.value.favicon = fileReader.result
}
faviconBase64.value = fileReader.result.split(',')[1]
}
}
}
onMounted(async () => {
await store.dispatch('adminDetial');
});
// reset avatar image
const resetAvatar = () => {
accountDataLocal.value.avatarImg = accountData.avatarImg
accountDataLocal.value.logo = accountData.logo
}
const resetAvatarFavicon = () => {
accountDataLocal.value.favicon = accountData.favicon
@ -122,72 +118,74 @@ const currencies = [
'INR',
]
onMounted(async () => {
await store.dispatch('siteSetting');
await store.dispatch('siteSetting');
let list = await store.getters.getSiteSetting
console.log('list',list)
accountDataLocal.value.logo = list.logo
accountDataLocal.value.favicon = list.favicon
accountDataLocal.value.plan_main_title = list.plan_main_title
accountDataLocal.value.plan_description = list.plan_description
accountDataLocal.value.header_title = list.header_title
accountDataLocal.value.footer_text = list.footer_text
accountDataLocal.value.domain_name = list.domain_name
accountDataLocal.value.id = list.id
});
const convertImageToBase64 = (event) => {
const file = event.target.files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
imageBase64.value = reader.result.split(',')[1]
}
}
const save = async () => {
const { valid } = await refVForm.value.validate()
console.log(valid)
if (valid) {
try {
console.log(imageBase64.value)
await store.dispatch('siteSettingUpdate',{
plan_main_title: accountDataLocal.value.plan_main_title,
plan_description: accountDataLocal.value.plan_description,
header_title: accountDataLocal.value.header_title,
footer_text: accountDataLocal.value.footer_text,
domain_name: accountDataLocal.value.domain_name,
id: accountDataLocal.value.id,
logo:imageBase64.value, //ecelData,
favicon:faviconBase64.value//imageBase64.value
})
} catch (error) {
console.error(error)
}
await store.dispatch('siteSetting');
let list = await store.getters.getSiteSetting
console.log('list',list)
accountDataLocal.value.logo = list.logo
accountDataLocal.value.favicon = list.favicon
accountDataLocal.value.plan_main_title = list.plan_main_title
accountDataLocal.value.plan_description = list.plan_description
accountDataLocal.value.header_title = list.header_title
accountDataLocal.value.footer_text = list.footer_text
accountDataLocal.value.domain_name = list.domain_name
}
}
</script>
<template>
<VRow>
<VCol cols="12">
<VCard>
<VCardText>
<div class="d-flex mb-10">
<!-- 👉 Avatar -->
<VAvatar
rounded
size="100"
class="me-6"
:image="accountDataLocal.avatarImg"
/>
<!-- 👉 Upload Photo -->
<form class="d-flex flex-column justify-center gap-4">
<div class="d-flex flex-wrap gap-4">
<VBtn
color="primary"
@click="refInputEl?.click()"
>
<VIcon
icon="ri-upload-cloud-line"
class="d-sm-none"
/>
<span class="d-none d-sm-block">Upload new Logo</span>
</VBtn>
<input
ref="refInputEl"
type="file"
name="file"
accept=".jpeg,.png,.jpg,GIF"
hidden
@input="changeAvatar"
>
<VBtn
type="reset"
color="error"
variant="outlined"
@click="resetAvatar"
>
<span class="d-none d-sm-block">Reset</span>
<VIcon
icon="ri-refresh-line"
class="d-sm-none"
/>
</VBtn>
</div>
<p class="text-body-1 mb-0">
Allowed JPG, GIF ,webp or PNG. Max size of 800K
</p>
</form>
</div>
<div class="d-flex mb-10">
<VForm ref="refVForm" >
<VCol cols="12">
<VCard>
<VCardText>
<div class="d-flex mb-10">
<!-- 👉 Avatar -->
<VAvatar
rounded
size="100"
class="me-6"
:image="accountDataLocal.favicon"
:image="accountDataLocal.logo"
/>
<!-- 👉 Upload Photo -->
@ -195,27 +193,27 @@ onMounted(async () => {
<div class="d-flex flex-wrap gap-4">
<VBtn
color="primary"
@click="refInputElFavicon?.click()"
@click="refInputEl?.click()"
>
<VIcon
icon="ri-upload-cloud-line"
class="d-sm-none"
/>
<span class="d-none d-sm-block">Upload new Favicon</span>
<span class="d-none d-sm-block">Upload new Logo</span>
</VBtn>
<input
ref="refInputElFavicon"
ref="refInputEl"
type="file"
name="file"
accept=".jpeg,.png,.jpg,GIF"
accept=".jpeg,.png,.webp,.jpg,GIF"
hidden
@input="changeAvatarFavicon"
@input="changeAvatar"
>
<VBtn
type="reset"
color="error"
variant="outlined"
@click="resetAvatarFavicon"
@click="resetAvatar"
>
<span class="d-none d-sm-block">Reset</span>
<VIcon
@ -225,202 +223,256 @@ onMounted(async () => {
</VBtn>
</div>
<p class="text-body-1 mb-0">
Allowed JPG,webp, GIF or PNG. Max size of 800K
Allowed JPG, GIF ,webp or PNG. Max size of 800K
</p>
</form>
</div>
<!-- 👉 Form -->
<VForm>
<VRow>
<!-- 👉 First Name -->
<VCol
md="6"
cols="12"
>
<VTextField
v-model="accountDataLocal.plan_main_title"
placeholder="Plan Main Page Title"
label="Plan Page Main Title"
</div>
<div class="d-flex mb-10">
<!-- 👉 Avatar -->
<VAvatar
rounded
size="100"
class="me-6"
:image="accountDataLocal.favicon"
/>
</VCol>
<!-- 👉 Last Name -->
<VCol
md="6"
cols="12"
>
<VTextField
v-model="accountDataLocal.plan_description"
placeholder="Doe"
label="Plan Description"
/>
</VCol>
<!-- 👉 Header Title -->
<VCol
cols="12"
md="6"
>
<VTextField
v-model="accountDataLocal.header_title"
label="Header Title"
placeholder="Header Title"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="accountDataLocal.domain_name"
label="Domain Name"
placeholder="Domain Name"
/>
</VCol>
<!-- 👉 Email -->
<VCol
cols="12"
md="6"
>
<VTextarea
v-model="accountDataLocal.footer_text"
label="Footer Text"
placeholder="Footer Text"
/>
</VCol>
<!-- 👉 Phone -->
<!-- 👉 Address -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.address"
label="Address"
placeholder="123 Main St, New York, NY 10001"
/>
</VCol>
<!-- 👉 State -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.state"
label="State"
placeholder="New York"
/>
</VCol>
<!-- 👉 Zip Code -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.zip"
label="Zip Code"
placeholder="10001"
/>
</VCol>
<!-- 👉 Country -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.country"
multiple
chips
closable-chips
label="Country"
:items="['USA', 'Canada', 'UK', 'India', 'Australia']"
placeholder="Select Country"
/>
</VCol>
<!-- 👉 Language -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.language"
label="Language"
multiple
chips
closable-chips
placeholder="Select Language"
:items="['English', 'Spanish', 'Arabic', 'Hindi', 'Urdu']"
/>
</VCol>
<!-- 👉 Timezone -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.timezone"
label="Timezone"
placeholder="Select Timezone"
:items="timezones"
:menu-props="{ maxHeight: 200 }"
/>
</VCol>
<!-- 👉 Currency -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.currency"
label="Currency"
placeholder="Select Currency"
:items="currencies"
:menu-props="{ maxHeight: 200 }"
/>
</VCol>
<!-- 👉 Form Actions -->
<VCol
cols="12"
class="d-flex flex-wrap gap-4"
>
<VBtn>Save changes</VBtn>
<VBtn
color="secondary"
variant="outlined"
type="reset"
@click.prevent="resetForm"
<!-- 👉 Upload Photo -->
<form class="d-flex flex-column justify-center gap-4">
<div class="d-flex flex-wrap gap-4">
<VBtn
color="primary"
@click="refInputElFavicon?.click()"
>
<VIcon
icon="ri-upload-cloud-line"
class="d-sm-none"
/>
<span class="d-none d-sm-block">Upload new Favicon</span>
</VBtn>
<input
ref="refInputElFavicon"
type="file"
name="file"
accept=".jpeg,.png,.webp,.jpg,GIF"
hidden
@input="changeAvatarFavicon"
>
<VBtn
type="reset"
color="error"
variant="outlined"
@click="resetAvatarFavicon"
>
<span class="d-none d-sm-block">Reset</span>
<VIcon
icon="ri-refresh-line"
class="d-sm-none"
/>
</VBtn>
</div>
<p class="text-body-1 mb-0">
Allowed JPG,webp, GIF or PNG. Max size of 800K
</p>
</form>
</div>
<!-- 👉 Form -->
<VRow>
<!-- 👉 First Name -->
<VCol
md="6"
cols="12"
>
Reset
</VBtn>
</VCol>
</VRow>
</VForm>
</VCardText>
</VCard>
</VCol>
<VTextField
v-model="accountDataLocal.plan_main_title"
placeholder="Plan Main Page Title"
label="Plan Page Main Title"
:rules="[requiredValidator]"
/>
</VCol>
<!-- 👉 Last Name -->
<VCol
md="6"
cols="12"
>
<VTextField
v-model="accountDataLocal.plan_description"
placeholder="Doe"
label="Plan Description"
:rules="[requiredValidator]"
/>
</VCol>
<!-- 👉 Header Title -->
<VCol
cols="12"
md="6"
>
<VTextField
v-model="accountDataLocal.header_title"
label="Header Title"
placeholder="Header Title"
:rules="[requiredValidator]"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="accountDataLocal.domain_name"
label="Domain Name"
placeholder="Domain Name"
:rules="[requiredValidator]"
/>
</VCol>
<!-- 👉 Email -->
<VCol
cols="12"
md="6"
>
<VTextarea
v-model="accountDataLocal.footer_text"
label="Footer Text"
placeholder="Footer Text"
:rules="[requiredValidator]"
/>
</VCol>
<!-- 👉 Phone -->
<!-- 👉 Address -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.address"
label="Address"
placeholder="123 Main St, New York, NY 10001"
/>
</VCol>
<!-- 👉 State -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.state"
label="State"
placeholder="New York"
/>
</VCol>
<!-- 👉 Zip Code -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VTextField
v-model="accountDataLocal.zip"
label="Zip Code"
placeholder="10001"
/>
</VCol>
<!-- 👉 Country -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.country"
multiple
chips
closable-chips
label="Country"
:items="['USA', 'Canada', 'UK', 'India', 'Australia']"
placeholder="Select Country"
/>
</VCol>
<!-- 👉 Language -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.language"
label="Language"
multiple
chips
closable-chips
placeholder="Select Language"
:items="['English', 'Spanish', 'Arabic', 'Hindi', 'Urdu']"
/>
</VCol>
<!-- 👉 Timezone -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.timezone"
label="Timezone"
placeholder="Select Timezone"
:items="timezones"
:menu-props="{ maxHeight: 200 }"
/>
</VCol>
<!-- 👉 Currency -->
<VCol
cols="12"
md="6"
style="display: none;"
>
<VSelect
v-model="accountDataLocal.currency"
label="Currency"
placeholder="Select Currency"
:items="currencies"
:menu-props="{ maxHeight: 200 }"
/>
</VCol>
<!-- 👉 Form Actions -->
<VCol
cols="12"
class="d-flex flex-wrap gap-4"
>
<VBtn @click="save">Save changes</VBtn>
<VBtn
color="secondary"
variant="outlined"
type="reset"
@click.prevent="resetForm"
>
Reset
</VBtn>
</VCol>
</VRow>
</VCardText>
</VCard>
</VCol>
</VForm>
<VCol cols="12" style="display: none;">
<!-- 👉 Delete Account -->
<VCard title="Delete Account">