Compare commits
3 Commits
87616ef6bd
...
1585830184
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1585830184 | ||
|
|
22918b8bdb | ||
|
|
d32eb2e7ed |
@ -8,6 +8,7 @@ const adResponseSchema = z.object({
|
||||
url: z.string(),
|
||||
start_date: z.string(),
|
||||
end_date: z.string(),
|
||||
clicked: z.number(),
|
||||
})
|
||||
const adsResponseSchema = z.object({
|
||||
data: z.array(adResponseSchema),
|
||||
|
||||
30
app/apis/news/create-log-ads.ts
Normal file
30
app/apis/news/create-log-ads.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
import { HttpServer, type THttpServer } from '~/libs/http-server'
|
||||
import type { TAdsSchema } from '~/pages/form-advertisements'
|
||||
|
||||
const logAdsResponseSchema = z.object({
|
||||
data: z.object({
|
||||
Message: z.string(),
|
||||
}),
|
||||
})
|
||||
type TParameters = {
|
||||
id: TAdsSchema['id']
|
||||
} & THttpServer
|
||||
|
||||
export const createLogAdsRequest = async (parameters: TParameters) => {
|
||||
const { id, ...restParameters } = parameters
|
||||
const payload = {
|
||||
ads_id: id,
|
||||
}
|
||||
try {
|
||||
const { data } = await HttpServer(restParameters).post(
|
||||
'/api/logs/ads',
|
||||
payload,
|
||||
)
|
||||
return logAdsResponseSchema.parse(data)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
|
||||
return Promise.reject(error)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import { Button } from '@headlessui/react'
|
||||
import Autoplay from 'embla-carousel-autoplay'
|
||||
import useEmblaCarousel from 'embla-carousel-react'
|
||||
import { Link, useRouteLoaderData } from 'react-router'
|
||||
import { useFetcher, useRouteLoaderData } from 'react-router'
|
||||
|
||||
import type { loader } from '~/routes/_news'
|
||||
|
||||
@ -8,6 +9,7 @@ export const Banner = () => {
|
||||
const loaderData = useRouteLoaderData<typeof loader>('routes/_news')
|
||||
const { adsData } = loaderData || {}
|
||||
const [emblaReference] = useEmblaCarousel({ loop: true }, [Autoplay()])
|
||||
const fetcher = useFetcher()
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
@ -17,24 +19,25 @@ export const Banner = () => {
|
||||
ref={emblaReference}
|
||||
>
|
||||
<div className="embla__container flex">
|
||||
{adsData?.map(({ image_url: urlImage, url: link, id }, index) => (
|
||||
<div
|
||||
{adsData?.map(({ image_url: urlImage, url, id }, index) => (
|
||||
<fetcher.Form
|
||||
method="POST"
|
||||
action={`/actions/log/ads/${id}`}
|
||||
key={index}
|
||||
className="embla__slide max-h-[100px] min-h-[65px] w-full min-w-0 flex-none"
|
||||
>
|
||||
<Link
|
||||
to={link}
|
||||
className="mt-2 h-full py-2"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
<Button
|
||||
className="h-full w-full cursor-pointer py-2"
|
||||
type="submit"
|
||||
onClick={() => window.open(url, '_blank')}
|
||||
>
|
||||
<img
|
||||
src={urlImage}
|
||||
alt={id}
|
||||
className="h-[70px] w-[100%] object-contain object-center sm:h-full"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</Button>
|
||||
</fetcher.Form>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -51,6 +51,10 @@ export const AdvertisementsPage = () => {
|
||||
return formatDate(data)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Jumlah Klik',
|
||||
data: 'clicked',
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
data: 'id',
|
||||
@ -66,7 +70,7 @@ export const AdvertisementsPage = () => {
|
||||
/>
|
||||
)
|
||||
},
|
||||
5: (value: string, _type: unknown, data: TAdResponse) => (
|
||||
6: (value: string, _type: unknown, data: TAdResponse) => (
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
as="a"
|
||||
|
||||
48
app/routes/actions.log.ads.$id.ts
Normal file
48
app/routes/actions.log.ads.$id.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { data } from 'react-router'
|
||||
import { XiorError } from 'xior'
|
||||
|
||||
import { createLogAdsRequest } from '~/apis/news/create-log-ads'
|
||||
import { handleCookie } from '~/libs/cookies'
|
||||
|
||||
import type { Route } from './+types/actions.log.ads.$id'
|
||||
|
||||
export const action = async ({ request, params }: Route.ActionArgs) => {
|
||||
const { userToken: accessToken } = await handleCookie(request)
|
||||
const { id } = params
|
||||
try {
|
||||
const { data: logsData } = await createLogAdsRequest({
|
||||
id,
|
||||
accessToken,
|
||||
})
|
||||
|
||||
return data(
|
||||
{
|
||||
success: true,
|
||||
logsData,
|
||||
},
|
||||
{
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
},
|
||||
)
|
||||
} catch (error) {
|
||||
if (error instanceof XiorError) {
|
||||
return data(
|
||||
{
|
||||
success: false,
|
||||
message: error?.response?.data?.error?.message || error.message,
|
||||
},
|
||||
{
|
||||
status: error?.response?.status || 500,
|
||||
},
|
||||
)
|
||||
}
|
||||
return data(
|
||||
{
|
||||
success: false,
|
||||
message: 'Internal server error',
|
||||
},
|
||||
{ status: 500 },
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import { getValidatedFormData } from 'remix-hook-form'
|
||||
import { XiorError } from 'xior'
|
||||
|
||||
import { updateSubscribeRequest } from '~/apis/admin/update-subscribe'
|
||||
import { getUser } from '~/apis/news/get-user'
|
||||
import {
|
||||
subscribeSchema,
|
||||
type TSubscribeSchema,
|
||||
@ -34,18 +33,15 @@ export const action = async ({ request }: Route.ActionArgs) => {
|
||||
console.log('payload', payload) // eslint-disable-line no-console
|
||||
|
||||
// TODO: will run after payment success
|
||||
const { data: updateSubscribeData } = await updateSubscribeRequest({
|
||||
const { data: subscribeData } = await updateSubscribeRequest({
|
||||
payload,
|
||||
accessToken,
|
||||
})
|
||||
console.log(updateSubscribeData) // eslint-disable-line no-console
|
||||
|
||||
const { data: userData } = await getUser({ accessToken })
|
||||
|
||||
return data(
|
||||
{
|
||||
success: true,
|
||||
user: userData,
|
||||
subscribeData,
|
||||
},
|
||||
{
|
||||
status: 200,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user