feat: refactor user handling in news components and add premium attribute logic

This commit is contained in:
Ardeman 2025-03-03 08:59:06 +08:00
parent a594227026
commit 1b4ff4c3e7
5 changed files with 24 additions and 4 deletions

View File

@ -2,7 +2,7 @@ import { z } from 'zod'
import { HttpServer, type THttpServer } from '~/libs/http-server' import { HttpServer, type THttpServer } from '~/libs/http-server'
const playerSchema = z.object({ const userSchema = z.object({
data: z.object({ data: z.object({
id: z.string(), id: z.string(),
email: z.string(), email: z.string(),
@ -12,10 +12,12 @@ const playerSchema = z.object({
}), }),
}) })
export type TUser = z.infer<typeof userSchema>
export const getUser = async (parameters: THttpServer) => { export const getUser = async (parameters: THttpServer) => {
try { try {
const { data } = await HttpServer(parameters).get(`/api/user/profile`) const { data } = await HttpServer(parameters).get(`/api/user/profile`)
return playerSchema.parse(data) return userSchema.parse(data)
} catch (error) { } catch (error) {
// eslint-disable-next-line unicorn/no-useless-promise-resolve-reject // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
return Promise.reject(error) return Promise.reject(error)

View File

@ -1,14 +1,18 @@
import useEmblaCarousel from 'embla-carousel-react' import useEmblaCarousel from 'embla-carousel-react'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { CarouselButton } from '~/components/ui/button-slide' import { CarouselButton } from '~/components/ui/button-slide'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CarouselHero = (properties: TNews) => { export const CarouselHero = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout')
const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties
const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false }) const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false })
@ -93,6 +97,7 @@ export const CarouselHero = (properties: TNews) => {
isPremium, isPremium,
slug, slug,
onClick: () => setIsSuccessOpen('warning'), onClick: () => setIsSuccessOpen('warning'),
userData,
})} })}
> >
View More View More

View File

@ -1,14 +1,18 @@
import useEmblaCarousel from 'embla-carousel-react' import useEmblaCarousel from 'embla-carousel-react'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { CarouselButton } from '~/components/ui/button-slide' import { CarouselButton } from '~/components/ui/button-slide'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CarouselSection = (properties: TNews) => { export const CarouselSection = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout')
const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties
const [emblaReference, emblaApi] = useEmblaCarousel({ const [emblaReference, emblaApi] = useEmblaCarousel({
loop: false, loop: false,
@ -115,6 +119,7 @@ export const CarouselSection = (properties: TNews) => {
isPremium, isPremium,
slug, slug,
onClick: () => setIsSuccessOpen('warning'), onClick: () => setIsSuccessOpen('warning'),
userData,
})} })}
className="mb-5" className="mb-5"
> >

View File

@ -1,14 +1,18 @@
import { useRouteLoaderData } from 'react-router'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { CarouselNextIcon } from '~/components/icons/carousel-next' import { CarouselNextIcon } from '~/components/icons/carousel-next'
import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' import { CarouselPreviousIcon } from '~/components/icons/carousel-previous'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout'
import type { TNews } from '~/types/news' import type { TNews } from '~/types/news'
import { getPremiumAttribute } from '~/utils/render' import { getPremiumAttribute } from '~/utils/render'
export const CategorySection = (properties: TNews) => { export const CategorySection = (properties: TNews) => {
const { setIsSuccessOpen } = useNewsContext() const { setIsSuccessOpen } = useNewsContext()
const loaderData = useRouteLoaderData<typeof loader>('routes/_layout')
const userData = loaderData?.userData
const { title, description, items } = properties const { title, description, items } = properties
@ -86,6 +90,7 @@ export const CategorySection = (properties: TNews) => {
isPremium, isPremium,
slug, slug,
onClick: () => setIsSuccessOpen('warning'), onClick: () => setIsSuccessOpen('warning'),
userData,
})} })}
className="mb-5" className="mb-5"
> >

View File

@ -1,15 +1,18 @@
import type { MouseEventHandler } from 'react' import type { MouseEventHandler } from 'react'
import { Link } from 'react-router' import { Link } from 'react-router'
import type { TUser } from '~/apis/news/get-user'
type TGetPremiumAttribute = { type TGetPremiumAttribute = {
isPremium?: boolean isPremium?: boolean
slug: string slug: string
onClick: MouseEventHandler<HTMLElement> onClick: MouseEventHandler<HTMLElement>
userData?: TUser['data']
} }
export const getPremiumAttribute = (parameters: TGetPremiumAttribute) => { export const getPremiumAttribute = (parameters: TGetPremiumAttribute) => {
const { isPremium, slug, onClick } = parameters const { isPremium, slug, onClick, userData } = parameters
if (isPremium) { if (isPremium && (!userData || userData?.subscribe_plan_code === 'basic')) {
return { return {
onClick, onClick,
to: '', to: '',