frontend-rw #1

Merged
marcin merged 347 commits from frontend-rw into develop 2024-12-05 15:32:18 -08:00
16 changed files with 94 additions and 96 deletions
Showing only changes of commit d07f698573 - Show all commits

View file

@ -1,82 +0,0 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import {
adminAnnouncementSchema,
type AdminAnnouncement,
type AdminCreateAnnouncementParams,
type AdminUpdateAnnouncementParams,
} from 'pl-api';
import * as v from 'valibot';
import { useClient } from 'pl-fe/hooks/use-client';
import { queryClient } from 'pl-fe/queries/client';
import { useAnnouncements as useUserAnnouncements } from '../../../queries/announcements/use-announcements';
const useAnnouncements = () => {
const client = useClient();
const userAnnouncements = useUserAnnouncements();
const getAnnouncements = async () => {
const data = await client.admin.announcements.getAnnouncements();
return data.items;
};
const result = useQuery<ReadonlyArray<AdminAnnouncement>>({
queryKey: ['admin', 'announcements'],
queryFn: getAnnouncements,
placeholderData: [] as ReadonlyArray<AdminAnnouncement>,
});
const {
mutate: createAnnouncement,
isPending: isCreating,
} = useMutation({
mutationFn: (params: AdminCreateAnnouncementParams) => client.admin.announcements.createAnnouncement(params),
retry: false,
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>
[...prevResult, v.parse(adminAnnouncementSchema, data)],
),
onSettled: () => userAnnouncements.refetch(),
});
const {
mutate: updateAnnouncement,
isPending: isUpdating,
} = useMutation({
mutationFn: ({ id, ...params }: AdminUpdateAnnouncementParams & { id: string }) =>
client.admin.announcements.updateAnnouncement(id, params),
retry: false,
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>
prevResult.map((announcement) => announcement.id === data.id ? v.parse(adminAnnouncementSchema, data) : announcement),
),
onSettled: () => userAnnouncements.refetch(),
});
const {
mutate: deleteAnnouncement,
isPending: isDeleting,
} = useMutation({
mutationFn: (id: string) => client.admin.announcements.deleteAnnouncement(id),
retry: false,
onSuccess: (_, id) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>
prevResult.filter(({ id: announcementId }) => announcementId !== id),
),
onSettled: () => userAnnouncements.refetch(),
});
return {
...result,
createAnnouncement,
isCreating,
updateAnnouncement,
isUpdating,
deleteAnnouncement,
isDeleting,
};
};
export { useAnnouncements };

View file

@ -1,7 +1,6 @@
import React from 'react';
import { FormattedDate, FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useAnnouncements } from 'pl-fe/api/hooks/admin/use-announcements';
import { ParsedContent } from 'pl-fe/components/parsed-content';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Button from 'pl-fe/components/ui/button';
@ -9,6 +8,7 @@ import Column from 'pl-fe/components/ui/column';
import HStack from 'pl-fe/components/ui/hstack';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useAnnouncements, useDeleteAnnouncementMutation } from 'pl-fe/queries/admin/use-announcements';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast from 'pl-fe/toast';
@ -28,7 +28,7 @@ interface IAnnouncement {
const Announcement: React.FC<IAnnouncement> = ({ announcement }) => {
const intl = useIntl();
const { deleteAnnouncement } = useAnnouncements();
const { mutate: deleteAnnouncement } = useDeleteAnnouncementMutation();
const { openModal } = useModalsStore();
const handleEditAnnouncement = () => {

View file

@ -1,7 +1,6 @@
import React, { useEffect } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useDomains } from 'pl-fe/api/hooks/admin/use-domains';
import { dateFormatOptions } from 'pl-fe/components/relative-timestamp';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Button from 'pl-fe/components/ui/button';
@ -9,6 +8,7 @@ import Column from 'pl-fe/components/ui/column';
import HStack from 'pl-fe/components/ui/hstack';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useDomains } from 'pl-fe/queries/admin/use-domains';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast from 'pl-fe/toast';

View file

@ -1,11 +1,11 @@
import React from 'react';
import { defineMessages, FormattedDate, useIntl } from 'react-intl';
import { useModerationLog } from 'pl-fe/api/hooks/admin/use-moderation-log';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Column from 'pl-fe/components/ui/column';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useModerationLog } from 'pl-fe/queries/admin/use-moderation-log';
import type { AdminModerationLogEntry } from 'pl-api';

View file

@ -1,7 +1,6 @@
import React from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRelays } from 'pl-fe/api/hooks/admin/use-relays';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Button from 'pl-fe/components/ui/button';
import Column from 'pl-fe/components/ui/column';
@ -11,6 +10,7 @@ import Input from 'pl-fe/components/ui/input';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useTextField } from 'pl-fe/hooks/forms/use-text-field';
import { useRelays } from 'pl-fe/queries/admin/use-relays';
import toast from 'pl-fe/toast';
import type { AdminRelay as RelayEntity } from 'pl-api';

View file

@ -1,13 +1,13 @@
import React from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRules } from 'pl-fe/api/hooks/admin/use-rules';
import ScrollableList from 'pl-fe/components/scrollable-list';
import Button from 'pl-fe/components/ui/button';
import Column from 'pl-fe/components/ui/column';
import HStack from 'pl-fe/components/ui/hstack';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { useRules } from 'pl-fe/queries/admin/use-rules';
import { useModalsStore } from 'pl-fe/stores/modals';
import toast from 'pl-fe/toast';

View file

@ -1,7 +1,6 @@
import React, { useState } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useAnnouncements } from 'pl-fe/api/hooks/admin/use-announcements';
import Form from 'pl-fe/components/ui/form';
import FormGroup from 'pl-fe/components/ui/form-group';
import HStack from 'pl-fe/components/ui/hstack';
@ -11,6 +10,7 @@ import Text from 'pl-fe/components/ui/text';
import Textarea from 'pl-fe/components/ui/textarea';
import Toggle from 'pl-fe/components/ui/toggle';
import { DatePicker } from 'pl-fe/features/ui/util/async-components';
import { useCreateAnnouncementMutation, useUpdateAnnouncementMutation } from 'pl-fe/queries/admin/use-announcements';
import toast from 'pl-fe/toast';
import type { BaseModalProps } from '../modal-root';
@ -30,7 +30,8 @@ interface EditAnnouncementModalProps {
}
const EditAnnouncementModal: React.FC<BaseModalProps & EditAnnouncementModalProps> = ({ onClose, announcement }) => {
const { createAnnouncement, updateAnnouncement } = useAnnouncements();
const { mutate: createAnnouncement } = useCreateAnnouncementMutation();
const { mutate: updateAnnouncement } = useUpdateAnnouncementMutation();
const intl = useIntl();
const [content, setContent] = useState(announcement?.raw_content || '');

View file

@ -1,7 +1,6 @@
import React, { useState } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useDomains } from 'pl-fe/api/hooks/admin/use-domains';
import Form from 'pl-fe/components/ui/form';
import FormGroup from 'pl-fe/components/ui/form-group';
import HStack from 'pl-fe/components/ui/hstack';
@ -10,6 +9,7 @@ import Modal from 'pl-fe/components/ui/modal';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import Toggle from 'pl-fe/components/ui/toggle';
import { useDomains } from 'pl-fe/queries/admin/use-domains';
import toast from 'pl-fe/toast';
import type { BaseModalProps } from '../modal-root';

View file

@ -1,12 +1,12 @@
import React from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRules } from 'pl-fe/api/hooks/admin/use-rules';
import Form from 'pl-fe/components/ui/form';
import FormGroup from 'pl-fe/components/ui/form-group';
import Input from 'pl-fe/components/ui/input';
import Modal from 'pl-fe/components/ui/modal';
import { useTextField } from 'pl-fe/hooks/forms/use-text-field';
import { useRules } from 'pl-fe/queries/admin/use-rules';
import toast from 'pl-fe/toast';
import type { BaseModalProps } from '../modal-root';

