155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
|
||
/**
|
||
* 直播切片专用字段:直播日期 / 主播(可关联用户)/ 直播平台
|
||
*/
|
||
|
||
'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>
|
||
</>
|
||
)
|
||
}
|