mirror of https://gitee.com/answerdev/answer.git
feat: personal setting notification change
This commit is contained in:
parent
41f7b1b9cd
commit
80df5193c5
|
@ -962,9 +962,16 @@ ui:
|
|||
placeholder: "City, Country"
|
||||
notification:
|
||||
heading: Notifications
|
||||
email:
|
||||
label: Email Notifications
|
||||
radio: "Answers to your questions, comments, and more"
|
||||
email: Email
|
||||
inbox:
|
||||
label: Inbox notifications
|
||||
description: Answers to your questions, comments, invites, and more.
|
||||
all_new_question:
|
||||
label: All new questions
|
||||
description: Get notified of all new questions. Up to 50 questions per week.
|
||||
all_new_question_for_following_tags:
|
||||
label: All new questions for following tags
|
||||
description: Get notified of new questions for following tags.
|
||||
account:
|
||||
heading: Account
|
||||
change_email_btn: Change email
|
||||
|
|
|
@ -57,7 +57,7 @@ export interface TagInfo extends TagBase {
|
|||
main_tag_slug_name?: string;
|
||||
excerpt?;
|
||||
}
|
||||
export interface QuestionParams extends ImgCodeReq{
|
||||
export interface QuestionParams extends ImgCodeReq {
|
||||
title: string;
|
||||
url_title?: string;
|
||||
content: string;
|
||||
|
@ -589,3 +589,13 @@ export interface UserOauthConnectorItem {
|
|||
binding: boolean;
|
||||
external_id: string;
|
||||
}
|
||||
|
||||
export interface NotificationConfigItem {
|
||||
enable: boolean;
|
||||
key: string;
|
||||
}
|
||||
export interface NotificationConfig {
|
||||
all_new_question: NotificationConfigItem[];
|
||||
all_new_question_for_following_tags: NotificationConfigItem[];
|
||||
inbox: NotificationConfigItem[];
|
||||
}
|
||||
|
|
|
@ -27,12 +27,13 @@ const Index: FC<Props> = ({
|
|||
index: number,
|
||||
) => {
|
||||
const { name, checked } = evt.currentTarget;
|
||||
const freshVal = checked ? enumValues?.[index] : '';
|
||||
enumValues[index] = checked;
|
||||
|
||||
const state = {
|
||||
...formData,
|
||||
[name]: {
|
||||
...formData[name],
|
||||
value: freshVal,
|
||||
value: enumValues,
|
||||
isInvalid: false,
|
||||
},
|
||||
};
|
||||
|
@ -51,7 +52,7 @@ const Index: FC<Props> = ({
|
|||
name={fieldName}
|
||||
id={`form-${String(item)}`}
|
||||
label={enumNames?.[index]}
|
||||
checked={(fieldObject?.value || '') === item}
|
||||
checked={fieldObject?.value?.[index] || false}
|
||||
feedback={fieldObject?.errorMsg}
|
||||
feedbackType="invalid"
|
||||
isInvalid={fieldObject?.isInvalid}
|
||||
|
|
|
@ -386,8 +386,13 @@ export const initFormData = (schema: JSONSchema): Type.FormDataType => {
|
|||
const props: JSONSchema['properties'] = schema?.properties || {};
|
||||
Object.keys(props).forEach((key) => {
|
||||
const prop = props[key];
|
||||
const defaultVal = prop?.default;
|
||||
|
||||
let defaultVal: any = '';
|
||||
if (Array.isArray(prop.default) && prop.enum && prop.enum.length > 0) {
|
||||
// for checkbox default values
|
||||
defaultVal = prop.enum;
|
||||
} else {
|
||||
defaultVal = prop?.default;
|
||||
}
|
||||
formData[key] = {
|
||||
value: defaultVal,
|
||||
isInvalid: false,
|
||||
|
|
|
@ -30,7 +30,7 @@ export interface JSONSchema {
|
|||
description?: string;
|
||||
enum?: Array<string | boolean | number>;
|
||||
enumNames?: string[];
|
||||
default?: string | boolean | number;
|
||||
default?: string | boolean | number | any[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import { usePageTags } from '@/hooks';
|
||||
import * as Type from '@/common/interface';
|
||||
import { FollowingTags, CustomSidebar } from '@/components';
|
||||
import { FollowingTags, CustomSidebar, Icon } from '@/components';
|
||||
import {
|
||||
useTagInfo,
|
||||
useFollow,
|
||||
|
@ -141,9 +141,16 @@ const Index: FC = () => {
|
|||
|
||||
<div className="box-ft">
|
||||
{tagInfo.is_follower ? (
|
||||
<Button variant="primary" onClick={() => toggleFollow()}>
|
||||
{t('button_following')}
|
||||
</Button>
|
||||
<div>
|
||||
<Button variant="primary" onClick={() => toggleFollow()}>
|
||||
{t('button_following')}
|
||||
</Button>
|
||||
<Link
|
||||
className="btn btn-outline-secondary ms-2"
|
||||
to="/users/settings/notify">
|
||||
<Icon name="bell-fill" />
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
variant="outline-primary"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useState, FormEvent, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { FormDataType } from '@/common/interface';
|
||||
import type { FormDataType, NotificationConfig } from '@/common/interface';
|
||||
import { useToast } from '@/hooks';
|
||||
import { setNotice, getLoggedUserInfo } from '@/services';
|
||||
import { useGetNotificationConfig, putNotificationConfig } from '@/services';
|
||||
import { SchemaForm, JSONSchema, UISchema, initFormData } from '@/components';
|
||||
|
||||
const Index = () => {
|
||||
|
@ -11,46 +11,90 @@ const Index = () => {
|
|||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'settings.notification',
|
||||
});
|
||||
const { data: configData } = useGetNotificationConfig();
|
||||
|
||||
const schema: JSONSchema = {
|
||||
title: t('heading'),
|
||||
properties: {
|
||||
notice_switch: {
|
||||
inbox: {
|
||||
type: 'boolean',
|
||||
title: t('email.label'),
|
||||
default: false,
|
||||
title: t('inbox.label'),
|
||||
description: t('inbox.description'),
|
||||
enum: configData?.inbox?.map((v) => v.enable),
|
||||
default: configData?.inbox?.map((v) => v.enable),
|
||||
enumNames: configData?.inbox?.map((v) => t(v.key)),
|
||||
},
|
||||
all_new_question: {
|
||||
type: 'boolean',
|
||||
title: t('all_new_question.label'),
|
||||
description: t('all_new_question.description'),
|
||||
enum: configData?.all_new_question?.map((v) => v.enable),
|
||||
default: configData?.all_new_question?.map((v) => v.enable),
|
||||
enumNames: configData?.all_new_question?.map((v) => t(v.key)),
|
||||
},
|
||||
all_new_question_for_following_tags: {
|
||||
type: 'boolean',
|
||||
title: t('all_new_question_for_following_tags.label'),
|
||||
description: t('all_new_question_for_following_tags.description'),
|
||||
enum: configData?.all_new_question_for_following_tags?.map(
|
||||
(v) => v.enable,
|
||||
),
|
||||
default: configData?.all_new_question_for_following_tags?.map(
|
||||
(v) => v.enable,
|
||||
),
|
||||
enumNames: configData?.all_new_question_for_following_tags?.map((v) =>
|
||||
t(v.key),
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
const uiSchema: UISchema = {
|
||||
notice_switch: {
|
||||
'ui:widget': 'switch',
|
||||
inbox: {
|
||||
'ui:widget': 'checkbox',
|
||||
'ui:options': {
|
||||
label: t('email.radio'),
|
||||
label: t('email'),
|
||||
},
|
||||
},
|
||||
all_new_question: {
|
||||
'ui:widget': 'checkbox',
|
||||
'ui:options': {
|
||||
label: t('email'),
|
||||
},
|
||||
},
|
||||
all_new_question_for_following_tags: {
|
||||
'ui:widget': 'checkbox',
|
||||
'ui:options': {
|
||||
label: t('email'),
|
||||
text: t('all_new_question_for_following_tags.description'),
|
||||
},
|
||||
},
|
||||
};
|
||||
const [formData, setFormData] = useState<FormDataType>(initFormData(schema));
|
||||
|
||||
const getProfile = () => {
|
||||
getLoggedUserInfo().then((res) => {
|
||||
if (res) {
|
||||
setFormData({
|
||||
notice_switch: {
|
||||
value: res.notice_status === 1,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
setFormData(initFormData(schema));
|
||||
}, [configData]);
|
||||
|
||||
const handleSubmit = (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
setNotice({
|
||||
notice_switch: formData.notice_switch.value,
|
||||
}).then(() => {
|
||||
const params = {
|
||||
inbox: configData?.inbox.map((v, index) => {
|
||||
return { enable: formData.inbox.value[index], key: v.key };
|
||||
}),
|
||||
all_new_question: configData?.all_new_question.map((v, index) => {
|
||||
return { enable: formData.all_new_question.value[index], key: v.key };
|
||||
}),
|
||||
all_new_question_for_following_tags:
|
||||
configData?.all_new_question_for_following_tags.map((v, index) => {
|
||||
return {
|
||||
enable: formData.all_new_question_for_following_tags.value[index],
|
||||
key: v.key,
|
||||
};
|
||||
}),
|
||||
} as NotificationConfig;
|
||||
|
||||
putNotificationConfig(params).then(() => {
|
||||
toast.onShow({
|
||||
msg: t('update', { keyPrefix: 'toast' }),
|
||||
variant: 'success',
|
||||
|
@ -58,9 +102,6 @@ const Index = () => {
|
|||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getProfile();
|
||||
}, []);
|
||||
const handleChange = (ud) => {
|
||||
setFormData(ud);
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import useSWR from 'swr';
|
||||
|
||||
import request from '@/utils/request';
|
||||
import type * as Type from '@/common/interface';
|
||||
|
||||
|
@ -14,3 +16,14 @@ export const updateUserInterface = (lang: string) => {
|
|||
language: lang,
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetNotificationConfig = () => {
|
||||
return useSWR<Type.NotificationConfig>(
|
||||
'/answer/api/v1/user/notification/config',
|
||||
request.instance.get,
|
||||
);
|
||||
};
|
||||
|
||||
export const putNotificationConfig = (data: Type.NotificationConfig) => {
|
||||
return request.put('/answer/api/v1/user/notification/config', data);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue