8 changed files with 309 additions and 0 deletions
@ -0,0 +1,56 @@ |
|||
<script setup lang="ts"> |
|||
import type { Recordable } from '@vben/types'; |
|||
|
|||
import type { VbenFormSchema } from '@vben-core/form-ui'; |
|||
|
|||
import { computed, reactive } from 'vue'; |
|||
|
|||
import { useVbenForm } from '@vben-core/form-ui'; |
|||
import { VbenButton } from '@vben-core/shadcn-ui'; |
|||
|
|||
interface Props { |
|||
formSchema?: VbenFormSchema[]; |
|||
} |
|||
|
|||
const props = withDefaults(defineProps<Props>(), { |
|||
formSchema: () => [], |
|||
}); |
|||
|
|||
const emit = defineEmits<{ |
|||
submit: [Recordable<any>]; |
|||
}>(); |
|||
|
|||
const [Form, formApi] = useVbenForm( |
|||
reactive({ |
|||
commonConfig: { |
|||
// 所有表单项 |
|||
componentProps: { |
|||
class: 'w-full', |
|||
}, |
|||
}, |
|||
layout: 'horizontal', |
|||
schema: computed(() => props.formSchema), |
|||
showDefaultActions: false, |
|||
}), |
|||
); |
|||
|
|||
async function handleSubmit() { |
|||
const { valid } = await formApi.validate(); |
|||
const values = await formApi.getValues(); |
|||
if (valid) { |
|||
emit('submit', values); |
|||
} |
|||
} |
|||
|
|||
defineExpose({ |
|||
getFormApi: () => formApi, |
|||
}); |
|||
</script> |
|||
<template> |
|||
<div @keydown.enter.prevent="handleSubmit"> |
|||
<Form /> |
|||
<VbenButton type="submit" class="mt-4" @click="handleSubmit"> |
|||
更新基本信息 |
|||
</VbenButton> |
|||
</div> |
|||
</template> |
|||
@ -0,0 +1,6 @@ |
|||
export { default as ProfileBaseSetting } from './base-setting.vue'; |
|||
export { default as ProfileNotificationSetting } from './notification-setting.vue'; |
|||
export { default as ProfilePasswordSetting } from './password-setting.vue'; |
|||
export { default as Profile } from './profile.vue'; |
|||
export { default as ProfileSecuritySetting } from './security-setting.vue'; |
|||
export type * from './types'; |
|||
@ -0,0 +1,53 @@ |
|||
<script setup lang="ts"> |
|||
import type { Recordable } from '@vben/types'; |
|||
|
|||
import type { SettingProps } from './types'; |
|||
|
|||
import { |
|||
Form, |
|||
FormControl, |
|||
FormDescription, |
|||
FormField, |
|||
FormItem, |
|||
FormLabel, |
|||
Switch, |
|||
} from '@vben-core/shadcn-ui'; |
|||
|
|||
withDefaults(defineProps<SettingProps>(), { |
|||
formSchema: () => [], |
|||
}); |
|||
|
|||
const emit = defineEmits<{ |
|||
change: [Recordable<any>]; |
|||
}>(); |
|||
|
|||
function handleChange(fieldName: string, value: boolean) { |
|||
emit('change', { fieldName, value }); |
|||
} |
|||
</script> |
|||
<template> |
|||
<Form class="space-y-8"> |
|||
<div class="space-y-4"> |
|||
<template v-for="item in formSchema" :key="item.fieldName"> |
|||
<FormField type="checkbox" :name="item.fieldName"> |
|||
<FormItem |
|||
class="flex flex-row items-center justify-between rounded-lg border p-4" |
|||
> |
|||
<div class="space-y-0.5"> |
|||
<FormLabel class="text-base"> {{ item.label }} </FormLabel> |
|||
<FormDescription> |
|||
{{ item.description }} |
|||
</FormDescription> |
|||
</div> |
|||
<FormControl> |
|||
<Switch |
|||
:model-value="item.value" |
|||
@update:model-value="handleChange(item.fieldName, $event)" |
|||
/> |
|||
</FormControl> |
|||
</FormItem> |
|||
</FormField> |
|||
</template> |
|||
</div> |
|||
</Form> |
|||
</template> |
|||
@ -0,0 +1,56 @@ |
|||
<script setup lang="ts"> |
|||
import type { Recordable } from '@vben/types'; |
|||
|
|||
import type { VbenFormSchema } from '@vben-core/form-ui'; |
|||
|
|||
import { computed, reactive } from 'vue'; |
|||
|
|||
import { useVbenForm } from '@vben-core/form-ui'; |
|||
import { VbenButton } from '@vben-core/shadcn-ui'; |
|||
|
|||
interface Props { |
|||
formSchema?: VbenFormSchema[]; |
|||
} |
|||
|
|||
const props = withDefaults(defineProps<Props>(), { |
|||
formSchema: () => [], |
|||
}); |
|||
|
|||
const emit = defineEmits<{ |
|||
submit: [Recordable<any>]; |
|||
}>(); |
|||
|
|||
const [Form, formApi] = useVbenForm( |
|||
reactive({ |
|||
commonConfig: { |
|||
// 所有表单项 |
|||
componentProps: { |
|||
class: 'w-full', |
|||
}, |
|||
}, |
|||
layout: 'horizontal', |
|||
schema: computed(() => props.formSchema), |
|||
showDefaultActions: false, |
|||
}), |
|||
); |
|||
|
|||
async function handleSubmit() { |
|||
const { valid } = await formApi.validate(); |
|||
const values = await formApi.getValues(); |
|||
if (valid) { |
|||
emit('submit', values); |
|||
} |
|||
} |
|||
|
|||
defineExpose({ |
|||
getFormApi: () => formApi, |
|||
}); |
|||
</script> |
|||
<template> |
|||
<div> |
|||
<Form /> |
|||
<VbenButton type="submit" class="mt-4" @click="handleSubmit"> |
|||
更新密码 |
|||
</VbenButton> |
|||
</div> |
|||
</template> |
|||
@ -0,0 +1,62 @@ |
|||
<script setup lang="ts"> |
|||
import type { Props } from './types'; |
|||
|
|||
import { preferences } from '@vben-core/preferences'; |
|||
import { |
|||
Card, |
|||
Separator, |
|||
Tabs, |
|||
TabsList, |
|||
TabsTrigger, |
|||
VbenAvatar, |
|||
} from '@vben-core/shadcn-ui'; |
|||
|
|||
import { Page } from '../../components'; |
|||
|
|||
defineOptions({ |
|||
name: 'ProfileUI', |
|||
}); |
|||
|
|||
withDefaults(defineProps<Props>(), { |
|||
title: '关于项目', |
|||
tabs: () => [], |
|||
}); |
|||
|
|||
const tabsValue = defineModel<string>('modelValue'); |
|||
</script> |
|||
<template> |
|||
<Page auto-content-height> |
|||
<div class="flex h-full w-full"> |
|||
<Card class="w-1/6 flex-none"> |
|||
<div class="mt-4 flex h-40 flex-col items-center justify-center gap-4"> |
|||
<VbenAvatar |
|||
:src="userInfo?.avatar ?? preferences.app.defaultAvatar" |
|||
class="size-20" |
|||
/> |
|||
<span class="text-lg font-semibold"> |
|||
{{ userInfo?.realName ?? '' }} |
|||
</span> |
|||
<span class="text-foreground/80 text-sm"> |
|||
{{ userInfo?.username ?? '' }} |
|||
</span> |
|||
</div> |
|||
<Separator class="my-4" /> |
|||
<Tabs v-model="tabsValue" orientation="vertical" class="m-4"> |
|||
<TabsList class="bg-card grid w-full grid-cols-1"> |
|||
<TabsTrigger |
|||
v-for="tab in tabs" |
|||
:key="tab.value" |
|||
:value="tab.value" |
|||
class="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground h-12 justify-start" |
|||
> |
|||
{{ tab.label }} |
|||
</TabsTrigger> |
|||
</TabsList> |
|||
</Tabs> |
|||
</Card> |
|||
<Card class="ml-4 w-5/6 flex-auto p-8"> |
|||
<slot name="content"></slot> |
|||
</Card> |
|||
</div> |
|||
</Page> |
|||
</template> |
|||
@ -0,0 +1,53 @@ |
|||
<script setup lang="ts"> |
|||
import type { Recordable } from '@vben/types'; |
|||
|
|||
import type { SettingProps } from './types'; |
|||
|
|||
import { |
|||
Form, |
|||
FormControl, |
|||
FormDescription, |
|||
FormField, |
|||
FormItem, |
|||
FormLabel, |
|||
Switch, |
|||
} from '@vben-core/shadcn-ui'; |
|||
|
|||
withDefaults(defineProps<SettingProps>(), { |
|||
formSchema: () => [], |
|||
}); |
|||
|
|||
const emit = defineEmits<{ |
|||
change: [Recordable<any>]; |
|||
}>(); |
|||
|
|||
function handleChange(fieldName: string, value: boolean) { |
|||
emit('change', { fieldName, value }); |
|||
} |
|||
</script> |
|||
<template> |
|||
<Form class="space-y-8"> |
|||
<div class="space-y-4"> |
|||
<template v-for="item in formSchema" :key="item.fieldName"> |
|||
<FormField type="checkbox" :name="item.fieldName"> |
|||
<FormItem |
|||
class="flex flex-row items-center justify-between rounded-lg border p-4" |
|||
> |
|||
<div class="space-y-0.5"> |
|||
<FormLabel class="text-base"> {{ item.label }} </FormLabel> |
|||
<FormDescription> |
|||
{{ item.description }} |
|||
</FormDescription> |
|||
</div> |
|||
<FormControl> |
|||
<Switch |
|||
:model-value="item.value" |
|||
@update:model-value="handleChange(item.fieldName, $event)" |
|||
/> |
|||
</FormControl> |
|||
</FormItem> |
|||
</FormField> |
|||
</template> |
|||
</div> |
|||
</Form> |
|||
</template> |
|||
@ -0,0 +1,22 @@ |
|||
import type { BasicUserInfo } from '@vben/types'; |
|||
|
|||
export interface Props { |
|||
title?: string; |
|||
userInfo: BasicUserInfo | null; |
|||
tabs: { |
|||
label: string; |
|||
value: string; |
|||
}[]; |
|||
} |
|||
|
|||
export interface FormSchemaItem { |
|||
description: string; |
|||
fieldName: string; |
|||
label: string; |
|||
name: string; |
|||
value: boolean; |
|||
} |
|||
|
|||
export interface SettingProps { |
|||
formSchema: FormSchemaItem[]; |
|||
} |
|||
Loading…
Reference in new issue