Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit b894f2b

Browse files
committed
Refactor bulk actions
1 parent 9ae608f commit b894f2b

File tree

3 files changed

+145
-92
lines changed

3 files changed

+145
-92
lines changed

_vercel.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"crons": [
3+
{
4+
"path": "/api/cron/daily-reset-posts",
5+
"schedule": "0 0 * * *"
6+
}
7+
]
8+
}

app/dashboard/posts/components/bulk-actions/bulk-actions.tsx

Lines changed: 115 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -68,53 +68,6 @@ const BulkActions = ({ className, ...props }: BulkActionsProps) => {
6868
const { mutate } = useSWRConfig()
6969
const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false)
7070

71-
const getData = React.useCallback((action: string, post: Post) => {
72-
const user_id = post?.user_id
73-
const visibility = getMetaValue(post?.meta, 'visibility')
74-
const future_date = getMetaValue(post?.meta, 'future_date')
75-
const now = new Date().toISOString()
76-
77-
if (action === 'draft') {
78-
return { status: 'draft', user_id }
79-
} else if (action === 'publish') {
80-
const data = {
81-
status: visibility === 'private' ? 'private' : 'publish',
82-
slug: post?.slug ?? slugify(post?.title ?? ''),
83-
meta: setMeta(post?.meta, 'future_date', null, {
84-
post_id: post?.id,
85-
}),
86-
user_id,
87-
}
88-
return post?.date ? data : { ...data, date: now }
89-
} else if (action === 'public') {
90-
const data = {
91-
status: future_date ? 'future' : 'publish',
92-
meta: setMeta(post?.meta, 'visibility', 'public', {
93-
post_id: post?.id,
94-
}),
95-
user_id,
96-
}
97-
return post?.date ? data : { ...data, date: now }
98-
} else if (action === 'private') {
99-
const data = {
100-
status: future_date ? 'future' : 'private',
101-
meta: setMeta(post?.meta, 'visibility', 'private', {
102-
post_id: post?.id,
103-
}),
104-
user_id,
105-
}
106-
return post?.date ? data : { ...data, date: now }
107-
} else if (action === 'trash') {
108-
return { status: 'trash', deleted_at: now, user_id }
109-
} else if (action === 'restore') {
110-
return { status: 'draft', deleted_at: null, user_id }
111-
} else if (action === 'delete') {
112-
return { user_id }
113-
}
114-
115-
return null
116-
}, [])
117-
11871
const onSubmit = async (formValues: FormValues) => {
11972
if (formValues?.action === 'unassigned') return false
12073
if (checks.length < 1) return false
@@ -123,36 +76,133 @@ const BulkActions = ({ className, ...props }: BulkActionsProps) => {
12376
setIsSubmitting(true)
12477

12578
for (let i = 0; i < checks.length; i++) {
126-
const post = checks[i]
127-
const data = getData(formValues?.action, post)
79+
const check = checks[i]
12880

129-
if (!data) throw new Error('Require is not defined.')
81+
const user_id = check?.user_id
82+
const visibility = getMetaValue(check?.meta, 'visibility')
83+
const future_date = getMetaValue(check?.meta, 'future_date')
84+
const now = new Date().toISOString()
13085

131-
const revalidatePaths = post?.permalink
132-
? relativeUrl(post?.permalink)
86+
const revalidatePaths = check?.permalink
87+
? relativeUrl(check?.permalink)
13388
: null
13489

135-
const { error } = await fetcher<PostAPI>(
136-
`/api/v1/post?id=${post?.id}`,
137-
{
138-
method: formValues?.action === 'delete' ? 'DELETE' : 'POST',
139-
body: JSON.stringify({
140-
data,
141-
options: { revalidatePaths },
90+
if (formValues?.action === 'draft') {
91+
const { error } = await fetcher<PostAPI>(
92+
`/api/v1/post?id=${check?.id}`,
93+
{
94+
method: 'POST',
95+
body: JSON.stringify({
96+
data: { status: 'draft', user_id },
97+
options: { revalidatePaths },
98+
}),
99+
}
100+
)
101+
if (error) throw new Error(error?.message)
102+
} else if (formValues?.action === 'publish') {
103+
const data = {
104+
status: visibility === 'private' ? 'private' : 'publish',
105+
slug: check?.slug ?? slugify(check?.title ?? ''),
106+
meta: setMeta(check?.meta, 'future_date', null, {
107+
post_id: check?.id,
142108
}),
109+
user_id,
143110
}
144-
)
145-
146-
if (error) throw new Error(error?.message)
111+
const { error } = await fetcher<PostAPI>(
112+
`/api/v1/post?id=${check?.id}`,
113+
{
114+
method: 'POST',
115+
body: JSON.stringify({
116+
data: check?.date ? data : { ...data, date: now },
117+
options: { revalidatePaths },
118+
}),
119+
}
120+
)
121+
if (error) throw new Error(error?.message)
122+
} else if (formValues?.action === 'public') {
123+
const data = {
124+
status: future_date ? 'future' : 'publish',
125+
meta: setMeta(check?.meta, 'visibility', 'public', {
126+
post_id: check?.id,
127+
}),
128+
user_id,
129+
}
130+
const { error } = await fetcher<PostAPI>(
131+
`/api/v1/post?id=${check?.id}`,
132+
{
133+
method: 'POST',
134+
body: JSON.stringify({
135+
data: check?.date ? data : { ...data, date: now },
136+
options: { revalidatePaths },
137+
}),
138+
}
139+
)
140+
if (error) throw new Error(error?.message)
141+
} else if (formValues?.action === 'private') {
142+
const data = {
143+
status: future_date ? 'future' : 'private',
144+
meta: setMeta(check?.meta, 'visibility', 'private', {
145+
post_id: check?.id,
146+
}),
147+
user_id,
148+
}
149+
const { error } = await fetcher<PostAPI>(
150+
`/api/v1/post?id=${check?.id}`,
151+
{
152+
method: 'POST',
153+
body: JSON.stringify({
154+
data: check?.date ? data : { ...data, date: now },
155+
options: { revalidatePaths },
156+
}),
157+
}
158+
)
159+
if (error) throw new Error(error?.message)
160+
} else if (formValues?.action === 'trash') {
161+
const { error } = await fetcher<PostAPI>(
162+
`/api/v1/post?id=${check?.id}`,
163+
{
164+
method: 'POST',
165+
body: JSON.stringify({
166+
data: { status: 'trash', deleted_at: now, user_id },
167+
options: { revalidatePaths },
168+
}),
169+
}
170+
)
171+
if (error) throw new Error(error?.message)
172+
} else if (formValues?.action === 'restore') {
173+
const { error } = await fetcher<PostAPI>(
174+
`/api/v1/post?id=${check?.id}`,
175+
{
176+
method: 'POST',
177+
body: JSON.stringify({
178+
data: { status: 'draft', deleted_at: null, user_id },
179+
options: { revalidatePaths },
180+
}),
181+
}
182+
)
183+
if (error) throw new Error(error?.message)
184+
} else if (formValues?.action === 'delete') {
185+
const { error } = await fetcher<PostAPI>(
186+
`/api/v1/post?id=${check?.id}`,
187+
{
188+
method: 'DELETE',
189+
body: JSON.stringify({
190+
data: { user_id },
191+
options: { revalidatePaths },
192+
}),
193+
}
194+
)
195+
if (error) throw new Error(error?.message)
196+
}
147197

148198
const countSearchParams = setQueryString({
149-
userId: post?.user_id,
199+
userId: check?.user_id,
150200
postType: paging?.postType,
151201
q: paging?.q,
152202
})
153203

154204
const listSearchParams = setQueryString({
155-
userId: post?.user_id,
205+
userId: check?.user_id,
156206
postType: paging?.postType,
157207
status: paging?.status,
158208
q: paging?.q,
@@ -162,7 +212,7 @@ const BulkActions = ({ className, ...props }: BulkActionsProps) => {
162212
page: paging?.page,
163213
})
164214

165-
mutate(`/api/v1/post?id=${post?.id}`)
215+
mutate(`/api/v1/post?id=${check?.id}`)
166216
mutate(`/api/v1/post/count?${countSearchParams}`)
167217
mutate(`/api/v1/post/list?${listSearchParams}`)
168218
}

app/dashboard/tags/components/bulk-actions/bulk-actions.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,6 @@ const BulkActions = ({ className, ...props }: BulkActionsProps) => {
6060
const { mutate } = useSWRConfig()
6161
const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false)
6262

63-
const getData = React.useCallback((action: string, tag: Tag) => {
64-
if (action === 'delete') {
65-
return {
66-
user_id: tag?.user_id,
67-
name: tag?.name,
68-
slug: tag?.slug,
69-
post_tags: tag?.post_tags,
70-
}
71-
}
72-
73-
return null
74-
}, [])
75-
7663
const onSubmit = async (formValues: FormValues) => {
7764
if (formValues?.action === 'unassigned') return false
7865
if (checks.length < 1) return false
@@ -81,31 +68,39 @@ const BulkActions = ({ className, ...props }: BulkActionsProps) => {
8168
setIsSubmitting(true)
8269

8370
for (let i = 0; i < checks.length; i++) {
84-
const tag = checks[i]
85-
const data = getData(formValues?.action, tag)
86-
87-
if (!data) throw new Error('Require is not defined.')
88-
89-
const { error } = await fetcher<PostAPI>(`/api/v1/tag?id=${tag?.id}`, {
90-
method: formValues?.action === 'delete' ? 'DELETE' : 'POST',
91-
body: JSON.stringify({ data }),
92-
})
93-
94-
if (error) throw new Error(error?.message)
71+
const check = checks[i]
72+
73+
if (formValues?.action === 'delete') {
74+
const { error } = await fetcher<PostAPI>(
75+
`/api/v1/tag?id=${check?.id}`,
76+
{
77+
method: formValues?.action === 'delete' ? 'DELETE' : 'POST',
78+
body: JSON.stringify({
79+
data: {
80+
user_id: check?.user_id,
81+
name: check?.name,
82+
slug: check?.slug,
83+
post_tags: check?.post_tags,
84+
},
85+
}),
86+
}
87+
)
88+
if (error) throw new Error(error?.message)
89+
}
9590

9691
const listSearchParams = setQueryString({
97-
userId: tag?.user_id,
92+
userId: check?.user_id,
9893
q: paging?.q,
9994
orderBy: paging?.orderBy,
10095
order: paging?.order,
10196
perPage: paging?.perPage,
10297
page: paging?.page,
10398
})
10499

105-
mutate(`/api/v1/tag?id=${tag?.id}`)
100+
mutate(`/api/v1/tag?id=${check?.id}`)
106101
mutate(`/api/v1/tag/list?${listSearchParams}`)
107102

108-
const post_tags = tag?.post_tags
103+
const post_tags = check?.post_tags
109104

110105
if (Array.isArray(post_tags) && post_tags?.length > 0) {
111106
for (let i = 0; i < post_tags.length; i++) {

0 commit comments

Comments
 (0)