This commit is contained in:
oneao committed 2026-02-28 17:02:35 +08:00
1 parent fc005e0fb4
commit 10d0cadfe3
18 files changed
+591 -133

No files matched your search

+1 -1
View File
@@ -127,7 +127,7 @@ export default function Auth() {
// avatar: loginRes.data.avatar,
// })
// router.push('/auth/space')
// router.push('/space/manage')
// }
// }
// catch (err) {
@@ -1,237 +0,0 @@
import type { UserSpace } from '@/types/space'
import { useCallback, useEffect, useState } from 'react'
import { Pressable, Text, View } from 'react-native'
import Animated, { useAnimatedRef } from 'react-native-reanimated'
import Sortable from 'react-native-sortables'
import { toast } from 'sonner-native'
import { AButton, ADivider, AInput, LucideIcon } from '@/components/common/ao'
import { AModal } from '@/components/common/ao/index'
import EmptyState from '@/components/common/EmptyStatus'
import CustomHeader from '@/components/custom/Header'
import { Badge, BadgeText } from '@/components/ui/badge'
import { createSpaceApi, listUserSpacesApi } from '@/request/api/space/index'
import { useUserStore } from '@/store/user'
export default function AuthSpace() {
const userStore = useUserStore()
const scrollableRef = useAnimatedRef<Animated.ScrollView>()
const [selectedId, setSelectedId] = useState<number | null>(null)
// 新建
const [createOpen, setCreateOpen] = useState(false)
const [createForm, setCreateForm] = useState({
name: '',
})
const [spaces, setSpaces] = useState<UserSpace[]>([])
function listUserSpaces() {
listUserSpacesApi().then((res) => {
if (res.isSuccess) {
setSpaces(res.data.spaces)
}
})
}
const renderItem
= ({ item }: { item: UserSpace }) => (
<Pressable
key={item.id}
onPress={() => setSelectedId(item.id)}
className={`rounded-md flex-row items-center justify-between px-4 py-3 border
${item.id === selectedId ? 'border-gray-700' : 'border-gray-300'}`}
>
<View className="flex-row items-center">
<Sortable.Handle>
<LucideIcon
icon="Grip"
size={20}
className="mr-4"
/>
</Sortable.Handle>
<View>
<View className="flex-row items-center gap-2">
<Text
className="font-semibold text-gray-900"
>
{item.name}
</Text>
{
item.owner_id === userStore.userInfo.id && (
<Badge size="sm" variant="solid" action="muted">
<BadgeText>创建者</BadgeText>
</Badge>
)
}
{
item.is_default === 1 && (
<Badge size="sm" variant="solid" action="info">
<BadgeText>默认</BadgeText>
</Badge>
)
}
</View>
<View className="flex-row items-center gap-3 mt-2">
<View className="flex-row gap-1">
<LucideIcon icon="UserRound" size={12} />
<Text
className="text-xs"
>
{item.user_name}
</Text>
</View>
<View className="flex-row gap-1">
<LucideIcon icon="UsersRound" size={12} />
<Text
className={`text-xs `}
>
{item.member_count}
</Text>
</View>
</View>
</View>
</View>
<LucideIcon
icon="Bolt"
size={20}
className="p-1"
/>
</Pressable>
)
useEffect(() => {
listUserSpaces()
}, [])
return (
<View className="flex-1 bg-white">
{/* Header */}
<CustomHeader title="空间列表" />
<View className="flex-1 px-4">
<View className="">
<Text className="text-sm text-gray-500 mb-2">
选择或创建空间
</Text>
<View className="flex-row gap-3">
<AButton
className="flex-1 rounded-full"
size="sm"
leftIcon={<LucideIcon icon="Plus" color="#fff" />}
onPress={() => setCreateOpen(true)}
>
创建新空间
</AButton>
<AButton
variant="outline"
className="flex-1 rounded-full"
size="sm"
leftIcon={<LucideIcon icon="HousePlus" />}
>
加入其他空间
</AButton>
</View>
</View>
<ADivider text="我的空间" className="py-2" />
<Animated.ScrollView
className="flex-1"
showsVerticalScrollIndicator={false}
ref={scrollableRef}
>
{spaces.length === 0
? (
<View className="flex-1 items-center justify-center mt-12">
<EmptyState
title="暂无空间"
description="请选择 创建 或 加入 空间"
/>
</View>
)
: (
<Sortable.Grid
scrollableRef={scrollableRef}
activeItemScale={1}
columns={1}
data={spaces}
overDrag="vertical"
renderItem={renderItem}
rowGap={10}
highlight-next-line
customHandle
autoScrollActivationOffset={200}
/>
)}
</Animated.ScrollView>
<View className="py-2">
<AButton size="sm" leftIcon={<LucideIcon icon="CircleArrowRight" color="#fff" />}>进入空间</AButton>
</View>
</View>
<AModal
title="创建新空间"
showCloseIcon
body={
(
<View className="gap-2">
<Text>空间名称</Text>
<AInput
className="flex-1"
value={createForm.name}
onChangeText={(val) => {
setCreateForm(prev => ({
...prev,
name: val,
}))
}}
/>
</View>
)
}
isOpen={createOpen}
onCancel={() => {
setCreateOpen(false)
setCreateForm({
name: '',
})
}}
onClose={() => {
setCreateOpen(false)
setCreateForm({
name: '',
})
}}
onConfirm={async () => {
if (!createForm.name) {
toast.warning('请输入空间名称')
return
}
await createSpaceApi({
name: createForm.name,
user_name: userStore.userInfo.nickname,
sort_number: 0,
}).then((res) => {
if (res.isSuccess) {
toast.success('创建成功')
setCreateOpen(false)
setCreateForm({
name: '',
})
}
})
}}
>
</AModal>
</View>
)
}