Added persistent statuses.
This commit is contained in:
@@ -12,11 +12,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^15.0.3",
|
||||
"@react-navigation/bottom-tabs": "^7.5.0",
|
||||
"@react-navigation/elements": "^2.7.0",
|
||||
"@react-navigation/native": "^7.1.18",
|
||||
"@react-navigation/bottom-tabs": "^7.6.0",
|
||||
"@react-navigation/elements": "^2.7.1",
|
||||
"@react-navigation/native": "^7.1.19",
|
||||
"@sentry/react-native": "^7.4.0",
|
||||
"expo": "~54.0.19",
|
||||
"expo": "~54.0.20",
|
||||
"expo-apple-authentication": "~8.0.7",
|
||||
"expo-constants": "~18.0.10",
|
||||
"expo-font": "~14.0.9",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-switch": "^1.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@sentry/nextjs": "^10.21.0",
|
||||
"@sentry/nextjs": "^10.22.0",
|
||||
"@t3-oss/env-nextjs": "^0.13.8",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
@@ -10,9 +10,11 @@ import {
|
||||
Button,
|
||||
Card,
|
||||
CardContent,
|
||||
Checkbox,
|
||||
Drawer,
|
||||
DrawerTrigger,
|
||||
Input,
|
||||
Label,
|
||||
SubmitButton,
|
||||
Tabs,
|
||||
TabsContent,
|
||||
@@ -49,6 +51,7 @@ export const StatusList = ({
|
||||
const [selectedUserIds, setSelectedUserIds] = useState<Id<'users'>[]>([]);
|
||||
const [selectAll, setSelectAll] = useState(false);
|
||||
const [statusInput, setStatusInput] = useState('');
|
||||
const [persistStatus, setPersistStatus] = useState(false);
|
||||
const [updatingStatus, setUpdatingStatus] = useState(false);
|
||||
const [animatingIds, setAnimatingIds] = useState<Set<string>>(new Set());
|
||||
const [previousStatuses, setPreviousStatuses] = useState(statuses);
|
||||
@@ -98,11 +101,24 @@ export const StatusList = ({
|
||||
throw new Error('Status must be between 3 & 80 characters');
|
||||
}
|
||||
if (selectedUserIds.length === 0 && user?.id) {
|
||||
await bulkCreate({ message, userIds: [user.id] });
|
||||
await bulkCreate({
|
||||
message,
|
||||
userIds: [user.id],
|
||||
persistentStatus: persistStatus
|
||||
});
|
||||
} else {
|
||||
await bulkCreate({ message, userIds: selectedUserIds });
|
||||
await bulkCreate({
|
||||
message,
|
||||
userIds: selectedUserIds,
|
||||
persistentStatus: persistStatus
|
||||
});
|
||||
}
|
||||
toast.success('Status updated.');
|
||||
toast.success('Status updated.', {
|
||||
duration: 2000,
|
||||
closeButton: true,
|
||||
dismissible: true,
|
||||
});
|
||||
setSelectedUserIds([]);
|
||||
setSelectAll(false);
|
||||
setStatusInput('');
|
||||
@@ -149,13 +165,13 @@ export const StatusList = ({
|
||||
<TabsList className={tabsCn}>
|
||||
<TabsTrigger value='status' className='py-3 sm:py-8'>
|
||||
<div className='flex items-center gap-2 sm:gap-3'>
|
||||
<Activity className='text-primary w-4 h-4 sm:w-5 sm:h-5' />
|
||||
<h1 className='text-base sm:text-2xl font-bold'>Team Status</h1>
|
||||
<Activity className='text-primary sm:scale-150' />
|
||||
<h1 className='text-base sm:text-2xl font-bold'>Status List</h1>
|
||||
</div>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value='history' className='py-3 sm:py-8'>
|
||||
<div className='flex items-center gap-2 sm:gap-3'>
|
||||
<History className='text-primary w-4 h-4 sm:w-5 sm:h-5' />
|
||||
<History className='text-primary sm:scale-150' />
|
||||
<h1 className='text-base sm:text-2xl font-bold'>
|
||||
Status History
|
||||
</h1>
|
||||
@@ -216,6 +232,7 @@ export const StatusList = ({
|
||||
className={`
|
||||
relative rounded-xl border transition-all
|
||||
${isAnimating ? 'bg-primary/5 border-primary/30' : ''}
|
||||
${s?.persistentStatus ? 'bg-black/10' : ''}
|
||||
${
|
||||
isSelected
|
||||
? 'border-primary bg-primary/5'
|
||||
@@ -236,7 +253,7 @@ export const StatusList = ({
|
||||
|
||||
<div className='flex items-start gap-3 sm:gap-4'>
|
||||
{/* Avatar */}
|
||||
<div className='flex-shrink-0'>
|
||||
<div className='shrink-0'>
|
||||
<BasedAvatar
|
||||
src={u.imageUrl}
|
||||
fullName={u.name ?? 'User'}
|
||||
@@ -295,11 +312,7 @@ export const StatusList = ({
|
||||
</div>
|
||||
{/* Meta - only show here when NOT in TV mode */}
|
||||
{!tvMode && (
|
||||
<div
|
||||
className={`
|
||||
flex items-center text-muted-foreground gap-3 sm:gap-4
|
||||
`}
|
||||
>
|
||||
<div className='flex items-center text-muted-foreground gap-3 sm:gap-4'>
|
||||
<div className='flex items-center gap-1.5'>
|
||||
<Clock className='w-4 h-4 sm:w-4 sm:h-4' />
|
||||
<span className='text-sm sm:text-lg'>
|
||||
@@ -401,17 +414,29 @@ export const StatusList = ({
|
||||
>
|
||||
<CardContent className='p-6'>
|
||||
<div className='flex flex-col gap-4'>
|
||||
<div className='flex items-center gap-3'>
|
||||
<Zap className='w-5 h-5 text-primary' />
|
||||
<h3 className='text-lg font-semibold'>Update Status</h3>
|
||||
{selectedUserIds.length > 0 && (
|
||||
<span
|
||||
className='px-2 py-1 bg-primary/10 text-primary
|
||||
text-sm rounded-full'
|
||||
>
|
||||
{selectedUserIds.length} selected
|
||||
</span>
|
||||
)}
|
||||
<div className='flex gap-3 w-full justify-between'>
|
||||
<div className='flex gap-3 items-center'>
|
||||
<Zap className='w-6 h-6 text-primary' />
|
||||
<h3 className='text-xl font-semibold'>Update Status</h3>
|
||||
{selectedUserIds.length > 0 && (
|
||||
<span
|
||||
className='px-2 py-1 bg-primary/10 text-primary
|
||||
text-sm rounded-full'
|
||||
>
|
||||
{selectedUserIds.length} selected
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex space-x-2 items-center'>
|
||||
<Checkbox
|
||||
checked={persistStatus}
|
||||
className='border border-primary'
|
||||
onCheckedChange={() => setPersistStatus(!persistStatus)}
|
||||
/>
|
||||
<Label>
|
||||
Persist Status
|
||||
</Label>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex gap-3'>
|
||||
<Input
|
||||
@@ -469,7 +494,7 @@ export const StatusList = ({
|
||||
<div
|
||||
className='md:hidden fixed bottom-0 left-0 right-0 z-50
|
||||
border-t bg-background/95 backdrop-blur
|
||||
supports-[backdrop-filter]:bg-background/60 p-3
|
||||
supports-backdrop-filter:bg-background/60 p-3
|
||||
pb-[calc(0.75rem+env(safe-area-inset-bottom))]'
|
||||
>
|
||||
<div className='flex items-center justify-between mb-2'>
|
||||
@@ -482,6 +507,16 @@ export const StatusList = ({
|
||||
Update your status
|
||||
</span>
|
||||
)}
|
||||
<div className='flex flex-row space-x-2'>
|
||||
<Checkbox
|
||||
className='border border-primary'
|
||||
checked={persistStatus}
|
||||
onCheckedChange={() => setPersistStatus(!persistStatus)}
|
||||
/>
|
||||
<Label className='text-xs'>
|
||||
Persist Status
|
||||
</Label>
|
||||
</div>
|
||||
<Button variant='outline' size='sm' onClick={handleSelectAll}>
|
||||
{selectAll ? 'Clear' : 'Select all'}
|
||||
</Button>
|
||||
|
||||
@@ -51,7 +51,8 @@ export const formatDate = (timestamp: Timestamp, locale = 'en-US'): string => {
|
||||
const date = toDate(timestamp);
|
||||
if (!date) return '--/--';
|
||||
return date.toLocaleDateString(locale, {
|
||||
month: 'long',
|
||||
weekday: 'long',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user