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_LOGIN_DETAIL = MAIN_DOMAIN + "/api/admin/admin-details"
export const ADMIN_GET_SITE_SETTING = MAIN_DOMAIN + "/api/admin/site-settings" 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", "Providers": "Providers",
"Labs": "Labs", "Labs": "Labs",
"Medicines": "Medicines", "Medicines": "Medicines",
"Profile": "Profile",
"Security": "Security",
"Site Setting": "Site Setting",
"5": "5", "5": "5",
"10": "10", "10": "10",
"20": "20", "20": "20",

View File

@ -3,6 +3,8 @@ import { createStore } from 'vuex';
import { import {
ADMIN_GET_SITE_SETTING, ADMIN_GET_SITE_SETTING,
ADMIN_LOGIN_DETAIL, ADMIN_LOGIN_DETAIL,
ADMIN_UPDATE_PASSWORD,
ADMIN_UPDATE_SITE_SETTING,
APPOINTMENT_DETAILS_API, APPOINTMENT_DETAILS_API,
LABS_DELETE_API, LABS_DELETE_API,
LABS_LIST_API, LABS_LIST_API,
@ -583,6 +585,53 @@ export default createStore({
console.error('Error:', error); 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: { getters: {
getIsLoading(state){ getIsLoading(state){

View File

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

View File

@ -1,31 +1,25 @@
<script setup> <script setup>
import avatar1 from '@images/avatars/avatar-1.png';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
const store = useStore(); const store = useStore();
const accountData = { const accountData = {
avatarImg: avatar1,
favicon:'', favicon:'',
firstName: 'john', domain_name: '',
lastName: 'Doe', footer_text: '',
email: 'johnDoe@example.com', header_title: '',
org: 'ThemeSelection', logo: '',
phone: '+1 (917) 543-9876', plan_description: '',
address: '123 Main St, New York, NY 10001', plan_main_title:'',
state: 'New York', id:'',
zip: '10001',
country: ['USA'],
language: ['English'],
timezone: '(GMT-11:00) International Date Line West',
currency: 'USD',
} }
const refVForm = ref(null)
const refInputEl = ref() const refInputEl = ref()
const refInputElFavicon = ref() const refInputElFavicon = ref()
const isConfirmDialogOpen = ref(false) const isConfirmDialogOpen = ref(false)
const accountDataLocal = ref(structuredClone(accountData)) const accountDataLocal = ref(structuredClone(accountData))
const isAccountDeactivated = ref(false) const isAccountDeactivated = ref(false)
const validateAccountDeactivation = [v => !!v || 'Please confirm account deactivation'] const validateAccountDeactivation = [v => !!v || 'Please confirm account deactivation']
const imageBase64 = ref(null)
const faviconBase64 = ref(null)
const resetForm = () => { const resetForm = () => {
accountDataLocal.value = structuredClone(accountData) accountDataLocal.value = structuredClone(accountData)
} }
@ -38,8 +32,11 @@ const changeAvatar = file => {
if (files && files.length) { if (files && files.length) {
fileReader.readAsDataURL(files[0]) fileReader.readAsDataURL(files[0])
fileReader.onload = () => { fileReader.onload = () => {
if (typeof fileReader.result === 'string') if (typeof fileReader.result === 'string') {
accountDataLocal.value.avatarImg = fileReader.result accountDataLocal.value.logo = fileReader.result
}
imageBase64.value = fileReader.result.split(',')[1]
} }
} }
} }
@ -49,18 +46,17 @@ const changeAvatarFavicon = file => {
if (files && files.length) { if (files && files.length) {
fileReader.readAsDataURL(files[0]) fileReader.readAsDataURL(files[0])
fileReader.onload = () => { fileReader.onload = () => {
if (typeof fileReader.result === 'string') if (typeof fileReader.result === 'string') {
accountDataLocal.value.favicon = fileReader.result accountDataLocal.value.favicon = fileReader.result
} }
faviconBase64.value = fileReader.result.split(',')[1]
}
} }
} }
onMounted(async () => {
await store.dispatch('adminDetial');
});
// reset avatar image // reset avatar image
const resetAvatar = () => { const resetAvatar = () => {
accountDataLocal.value.avatarImg = accountData.avatarImg accountDataLocal.value.logo = accountData.logo
} }
const resetAvatarFavicon = () => { const resetAvatarFavicon = () => {
accountDataLocal.value.favicon = accountData.favicon accountDataLocal.value.favicon = accountData.favicon
@ -123,12 +119,63 @@ const currencies = [
] ]
onMounted(async () => { 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> </script>
<template> <template>
<VRow> <VRow>
<VForm ref="refVForm" >
<VCol cols="12"> <VCol cols="12">
<VCard> <VCard>
<VCardText> <VCardText>
@ -138,7 +185,7 @@ onMounted(async () => {
rounded rounded
size="100" size="100"
class="me-6" class="me-6"
:image="accountDataLocal.avatarImg" :image="accountDataLocal.logo"
/> />
<!-- 👉 Upload Photo --> <!-- 👉 Upload Photo -->
@ -158,7 +205,7 @@ onMounted(async () => {
ref="refInputEl" ref="refInputEl"
type="file" type="file"
name="file" name="file"
accept=".jpeg,.png,.jpg,GIF" accept=".jpeg,.png,.webp,.jpg,GIF"
hidden hidden
@input="changeAvatar" @input="changeAvatar"
> >
@ -207,7 +254,7 @@ onMounted(async () => {
ref="refInputElFavicon" ref="refInputElFavicon"
type="file" type="file"
name="file" name="file"
accept=".jpeg,.png,.jpg,GIF" accept=".jpeg,.png,.webp,.jpg,GIF"
hidden hidden
@input="changeAvatarFavicon" @input="changeAvatarFavicon"
> >
@ -230,7 +277,7 @@ onMounted(async () => {
</form> </form>
</div> </div>
<!-- 👉 Form --> <!-- 👉 Form -->
<VForm>
<VRow> <VRow>
<!-- 👉 First Name --> <!-- 👉 First Name -->
<VCol <VCol
@ -241,6 +288,7 @@ onMounted(async () => {
v-model="accountDataLocal.plan_main_title" v-model="accountDataLocal.plan_main_title"
placeholder="Plan Main Page Title" placeholder="Plan Main Page Title"
label="Plan Page Main Title" label="Plan Page Main Title"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
@ -253,6 +301,7 @@ onMounted(async () => {
v-model="accountDataLocal.plan_description" v-model="accountDataLocal.plan_description"
placeholder="Doe" placeholder="Doe"
label="Plan Description" label="Plan Description"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
<!-- 👉 Header Title --> <!-- 👉 Header Title -->
@ -265,6 +314,7 @@ onMounted(async () => {
v-model="accountDataLocal.header_title" v-model="accountDataLocal.header_title"
label="Header Title" label="Header Title"
placeholder="Header Title" placeholder="Header Title"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
@ -276,6 +326,7 @@ onMounted(async () => {
v-model="accountDataLocal.domain_name" v-model="accountDataLocal.domain_name"
label="Domain Name" label="Domain Name"
placeholder="Domain Name" placeholder="Domain Name"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
<!-- 👉 Email --> <!-- 👉 Email -->
@ -287,6 +338,7 @@ onMounted(async () => {
v-model="accountDataLocal.footer_text" v-model="accountDataLocal.footer_text"
label="Footer Text" label="Footer Text"
placeholder="Footer Text" placeholder="Footer Text"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
@ -404,7 +456,7 @@ onMounted(async () => {
cols="12" cols="12"
class="d-flex flex-wrap gap-4" class="d-flex flex-wrap gap-4"
> >
<VBtn>Save changes</VBtn> <VBtn @click="save">Save changes</VBtn>
<VBtn <VBtn
color="secondary" color="secondary"
@ -416,11 +468,11 @@ onMounted(async () => {
</VBtn> </VBtn>
</VCol> </VCol>
</VRow> </VRow>
</VForm>
</VCardText> </VCardText>
</VCard> </VCard>
</VCol> </VCol>
</VForm>
<VCol cols="12" style="display: none;"> <VCol cols="12" style="display: none;">
<!-- 👉 Delete Account --> <!-- 👉 Delete Account -->
<VCard title="Delete Account"> <VCard title="Delete Account">