finally revalidate data completed

This commit is contained in:
2024-11-06 14:18:42 +05:00
parent bc86c7384f
commit 73f6845ede
19 changed files with 236 additions and 225 deletions
+19
View File
@@ -0,0 +1,19 @@
'use server';
import { CreateArticleInput } from '@/generated/graphql';
import { getClient } from '@/lib/apolloClientForSC';
import {
AddArticleDocument,
AddArticleMutation,
} from '@/queries/articles/addArticle';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function addArticleAction(input: CreateArticleInput) {
const { data } = await getClient().mutate<AddArticleMutation>({
mutation: AddArticleDocument,
variables: { input },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/blog');
return data?.createArticle;
}
@@ -0,0 +1,14 @@
'use server';
import { getClient } from '@/lib/apolloClientForSC';
import { DeleteArticleDocument } from '@/queries/articles/deleteArticle';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function deleteArticleAction(id: number) {
await getClient().mutate({
mutation: DeleteArticleDocument,
variables: { id },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/blog');
}
+16
View File
@@ -0,0 +1,16 @@
'use server';
import { CreateArticleInput } from '@/generated/graphql';
import { getClient } from '@/lib/apolloClientForSC';
import { EditArticleDocument } from '@/queries/articles/editArticle';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function editArticleAction(id: number, input: CreateArticleInput) {
await getClient().mutate({
mutation: EditArticleDocument,
variables: { id, input },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/blog');
revalidatePath(`/blog/${id}`);
}
+20
View File
@@ -0,0 +1,20 @@
'use server';
import { CreateProjectInput } from '@/generated/graphql';
import { getClient } from '@/lib/apolloClientForSC';
import {
AddProjectDocument,
AddProjectMutation,
} from '@/queries/projects/addProject';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function addProjectAction(input: CreateProjectInput) {
await getClient().mutate<AddProjectMutation>({
mutation: AddProjectDocument,
variables: { input },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/');
revalidatePath('/projects');
}
@@ -0,0 +1,19 @@
'use server';
import { getClient } from '@/lib/apolloClientForSC';
import {
DeleteProjectDocument,
DeleteProjectMutation,
} from '@/queries/projects/deleleProject';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function deleteProjectAction(id: number) {
await getClient().mutate<DeleteProjectMutation>({
mutation: DeleteProjectDocument,
variables: { id },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/');
revalidatePath('/projects');
}
@@ -0,0 +1,20 @@
'use server';
import { CreateProjectInput } from '@/generated/graphql';
import { getClient } from '@/lib/apolloClientForSC';
import { EditProjectDocument } from '@/queries/projects/editProject';
import { revalidatePath } from 'next/cache';
import { cookies } from 'next/headers';
export async function editProjectActions(
id: number,
input: CreateProjectInput,
) {
await getClient().mutate({
mutation: EditProjectDocument,
variables: { id, input },
context: { headers: { cookie: cookies().toString() } },
});
revalidatePath('/');
revalidatePath('/projects');
}
+11 -42
View File
@@ -1,16 +1,13 @@
'use client';
import { editArticleAction } from '@/actions/articles/editArticleAction';
import { ArticleActions } from '@/components/ArticleActions';
import { ArticleHeader } from '@/components/ArticleHeader';
import { ArticleContentInput } from '@/components/articleInputs/ArticleContentInput';
import { ArticleSliderInput } from '@/components/articleInputs/ArticleSliderInput';
import { IArticleFormInput } from '@/components/modals/ArticleFormModal';
import { ArticleContent } from '@/components/pages/BlogPage/ArticleContent';
import { useEditArticleMutation } from '@/queries/articles/editArticle';
import {
GetArticleByIdDocument,
useGetArticleByIdQuery,
} from '@/queries/articles/getArticleById';
import { useGetArticleByIdQuery } from '@/queries/articles/getArticleById';
import { IArticle } from '@/types/IArticle';
import { Button } from '@/ui/Button';
import { reorderFields } from '@/utils/reorderFields';
@@ -59,17 +56,7 @@ export default function DashboardArticlePage() {
fetchPolicy: 'no-cache',
});
const { query } = useApolloClient();
const [editArticle] = useEditArticleMutation({
async onCompleted() {
await query({
query: GetArticleByIdDocument,
variables: { id: +articleId },
});
window.location.href = '/blog';
},
});
const client = useApolloClient();
const [title, description, createdAt, cardImage, tags, blocks] = useWatch({
name: ['title', 'description', 'createdAt', 'cardImage', 'tags', 'blocks'],
@@ -88,34 +75,16 @@ export default function DashboardArticlePage() {
});
}, [title, description, createdAt, cardImage, tags, blocks, articleId]);
function handleSaveArticle() {
async function onSubmit() {
if (!article) return;
const { id, createdAt, ...other } = article;
editArticle({
variables: {
id: +articleId,
input: {
...other,
createdAt: new Date(createdAt).toISOString(),
blocks: JSON.stringify(getValues('blocks')),
},
},
});
}
function onSubmit(formData: IArticleFormInput) {
if (!article) return;
const { id, createdAt, ...other } = article;
editArticle({
variables: {
id: +articleId,
input: {
...other,
createdAt: createdAt.toISOString(),
blocks: JSON.stringify(formData.blocks),
},
},
await editArticleAction(id, {
...other,
createdAt: new Date(createdAt).toISOString(),
blocks: JSON.stringify(getValues('blocks')),
});
client.refetchQueries({ include: ['GetArticlesCount'] });
window.location.href = '/blog';
}
if (!article) return <div>not found</div>;
@@ -126,7 +95,7 @@ export default function DashboardArticlePage() {
<div className="w-full h-full bg-[#14161F] top-px pt-10 relative">
<div className="absolute justify-between w-full flex lg:-top-20 sm:-top-16 -top-10">
<Button onClick={() => setShowPreview(false)}>Назад</Button>
<Button onClick={handleSaveArticle}>Сохранить</Button>
<Button onClick={onSubmit}>Сохранить</Button>
</div>
<ArticleContent {...article} />
</div>
-2
View File
@@ -25,7 +25,6 @@ export default async function BlogPage({
tags,
limit: +limit,
},
fetchPolicy: 'network-only',
});
const {
@@ -35,7 +34,6 @@ export default async function BlogPage({
variables: {
tags,
},
fetchPolicy: 'no-cache',
});
return (
-2
View File
@@ -14,8 +14,6 @@ import { getClient } from '@/lib/apolloClientForSC';
import { GetProjectsDocument } from '@/queries/projects/getProjects';
import dynamicImport from 'next/dynamic';
export const dynamic = 'force-dynamic';
export default async function HomePage() {
const DynamicIntegrationsSlider = dynamicImport(
async () =>
+10 -33
View File
@@ -1,7 +1,6 @@
'use client';
import { editProjectActions } from '@/actions/projects/editProjectActions';
import { Project } from '@/generated/graphql';
import { useEditProjectMutation } from '@/queries/projects/editProject';
import { GetProjectsDocument } from '@/queries/projects/getProjects';
import { useModalStore } from '@/stores/useModalStore';
import { useApolloClient } from '@apollo/client';
import { DeleteIcon } from './icons/DeleteIcon';
@@ -20,34 +19,15 @@ export function ProjectsActions({
}) {
const { setModal } = useModalStore();
const [editProject] = useEditProjectMutation({
onCompleted: () => setModal(null, ''),
});
const client = useApolloClient();
function onSubmit(id: number) {
return async (data: IAddProjectFormInput) => {
await editProject({
variables: {
id,
input: {
...data,
releaseDate: new Date(data.releaseDate).toISOString().split('T')[0],
},
},
refetchQueries: [
{
query: GetProjectsDocument,
variables: { devices: [], city: chosenCity },
},
],
update(cache, { data }) {
if (data?.updateProject.__typename === 'Project')
window.location.reload();
},
});
};
async function onSubmit({ releaseDate, ...data }: IAddProjectFormInput) {
await editProjectActions(project.id, {
...data,
releaseDate: releaseDate.toISOString().split('T')[0],
});
setModal(null, '');
client.refetchQueries({ include: ['GetProjectsCount'] });
}
function handleEditProject() {
@@ -55,11 +35,8 @@ export function ProjectsActions({
setModal(
<ProjectFormModal
action="edit"
onSubmit={onSubmit(id)}
defaultValues={{
...(other as IAddProjectFormInput),
releaseDate: other.releaseDate.toISOString().split('T')[0],
}}
onSubmit={onSubmit}
defaultValues={other as IAddProjectFormInput}
/>,
'editProject',
);
+19 -10
View File
@@ -1,19 +1,28 @@
import { useDeleteArticleMutation } from '@/queries/articles/deleteArticle';
import { deleteArticleAction } from '@/actions/articles/deleteArticleAction';
import { useModalStore } from '@/stores/useModalStore';
import { Button } from '@/ui/Button';
import { useApolloClient } from '@apollo/client';
import { CloseIcon } from '../icons/CloseIcon';
export function DeleteArticleModal({ id }: { id: number }) {
const { setModal } = useModalStore();
const [deleteArticle] = useDeleteArticleMutation({
variables: { id },
refetchQueries: ['GetArticleById', 'GetArticlesCount'],
onCompleted: () => {
setModal(null, '');
window.location.href = '/blog';
},
});
// const [deleteArticle] = useDeleteArticleMutation({
// variables: { id },
// refetchQueries: ['GetArticleById', 'GetArticlesCount'],
// onCompleted: () => {
// setModal(null, '');
// window.location.href = '/blog';
// },
// });
const client = useApolloClient();
async function handleDeleteArticle() {
await deleteArticleAction(id);
setModal(null, '');
client.refetchQueries({ include: ['GetArticlesCount'] });
}
return (
<div className="bg-white shadow-lg text-black p-8 rounded-xl flex flex-col gap-4">
@@ -28,7 +37,7 @@ export function DeleteArticleModal({ id }: { id: number }) {
</div>
<Button
onClick={deleteArticle}
onClick={handleDeleteArticle}
className="text-white self-end outline-none"
>
Удалить статью
+9 -20
View File
@@ -1,30 +1,19 @@
import { Devices } from '@/consts/ProjectTags';
import { useDeleteProjectMutation } from '@/queries/projects/deleleProject';
import { GetProjectsDocument } from '@/queries/projects/getProjects';
import { deleteProjectAction } from '@/actions/projects/deleteProjectAction';
import { useModalStore } from '@/stores/useModalStore';
import { Button } from '@/ui/Button';
import { useSearchParams } from 'next/navigation';
import { useApolloClient } from '@apollo/client';
import { CloseIcon } from '../icons/CloseIcon';
export function DeleteProjectModal({ id }: { id: number }) {
const { setModal } = useModalStore();
const params = useSearchParams();
const client = useApolloClient();
const [deleteProject] = useDeleteProjectMutation({
variables: { id },
refetchQueries: [
...Devices.map(device => ({
query: GetProjectsDocument,
variables: { devices: [device], city: params.get('city') },
})),
'GetProjectsCount',
],
onCompleted: () => {
setModal(null, '');
window.location.reload();
},
});
async function handleDelete() {
await deleteProjectAction(id);
setModal(null, '');
client.refetchQueries({ include: ['GetProjectsCount'] });
}
return (
<div className="bg-white shadow-lg text-black p-8 rounded-xl flex flex-col gap-4">
@@ -39,7 +28,7 @@ export function DeleteProjectModal({ id }: { id: number }) {
</div>
<Button
onClick={deleteProject}
onClick={handleDelete}
className="text-white self-end outline-none"
>
Удалить проект
+8 -7
View File
@@ -13,7 +13,7 @@ export interface IAddProjectFormInput {
city: string;
image: string;
stage: number;
releaseDate: string;
releaseDate: Date;
devices: Device[];
}
@@ -32,7 +32,13 @@ export function ProjectFormModal({
const { register, handleSubmit, setValue } = useForm<IAddProjectFormInput>({
defaultValues:
action === 'create' ? { devices: [], stage: 1 } : defaultValues,
action === 'create'
? {
devices: [],
stage: 1,
releaseDate: new Date(),
}
: defaultValues,
});
return (
@@ -108,11 +114,6 @@ export function ProjectFormModal({
{...register('releaseDate', { valueAsDate: true })}
id="releaseDate"
className="border border-neutral-500 outline-none px-3 py-2 rounded-lg"
defaultValue={
action === 'create'
? new Date().toISOString().split('T')[0]
: defaultValues!.releaseDate
}
/>
</div>
<div className="flex flex-col">
@@ -13,7 +13,6 @@ export function ArticlesList({
articlesData: ArticlesResult;
articlesCount: number;
}) {
// const {} = useGetArticlesSuspenseQuery()
const { push } = useRouter();
const pathname = usePathname();
@@ -1,8 +1,6 @@
'use client';
import { PostTags } from '@/consts/PostTags';
import { useAddArticleMutation } from '@/queries/articles/addArticle';
import { GetArticlesCountDocument } from '@/queries/articles/getArticlesCount';
import { addArticleAction } from '@/actions/articles/addArticleAction';
import { useCheckAuthQuery } from '@/queries/auth/checkAuth';
import { Button } from '@/ui/Button';
import { Title } from '@/ui/Title';
@@ -17,37 +15,19 @@ export function ArticlesPageHeader() {
const client = useApolloClient();
const [addArticle] = useAddArticleMutation({
onCompleted(data) {
client.query({
query: GetArticlesCountDocument,
variables: { tags: [] },
});
PostTags.forEach(tag => {
client.query({
query: GetArticlesCountDocument,
variables: { tags: [tag] },
});
});
if (data.createArticle.__typename === 'Article')
push(`/blog/${data.createArticle.id}/edit`);
},
});
function handleAddArticle() {
addArticle({
variables: {
input: {
blocks: '[]',
cardImage: '',
createdAt: new Date(),
description: '',
tags: [],
title: '',
},
},
async function handleAddArticle() {
const data = await addArticleAction({
blocks: '[]',
cardImage: '',
createdAt: new Date(),
description: '',
tags: [],
title: '',
});
if (data?.__typename === 'Article') {
client.refetchQueries({ include: ['GetArticlesCount'] });
push(`/blog/${data.id}/edit`);
}
}
return (
+9 -22
View File
@@ -1,5 +1,6 @@
'use client';
import { addProjectAction } from '@/actions/projects/addProjectAction';
import { ArrowMoreIcon } from '@/components/icons/ArrowMoreIcon';
import {
IAddProjectFormInput,
@@ -8,7 +9,6 @@ import {
import { ProjectsResult } from '@/generated/graphql';
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
import { useCheckAuthQuery } from '@/queries/auth/checkAuth';
import { useAddProjectMutation } from '@/queries/projects/addProject';
import { useModalStore } from '@/stores/useModalStore';
import { IProject } from '@/types/IProject';
import { Button } from '@/ui/Button';
@@ -26,13 +26,13 @@ export function Projects({ projects }: { projects: ProjectsResult }) {
const { data: authData } = useCheckAuthQuery();
const [addProject] = useAddProjectMutation({
refetchQueries: ['GetProjects', 'GetProjectsCount'],
update(_, { data }) {
if (data?.createProject.__typename === 'Project')
window.location.reload();
},
});
async function onSubmit({ releaseDate, ...data }: IAddProjectFormInput) {
await addProjectAction({
releaseDate: releaseDate.toISOString().split('T')[0],
...data,
});
setModal(null, '');
}
return (
<>
@@ -55,20 +55,7 @@ export function Projects({ projects }: { projects: ProjectsResult }) {
<Button
onClick={() =>
setModal(
<ProjectFormModal
action={'create'}
onSubmit={(data: IAddProjectFormInput) => {
addProject({
variables: {
input: {
...data,
releaseDate: new Date(data.releaseDate),
},
},
});
setModal(null, '');
}}
/>,
<ProjectFormModal action={'create'} onSubmit={onSubmit} />,
'addProject',
)
}
@@ -1,53 +1,37 @@
'use client';
import { addProjectAction } from '@/actions/projects/addProjectAction';
import { CitySelector } from '@/components/CitySelector';
import {
IAddProjectFormInput,
ProjectFormModal,
} from '@/components/modals/ProjectFormModal';
import { PostTags } from '@/consts/PostTags';
import { useCheckAuthQuery } from '@/queries/auth/checkAuth';
import { useAddProjectMutation } from '@/queries/projects/addProject';
import { GetProjectsDocument } from '@/queries/projects/getProjects';
import { useModalStore } from '@/stores/useModalStore';
import { Button } from '@/ui/Button';
import { Title } from '@/ui/Title';
import { useSearchParams } from 'next/navigation';
import { useApolloClient } from '@apollo/client';
import { ProjectsFilters } from './ProjectsFilters';
export function ProjectsPageHeader() {
const { setModal } = useModalStore();
const params = useSearchParams();
const { data } = useCheckAuthQuery();
const [addProject] = useAddProjectMutation({
refetchQueries: [
...PostTags.map(tag => ({
query: GetProjectsDocument,
variables: { devices: [tag], city: params.get('city') },
})),
'GetProjectsCount',
],
});
const client = useApolloClient();
async function onSubmit({ releaseDate, ...data }: IAddProjectFormInput) {
await addProjectAction({
...data,
releaseDate: releaseDate.toISOString().split('T')[0],
});
setModal(null, '');
client.refetchQueries({ include: ['GetProjectsCount'] });
}
function handleAddProject() {
setModal(
<ProjectFormModal
action={'create'}
onSubmit={(data: IAddProjectFormInput) => {
addProject({
variables: {
input: {
...data,
releaseDate: new Date(data.releaseDate),
},
},
});
setModal(null, '');
}}
/>,
<ProjectFormModal action={'create'} onSubmit={onSubmit} />,
'addProject',
);
}
+1 -2
View File
@@ -8,9 +8,8 @@ import { DateTypeDefinition } from 'graphql-scalars';
export function makeClient() {
const httpLink = new HttpLink({
uri: `${process.env.NEXT_PUBLIC_API}graphql`,
uri: process.env.NEXT_PUBLIC_API + 'graphql',
credentials: 'include',
fetchOptions: { caches: 'force-cache' },
});
return new ApolloClient({
+35 -22
View File
@@ -1,31 +1,44 @@
import { HttpLink } from '@apollo/client';
import { ApolloLink, HttpLink } from '@apollo/client';
import {
ApolloClient,
InMemoryCache,
registerApolloClient,
SSRMultipartLink,
} from '@apollo/experimental-nextjs-app-support';
export const { getClient } = registerApolloClient(
() =>
new ApolloClient({
ssrMode: typeof window === 'undefined',
cache: new InMemoryCache({
typePolicies: {
Project: {
fields: {
releaseDate: {
read(releaseDate) {
return new Date(releaseDate);
},
},
},
export const { getClient } = registerApolloClient(() => {
const httpLink = new HttpLink({
uri: process.env.NEXT_PUBLIC_API + 'graphql',
credentials: 'include',
});
return new ApolloClient({
credentials: 'include',
ssrMode: typeof window === 'undefined',
cache: new InMemoryCache({
typePolicies: {
Project: {
fields: {
// releaseDate: {
// read(releaseDate) {
// return new Date(releaseDate);
// },
// },
},
},
}),
link: new HttpLink({
uri: process.env.NEXT_PUBLIC_API + 'graphql',
credentials: 'include',
fetchOptions: { caches: 'force-cache' },
}),
},
}),
);
// link: new HttpLink({
// uri: process.env.NEXT_PUBLIC_API + 'graphql',
// credentials: 'include',
// fetchOptions: { credentials: 'include' },
// }),
link:
typeof window === 'undefined'
? ApolloLink.from([
new SSRMultipartLink({ stripDefer: true }),
httpLink,
])
: httpLink,
});
});