[frontend]: add chat settings page
This commit is contained in:
parent
4c0e463aec
commit
ed59327cb7
20
frontend/src/app/(site)/dashboard/chat/page.tsx
Normal file
20
frontend/src/app/(site)/dashboard/chat/page.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
import { ChangeChatSettings } from '@/components/features/chat/settings/ChangeChatSettings';
|
||||
import { NO_INDEX_PAGE } from '@/libs/constants/seo.constants';
|
||||
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const t = await getTranslations('dashboard.chat.header');
|
||||
|
||||
return {
|
||||
title: t('heading'),
|
||||
description: t('description'),
|
||||
...NO_INDEX_PAGE,
|
||||
};
|
||||
}
|
||||
|
||||
const ChatSettingsPage = () => <ChangeChatSettings />;
|
||||
|
||||
export default ChatSettingsPage;
|
||||
@ -0,0 +1,132 @@
|
||||
'use client';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import { Form, FormField } from '@/components/ui/common/Form';
|
||||
import { Heading } from '@/components/ui/elements/Heading';
|
||||
import {
|
||||
ToggleCard,
|
||||
ToggleCardSkeleton,
|
||||
} from '@/components/ui/elements/ToggleCard';
|
||||
import { useChangeChatSettingsMutation } from '@/graphql/generated/output';
|
||||
import { useCurrent } from '@/hooks/useCurrent';
|
||||
import { changeChatSettingsSchema } from '@/schemas/chat/change-chat.settings.schema';
|
||||
|
||||
import type { TypeChangeChatSettingsSchema } from '@/schemas/chat/change-chat.settings.schema';
|
||||
|
||||
export const ChangeChatSettings = () => {
|
||||
const t = useTranslations('dashboard.chat');
|
||||
|
||||
const { user, isLoadingProfile } = useCurrent();
|
||||
|
||||
const form = useForm<TypeChangeChatSettingsSchema>({
|
||||
resolver: zodResolver(changeChatSettingsSchema),
|
||||
values: {
|
||||
isChatEnable: user?.stream.isChatEnable ?? false,
|
||||
isChatFollowersOnly: user?.stream.isChatFollowersOnly ?? false,
|
||||
isChatPremiumFollowersOnly:
|
||||
user?.stream.isChatPremiumFollowersOnly ?? false,
|
||||
},
|
||||
});
|
||||
|
||||
const [update, { loading: isLoadingUpdate }] = useChangeChatSettingsMutation({
|
||||
onCompleted(data) {
|
||||
toast.success(t('successMessage'));
|
||||
},
|
||||
onError() {
|
||||
toast.error(t('errorMessage'));
|
||||
},
|
||||
});
|
||||
|
||||
function onChange(
|
||||
field: keyof TypeChangeChatSettingsSchema,
|
||||
value: boolean,
|
||||
) {
|
||||
form.setValue(field, value);
|
||||
|
||||
update({
|
||||
variables: {
|
||||
data: { ...form.getValues(), [field]: value },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="lg:px-10">
|
||||
<Heading
|
||||
description={t('header.description')}
|
||||
size="lg"
|
||||
title={t('header.heading')}
|
||||
/>
|
||||
|
||||
<div className="mt-3 space-y-6">
|
||||
{isLoadingProfile
|
||||
? Array.from({ length: 3 }).map((_, index) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<ToggleCardSkeleton key={index} />
|
||||
))
|
||||
: (
|
||||
<Form {...form}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="isChatEnable"
|
||||
render={({ field }) => (
|
||||
<ToggleCard
|
||||
description={t('isChatEnabled.description')}
|
||||
heading={t('isChatEnabled.heading')}
|
||||
isDisabled={isLoadingUpdate}
|
||||
value={field.value}
|
||||
onChange={(value) => { onChange('isChatEnable', value); }}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="isChatFollowersOnly"
|
||||
render={({ field }) => (
|
||||
<ToggleCard
|
||||
description={t(
|
||||
'isChatFollowersOnly.description',
|
||||
)}
|
||||
heading={t('isChatFollowersOnly.heading')}
|
||||
isDisabled={isLoadingUpdate}
|
||||
value={field.value}
|
||||
onChange={(value) => { onChange('isChatFollowersOnly', value); }}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="isChatPremiumFollowersOnly"
|
||||
render={({ field }) => (
|
||||
<ToggleCard
|
||||
description={t(
|
||||
'isChatPremiumFollowersOnly.description',
|
||||
)}
|
||||
heading={t(
|
||||
'isChatPremiumFollowersOnly.heading',
|
||||
)}
|
||||
isDisabled={
|
||||
isLoadingUpdate || !user?.isVerified
|
||||
}
|
||||
value={field.value}
|
||||
onChange={(value) => {
|
||||
onChange(
|
||||
'isChatPremiumFollowersOnly',
|
||||
value,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -643,6 +643,20 @@ export type VerifyAccountMutationVariables = Exact<{
|
||||
|
||||
export type VerifyAccountMutation = { __typename?: 'Mutation', verifyAccount: { __typename?: 'AuthModel', message?: string | null, user?: { __typename?: 'UserModel', isEmailVerified: boolean } | null } };
|
||||
|
||||
export type ChangeChatSettingsMutationVariables = Exact<{
|
||||
data: ChangeChatSettingsInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type ChangeChatSettingsMutation = { __typename?: 'Mutation', changeChatSettings: { __typename?: 'StreamModel', id: string } };
|
||||
|
||||
export type SendChatMessageMutationVariables = Exact<{
|
||||
data: SendMessageInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type SendChatMessageMutation = { __typename?: 'Mutation', sendChatMessage: { __typename?: 'ChatMessageModel', streamId: string } };
|
||||
|
||||
export type CreateIngressMutationVariables = Exact<{
|
||||
ingressType: Scalars['Float']['input'];
|
||||
}>;
|
||||
@ -768,7 +782,7 @@ export type FindUnreadNotificationsCountQuery = { __typename?: 'Query', findUnre
|
||||
export type FindProfileQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type FindProfileQuery = { __typename?: 'Query', findProfile: { __typename?: 'UserModel', avatar?: string | null, bio?: string | null, createdAt: any, email: string, id: string, name: string, updatedAt: any, isEmailVerified: boolean, isTotpEnabled: boolean, isVerified: boolean, displayName: string, socialLink: Array<{ __typename?: 'SocialLinkModel', title: string, url: string, position: number }>, notificationSettings?: { __typename?: 'NotificationSettingsModel', siteNotifications: boolean, telegramNotifications: boolean } | null, stream: { __typename?: 'StreamModel', serverUrl?: string | null, key?: string | null } } };
|
||||
export type FindProfileQuery = { __typename?: 'Query', findProfile: { __typename?: 'UserModel', avatar?: string | null, bio?: string | null, createdAt: any, email: string, id: string, name: string, updatedAt: any, isEmailVerified: boolean, isTotpEnabled: boolean, isVerified: boolean, displayName: string, socialLink: Array<{ __typename?: 'SocialLinkModel', title: string, url: string, position: number }>, notificationSettings?: { __typename?: 'NotificationSettingsModel', siteNotifications: boolean, telegramNotifications: boolean } | null, stream: { __typename?: 'StreamModel', serverUrl?: string | null, key?: string | null, isChatEnable: boolean, isChatFollowersOnly: boolean, isChatPremiumFollowersOnly: boolean } } };
|
||||
|
||||
export type FindSessionsByUserQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
@ -1053,6 +1067,72 @@ export function useVerifyAccountMutation(baseOptions?: Apollo.MutationHookOption
|
||||
export type VerifyAccountMutationHookResult = ReturnType<typeof useVerifyAccountMutation>;
|
||||
export type VerifyAccountMutationResult = Apollo.MutationResult<VerifyAccountMutation>;
|
||||
export type VerifyAccountMutationOptions = Apollo.BaseMutationOptions<VerifyAccountMutation, VerifyAccountMutationVariables>;
|
||||
export const ChangeChatSettingsDocument = gql`
|
||||
mutation ChangeChatSettings($data: ChangeChatSettingsInput!) {
|
||||
changeChatSettings(data: $data) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type ChangeChatSettingsMutationFn = Apollo.MutationFunction<ChangeChatSettingsMutation, ChangeChatSettingsMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useChangeChatSettingsMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useChangeChatSettingsMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useChangeChatSettingsMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [changeChatSettingsMutation, { data, loading, error }] = useChangeChatSettingsMutation({
|
||||
* variables: {
|
||||
* data: // value for 'data'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useChangeChatSettingsMutation(baseOptions?: Apollo.MutationHookOptions<ChangeChatSettingsMutation, ChangeChatSettingsMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<ChangeChatSettingsMutation, ChangeChatSettingsMutationVariables>(ChangeChatSettingsDocument, options);
|
||||
}
|
||||
export type ChangeChatSettingsMutationHookResult = ReturnType<typeof useChangeChatSettingsMutation>;
|
||||
export type ChangeChatSettingsMutationResult = Apollo.MutationResult<ChangeChatSettingsMutation>;
|
||||
export type ChangeChatSettingsMutationOptions = Apollo.BaseMutationOptions<ChangeChatSettingsMutation, ChangeChatSettingsMutationVariables>;
|
||||
export const SendChatMessageDocument = gql`
|
||||
mutation SendChatMessage($data: SendMessageInput!) {
|
||||
sendChatMessage(data: $data) {
|
||||
streamId
|
||||
}
|
||||
}
|
||||
`;
|
||||
export type SendChatMessageMutationFn = Apollo.MutationFunction<SendChatMessageMutation, SendChatMessageMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useSendChatMessageMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useSendChatMessageMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useSendChatMessageMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [sendChatMessageMutation, { data, loading, error }] = useSendChatMessageMutation({
|
||||
* variables: {
|
||||
* data: // value for 'data'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useSendChatMessageMutation(baseOptions?: Apollo.MutationHookOptions<SendChatMessageMutation, SendChatMessageMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<SendChatMessageMutation, SendChatMessageMutationVariables>(SendChatMessageDocument, options);
|
||||
}
|
||||
export type SendChatMessageMutationHookResult = ReturnType<typeof useSendChatMessageMutation>;
|
||||
export type SendChatMessageMutationResult = Apollo.MutationResult<SendChatMessageMutation>;
|
||||
export type SendChatMessageMutationOptions = Apollo.BaseMutationOptions<SendChatMessageMutation, SendChatMessageMutationVariables>;
|
||||
export const CreateIngressDocument = gql`
|
||||
mutation CreateIngress($ingressType: Float!) {
|
||||
createIngress(ingressType: $ingressType)
|
||||
@ -1757,6 +1837,9 @@ export const FindProfileDocument = gql`
|
||||
stream {
|
||||
serverUrl
|
||||
key
|
||||
isChatEnable
|
||||
isChatFollowersOnly
|
||||
isChatPremiumFollowersOnly
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
mutation ChangeChatSettings($data: ChangeChatSettingsInput!) {
|
||||
changeChatSettings(data: $data) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
mutation SendChatMessage($data: SendMessageInput!) {
|
||||
sendChatMessage(data: $data) {
|
||||
streamId
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,9 @@ query FindProfile {
|
||||
stream {
|
||||
serverUrl
|
||||
key
|
||||
isChatEnable
|
||||
isChatFollowersOnly
|
||||
isChatPremiumFollowersOnly
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
frontend/src/schemas/chat/change-chat.settings.schema.ts
Normal file
11
frontend/src/schemas/chat/change-chat.settings.schema.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const changeChatSettingsSchema = z.object({
|
||||
isChatEnable: z.boolean(),
|
||||
isChatFollowersOnly: z.boolean(),
|
||||
isChatPremiumFollowersOnly: z.boolean(),
|
||||
});
|
||||
|
||||
export type TypeChangeChatSettingsSchema = z.infer<
|
||||
typeof changeChatSettingsSchema
|
||||
>;
|
||||
7
frontend/src/schemas/chat/send-message.schema.ts
Normal file
7
frontend/src/schemas/chat/send-message.schema.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const sendMessageSchema = z.object({
|
||||
text: z.string().min(1),
|
||||
});
|
||||
|
||||
export type TypeSendMessageSchema = z.infer<typeof sendMessageSchema>;
|
||||
Loading…
x
Reference in New Issue
Block a user