gongxiangp2/components/upload/LiveClipFields.tsx

155 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 直播切片专用字段:直播日期 / 主播(可关联用户)/ 直播平台
*/
'use client'
import Select from '@/components/ui/Select'
import { useEffect, useState } from 'react'
import {
fieldControlClass,
fieldHintClass,
fieldLabelClass,
} from '@/components/upload/upload-field-styles'
import {
getDefaultLiveDate,
LIVE_CLIP_PLATFORMS,
} from '@/lib/live-clip'
export interface LiveClipFieldsProps {
liveDate: string
liveHost: string
liveHostUserId: string
livePlatform: string
onLiveDateChange: (value: string) => void
onLiveHostChange: (value: string) => void
onLiveHostUserIdChange: (value: string) => void
onLivePlatformChange: (value: string) => void
}
interface UserOption {
id: string
displayName: string
username: string
}
export default function LiveClipFields({
liveDate,
liveHost,
liveHostUserId,
livePlatform,
onLiveDateChange,
onLiveHostChange,
onLiveHostUserIdChange,
onLivePlatformChange,
}: LiveClipFieldsProps) {
const [users, setUsers] = useState<UserOption[]>([])
const [usersLoaded, setUsersLoaded] = useState(false)
useEffect(() => {
if (!liveDate) {
onLiveDateChange(getDefaultLiveDate())
}
// 仅在日期为空时补默认值,避免依赖回调导致循环
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
let cancelled = false
fetch('/api/users/list')
.then((res) => (res.ok ? res.json() : []))
.then((data: UserOption[]) => {
if (!cancelled && Array.isArray(data)) {
setUsers(data)
setUsersLoaded(true)
}
})
.catch(() => {
if (!cancelled) setUsersLoaded(true)
})
return () => {
cancelled = true
}
}, [])
return (
<>
<div>
<label htmlFor="liveDate" className={fieldLabelClass}>
直播日期
</label>
<input
id="liveDate"
type="date"
value={liveDate}
onChange={(e) => onLiveDateChange(e.target.value)}
className={fieldControlClass}
max={getDefaultLiveDate()}
/>
<p className={`mt-2 ${fieldHintClass}`}>默认上传当天,可按日历修改</p>
</div>
<div>
<label htmlFor="liveHost" className={fieldLabelClass}>
主播 <span className={`ml-1 font-normal ${fieldHintClass}`}>(可选)</span>
</label>
<input
id="liveHost"
type="text"
value={liveHost}
onChange={(e) => onLiveHostChange(e.target.value)}
className={fieldControlClass}
maxLength={50}
placeholder="填写主播昵称"
/>
<label htmlFor="liveHostUserId" className={`${fieldLabelClass} mt-4 block`}>
关联用户 <span className={`ml-1 font-normal ${fieldHintClass}`}>(可选,便于按人筛选)</span>
</label>
<Select
id="liveHostUserId"
value={liveHostUserId}
onChange={(e) => {
const userId = e.target.value
onLiveHostUserIdChange(userId)
if (userId) {
const matched = users.find((u) => u.id === userId)
if (matched && !liveHost.trim()) {
onLiveHostChange(matched.displayName)
}
}
}}
className={fieldControlClass}
>
<option value="">{usersLoaded ? '不关联用户' : '加载用户…'}</option>
{users.map((user) => (
<option key={user.id} value={user.id}>
{user.displayName}
</option>
))}
</Select>
</div>
<div>
<label htmlFor="livePlatform" className={fieldLabelClass}>
直播平台
</label>
<Select
id="livePlatform"
value={livePlatform}
onChange={(e) => onLivePlatformChange(e.target.value)}
className={fieldControlClass}
>
<option value="">请选择平台</option>
{LIVE_CLIP_PLATFORMS.map((platform) => (
<option key={platform} value={platform}>
{platform}
</option>
))}
</Select>
</div>
</>
)
}