View file

@ -0,0 +1,79 @@
import { type InfiniteData, useMutation } from '@tanstack/react-query';
import { create } from 'mutative';
import {
adminAnnouncementSchema,
PaginatedResponse,
type AdminAnnouncement,
type AdminCreateAnnouncementParams,
type AdminUpdateAnnouncementParams,
} from 'pl-api';
import * as v from 'valibot';
import { useClient } from 'pl-fe/hooks/use-client';
import { queryClient } from 'pl-fe/queries/client';
import { makePaginatedResponseQuery } from '../utils/make-paginated-response-query';
const useAnnouncements = makePaginatedResponseQuery(
() => ['admin', 'announcements'],
(client) => client.admin.announcements.getAnnouncements(),
);
const useCreateAnnouncementMutation = () => {
const client = useClient();
return useMutation({
mutationFn: (params: AdminCreateAnnouncementParams) => client.admin.announcements.createAnnouncement(params),
retry: false,
onSuccess: (data) => {
queryClient.setQueryData<InfiniteData<PaginatedResponse<AdminAnnouncement>>>(
['admin', 'announcements'],
(prevData) => create(prevData, (draft) => {
if (draft?.pages.length) draft.pages[0].items = [v.parse(adminAnnouncementSchema, data), ...draft.pages[0].items];
}),
);
queryClient.invalidateQueries({ queryKey: ['announcements'] });
},
});
};
const useUpdateAnnouncementMutation = () => {
const client = useClient();
return useMutation({
mutationFn: ({ id, ...params }: AdminUpdateAnnouncementParams & { id: string }) => client.admin.announcements.updateAnnouncement(id, params),
retry: false,
onSuccess: (data) => {
queryClient.setQueryData<InfiniteData<PaginatedResponse<AdminAnnouncement>>>(
['admin', 'announcements'],
(prevData) => create(prevData, (draft) => {
draft?.pages.forEach(({ items }) => {
const index = items.findIndex(({ id }) => id === data.id);
if (index !== -1) items[index] = v.parse(adminAnnouncementSchema, data);
});
}),
);
queryClient.invalidateQueries({ queryKey: ['announcements'] });
},
});
};
const useDeleteAnnouncementMutation = () => {
const client = useClient();
return useMutation({
mutationFn: (id: string) => client.admin.announcements.deleteAnnouncement(id),
retry: false,
onSuccess: (_, deletedAnnouncementId) => {
queryClient.setQueryData<InfiniteData<PaginatedResponse<AdminAnnouncement>>>(
['admin', 'announcements'],
(prevData) => create(prevData, (draft) => {
draft?.pages.forEach((page) => page.items = page.items.filter(({ id }) => id !== deletedAnnouncementId));
}),
);
queryClient.invalidateQueries({ queryKey: ['announcements'] });
},
});
};
export { useAnnouncements, useCreateAnnouncementMutation, useUpdateAnnouncementMutation, useDeleteAnnouncementMutation };

View file

@ -2,10 +2,10 @@
import { type InfiniteData, useMutation } from '@tanstack/react-query';
import { importEntities } from 'pl-fe/actions/importer';
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyList } from 'pl-fe/queries/utils/minify-list';
import { useClient } from 'pl-fe/hooks/use-client';
import { queryClient } from 'pl-fe/queries/client';
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyList } from 'pl-fe/queries/utils/minify-list';
import { store } from 'pl-fe/store';
import type { PlApiClient } from 'pl-api';

View file

@ -1,10 +1,10 @@
import { useQuery } from '@tanstack/react-query';
import { importEntities } from 'pl-fe/actions/importer';
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyAccountList } from 'pl-fe/queries/utils/minify-list';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useClient } from 'pl-fe/hooks/use-client';
import { makePaginatedResponseQuery } from 'pl-fe/queries/utils/make-paginated-response-query';
import { minifyAccountList } from 'pl-fe/queries/utils/minify-list';
const queryKey = {
getDislikedBy: 'statusDislikes',