feat: add app list context

This commit is contained in:
Joel
2025-10-24 18:33:54 +08:00
parent 0a7b59f500
commit b49a4eab62
3 changed files with 60 additions and 5 deletions

View File

@@ -6,6 +6,11 @@ import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
import type { App } from '@/models/explore'
import AppIcon from '@/app/components/base/app-icon'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { RiInformation2Line } from '@remixicon/react'
import { useCallback } from 'react'
import AppListContext from '@/context/app-list-context'
import { useContextSelector } from 'use-context-selector'
export type AppCardProps = {
app: App
@@ -19,6 +24,14 @@ const AppCard = ({
}: AppCardProps) => {
const { t } = useTranslation()
const { app: appBasicInfo } = app
const { systemFeatures } = useGlobalPublicStore()
const isTrialApp = app.can_trial && systemFeatures.enable_trial_app
const setShowTryAppPanel = useContextSelector(AppListContext, ctx => ctx.setShowTryAppPanel)
const showTryAPPPanel = useCallback((appId: string) => {
return () => {
setShowTryAppPanel?.(true, { appId, app })
}
}, [setShowTryAppPanel, app.category])
return (
<div className={cn('group relative flex h-[132px] cursor-pointer flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 shadow-xs hover:shadow-lg')}>
<div className='flex shrink-0 grow-0 items-center gap-3 pb-2'>
@@ -46,11 +59,17 @@ const AppCard = ({
</div>
</div>
<div className={cn('absolute bottom-0 left-0 right-0 hidden bg-gradient-to-t from-components-panel-gradient-2 from-[60.27%] to-transparent p-4 pt-8 group-hover:flex')}>
<div className={cn('flex h-8 w-full items-center space-x-2')}>
<Button variant='primary' className='grow' onClick={() => onCreate()}>
<div className={cn('w-full', isTrialApp && 'grid grid-cols-2 gap-2')}>
<Button variant='primary' className='w-full' onClick={() => onCreate()}>
<PlusIcon className='mr-1 h-4 w-4' />
<span className='text-xs'>{t('app.newApp.useTemplate')}</span>
</Button>
{isTrialApp && (
<Button className='w-full' onClick={showTryAPPPanel(app.app_id)}>
<RiInformation2Line className='mr-1 size-4' />
<span>{t('explore.appCard.try')}</span>
</Button>
)}
</div>
</div>
</div>

View File

@@ -3,6 +3,9 @@ import { useEducationInit } from '@/app/education-apply/hooks'
import List from './list'
import useDocumentTitle from '@/hooks/use-document-title'
import { useTranslation } from 'react-i18next'
import AppListContext from '@/context/app-list-context'
import { useState } from 'react'
import type { CurrentTryAppParams } from '@/context/explore-context'
const Apps = () => {
const { t } = useTranslation()
@@ -10,10 +13,26 @@ const Apps = () => {
useDocumentTitle(t('common.menus.apps'))
useEducationInit()
const [currentTryAppParams, setCurrentTryAppParams] = useState<CurrentTryAppParams | undefined>(undefined)
const [isShowTryAppPanel, setIsShowTryAppPanel] = useState(false)
const setShowTryAppPanel = (showTryAppPanel: boolean, params?: CurrentTryAppParams) => {
if (showTryAppPanel)
setCurrentTryAppParams(params)
else
setCurrentTryAppParams(undefined)
setIsShowTryAppPanel(showTryAppPanel)
}
return (
<div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body'>
<List />
</div >
<AppListContext.Provider value={{
currentApp: currentTryAppParams,
isShowTryAppPanel,
setShowTryAppPanel,
}}>
<div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body'>
<List />
</div >
</AppListContext.Provider>
)
}

View File

@@ -0,0 +1,17 @@
import { createContext } from 'use-context-selector'
import { noop } from 'lodash-es'
import type { CurrentTryAppParams } from './explore-context'
type Props = {
currentApp?: CurrentTryAppParams
isShowTryAppPanel: boolean
setShowTryAppPanel: (showTryAppPanel: boolean, params?: CurrentTryAppParams) => void
}
const AppListContext = createContext<Props>({
isShowTryAppPanel: false,
setShowTryAppPanel: noop,
currentApp: undefined,
})
export default AppListContext