Skip to content

Commit

Permalink
Readd animations
Browse files Browse the repository at this point in the history
  • Loading branch information
albi005 committed Nov 15, 2024
1 parent dad8167 commit 1de3070
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 133 deletions.
311 changes: 179 additions & 132 deletions frontend/app/groups/[id]/activity/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { AnimatePresence, motion } from 'framer-motion';
import { AwardIcon, ChevronDownIcon, StarIcon, UserIcon } from 'lucide-react';

Check failure on line 4 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (backend) / eslint-check

'ChevronDownIcon' is defined but never used

Check failure on line 4 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (frontend) / eslint-check

'ChevronDownIcon' is defined but never used
import Link from 'next/link';
import { useState } from 'react';
Expand Down Expand Up @@ -69,149 +70,195 @@ export default function GroupSemesterScores() {

return (
<div className='min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 text-gray-900 p-4 sm:p-8'>
<Card className='overflow-hidden shadow-lg'>
<CardHeader className='p-6 sm:p-8 bg-gradient-to-r from-blue-500 to-purple-500'>
<div className='flex flex-col sm:flex-row items-center sm:items-start gap-6'>
<Avatar className='h-32 w-32 border-4 border-white shadow-lg'>
<AvatarImage src='/placeholder.svg?height=128&width=128' alt={groupData.name} />
<AvatarFallback className='text-4xl bg-white text-blue-500'>
{groupData.name
.split(' ')
.map((n) => n[0])
.join('')}
</AvatarFallback>
</Avatar>
<div className='text-center sm:text-left'>
<CardTitle className='text-3xl sm:text-4xl font-bold text-white mb-2'>{groupData.name}</CardTitle>
<CardDescription className='text-lg text-blue-100'>
<Select value={selectedSemester} onValueChange={setSelectedSemester}>
<SelectTrigger className='border-none bg-white/20 text-white hover:bg-white/30 transition-colors'>
<SelectValue placeholder='Select semester' />
</SelectTrigger>
<SelectContent>
{groupData.semesters.map((semester) => (
<SelectItem key={semester} value={semester}>
{semester}
</SelectItem>
))}
</SelectContent>
</Select>
</CardDescription>
</div>
<div className='sm:ml-auto flex gap-2'>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant='ghost' size='icon' className='text-white hover:bg-white/20'>
<UserIcon className='h-5 w-5' />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Group Members</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant='ghost' size='icon' className='text-white hover:bg-white/20'>
<StarIcon className='h-5 w-5' />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Group Achievements</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
</CardHeader>
<CardContent className='p-6'>
<div className='grid gap-4 sm:grid-cols-2'>
<div className='flex items-center justify-between bg-blue-100 rounded-lg p-4'>
<div className='flex items-center space-x-2'>
<UserIcon className='h-6 w-6 text-blue-600' />
<span className='text-sm font-medium text-blue-800'>Total Members</span>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className='max-w-5xl mx-auto space-y-8'
>
<Card className='overflow-hidden shadow-lg'>
<CardHeader className='p-6 sm:p-8 bg-gradient-to-r from-blue-500 to-purple-500'>
<div className='flex flex-col sm:flex-row items-center sm:items-start gap-6'>
<Avatar className='h-32 w-32 border-4 border-white shadow-lg'>
<AvatarImage src='/placeholder.svg?height=128&width=128' alt={groupData.name} />
<AvatarFallback className='text-4xl bg-white text-blue-500'>
{groupData.name
.split(' ')
.map((n) => n[0])
.join('')}
</AvatarFallback>
</Avatar>
<div className='text-center sm:text-left'>
<CardTitle className='text-3xl sm:text-4xl font-bold text-white mb-2'>{groupData.name}</CardTitle>
<CardDescription className='text-lg text-blue-100'>
<Select value={selectedSemester} onValueChange={setSelectedSemester}>
<SelectTrigger className='border-none bg-white/20 text-white hover:bg-white/30 transition-colors'>
<SelectValue placeholder='Select semester' />
</SelectTrigger>
<SelectContent>
{groupData.semesters.map((semester) => (
<SelectItem key={semester} value={semester}>
{semester}
</SelectItem>
))}
</SelectContent>
</Select>
</CardDescription>
</div>
<div className='sm:ml-auto flex gap-2'>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant='ghost' size='icon' className='text-white hover:bg-white/20'>
<UserIcon className='h-5 w-5' />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Group Members</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant='ghost' size='icon' className='text-white hover:bg-white/20'>
<StarIcon className='h-5 w-5' />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Group Achievements</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<span className='text-2xl font-bold text-blue-600'>{totalMembers}</span>
</div>
<div className='flex items-center justify-between bg-purple-100 rounded-lg p-4'>
<div className='flex items-center space-x-2'>
<StarIcon className='h-6 w-6 text-purple-600' />
<span className='text-sm font-medium text-purple-800'>Entry Cards</span>
</CardHeader>
<CardContent className='p-6'>
<div className='grid gap-4 sm:grid-cols-2'>
<div className='flex items-center justify-between bg-blue-100 rounded-lg p-4'>
<div className='flex items-center space-x-2'>
<UserIcon className='h-6 w-6 text-blue-600' />
<span className='text-sm font-medium text-blue-800'>Total Members</span>
</div>
<span className='text-2xl font-bold text-blue-600'>{totalMembers}</span>
</div>
<div className='flex items-center justify-between bg-purple-100 rounded-lg p-4'>
<div className='flex items-center space-x-2'>
<StarIcon className='h-6 w-6 text-purple-600' />
<span className='text-sm font-medium text-purple-800'>Entry Cards</span>
</div>
<span className='text-2xl font-bold text-purple-600'>{entryCards}</span>
</div>
<span className='text-2xl font-bold text-purple-600'>{entryCards}</span>
</div>
</div>
</CardContent>
</Card>
</CardContent>
</Card>

<Card className='overflow-hidden shadow-lg'>
<CardHeader className='bg-gradient-to-r from-yellow-400 to-orange-500 p-6'>
<CardTitle className='text-2xl font-bold flex items-center text-white'>
<AwardIcon className='mr-2 h-8 w-8' />
Group Leader's Praise
</CardTitle>
</CardHeader>
<CardContent className='p-6'>
<p className='text-gray-700 italic'>&ldquo;{groupData.leaderPraise}&rdquo;</p>
</CardContent>
</Card>
<AnimatePresence>
<motion.div
key='leader-praise'
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.5 }}
>
<Card className='overflow-hidden shadow-lg'>
<CardHeader className='bg-gradient-to-r from-yellow-400 to-orange-500 p-6'>
<CardTitle className='text-2xl font-bold flex items-center text-white'>
<AwardIcon className='mr-2 h-8 w-8' />
Group Leader's Praise

Check failure on line 168 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (backend) / eslint-check

`'` can be escaped with `&apos;`, `&lsquo;`, `&#39;`, `&rsquo;`

Check failure on line 168 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (frontend) / eslint-check

`'` can be escaped with `&apos;`, `&lsquo;`, `&#39;`, `&rsquo;`
</CardTitle>
</CardHeader>
<CardContent className='p-6'>
<p className='text-gray-700 italic'>&ldquo;{groupData.leaderPraise}&rdquo;</p>
</CardContent>
</Card>
</motion.div>
</AnimatePresence>

<Card className='overflow-hidden shadow-lg'>
<CardHeader className='bg-gradient-to-r from-green-400 to-blue-500 p-6'>
<CardTitle className='text-2xl font-bold flex items-center text-white'>
<UserIcon className='mr-2 h-8 w-8' />
Member Contributions
</CardTitle>
</CardHeader>
<CardContent className='p-6'>
<div className='overflow-x-auto'>
<Table>
<TableHeader>
<TableRow>
<TableHead className='w-[40%]'>Name</TableHead>
<TableHead>Score</TableHead>
<TableHead>Award Class</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{groupData.members.map((member, index) => (
<tr key={member.id}>
<TableCell className='font-medium'>
<Link
href={`/profile/${member.id}`}
className='text-blue-600 hover:text-blue-800 transition-colors duration-200'
>
{member.name}
</Link>
{(member.awardClass === 'AB' || member.awardClass === 'KB') && <>{member.comment}</>}
</TableCell>
<TableCell>
<span className='font-semibold text-gray-700'>{member.score}</span>
</TableCell>
<TableCell>
<Badge
variant={
member.awardClass === 'AB' ? 'default' : member.awardClass === 'KB' ? 'secondary' : 'outline'
}
className={`
<AnimatePresence>
<motion.div
key='member-contributions'
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.5, delay: 0.2 }}
>
<Card className='overflow-hidden shadow-lg'>
<CardHeader className='bg-gradient-to-r from-green-400 to-blue-500 p-6'>
<CardTitle className='text-2xl font-bold flex items-center text-white'>
<UserIcon className='mr-2 h-8 w-8' />
Member Contributions
</CardTitle>
</CardHeader>
<CardContent className='p-6'>
<div className='overflow-x-auto'>
<Table>
<TableHeader>
<TableRow>
<TableHead className='flex-1'>Name</TableHead>
<TableHead>Score</TableHead>
<TableHead className='w-32 text-center'>Award Class</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{groupData.members.map((member, index) => (
<motion.tr
key={member.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, delay: index * 0.05 }}
className='group hover:bg-gray-50'
>
<TableCell className='font-medium'>
<Link
href={`/profile/${member.id}`}
className='text-blue-600 hover:text-blue-800 transition-colors duration-200'
>
{member.name}
</Link>
{(member.awardClass === 'AB' || member.awardClass === 'KB') && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
transition={{ duration: 0.3 }}
className='text-sm text-gray-600 mt-1'
>
{member.comment}
</motion.div>
)}
</TableCell>
<TableCell>
<span className='font-semibold text-gray-700 text-center'>{member.score}</span>
</TableCell>
<TableCell className='text-center'>
<Badge
variant={
member.awardClass === 'AB'

Check failure on line 236 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (backend) / eslint-check

Do not nest ternary expressions

Check failure on line 236 in frontend/app/groups/[id]/activity/page.tsx

View workflow job for this annotation

GitHub Actions / analysis (frontend) / eslint-check

Do not nest ternary expressions
? 'default'
: member.awardClass === 'KB'
? 'secondary'
: 'outline'
}
className={`
${member.awardClass === 'AB' ? 'bg-amber-500 hover:bg-amber-600 text-white' : ''}
${member.awardClass === 'KB' ? 'bg-blue-500 hover:bg-blue-600 text-white' : ''}
${member.awardClass === 'DO' ? 'bg-gray-500 hover:bg-gray-600 text-white' : ''}
transition-all duration-300 ease-in-out transform hover:scale-105
`}
>
{member.awardClass}
</Badge>
</TableCell>
</tr>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
>
{member.awardClass}
</Badge>
</TableCell>
</motion.tr>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
</motion.div>
</AnimatePresence>
</motion.div>
</div>
);
}
2 changes: 1 addition & 1 deletion frontend/components/client-side-profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function ClientSideProfile() {
const { data: me, status, error } = useAuthMe({ query: { retry: false } });
if (status === 'pending') return <h1>Loading...</h1>;
if (status === 'error' && error.status === 401) return <h1>Client: Anonymous</h1>;
if (status === 'error') return <h1>Something went wrong {error.response.data.message}</h1>;
if (status === 'error') return <h1>Something went wrong {error?.response?.data?.message}</h1>;

return <h1>Client: {me.name}</h1>;
}
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"axios": "^1.7.7",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"framer-motion": "^11.11.17",
"js-cookie": "^3.0.5",
"lucide-react": "^0.441.0",
"next": "14.2.11",
Expand Down
21 changes: 21 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7071,6 +7071,26 @@ __metadata:
languageName: node
linkType: hard

"framer-motion@npm:^11.11.17":
version: 11.11.17
resolution: "framer-motion@npm:11.11.17"
dependencies:
tslib: "npm:^2.4.0"
peerDependencies:
"@emotion/is-prop-valid": "*"
react: ^18.0.0
react-dom: ^18.0.0
peerDependenciesMeta:
"@emotion/is-prop-valid":
optional: true
react:
optional: true
react-dom:
optional: true
checksum: 10c0/4ec88a568e636c5409a238668770a7d0237270b4b58fdf27d0cab1f9094a4fdd22d25d827a1bba51e52f01e9d2db65544b32a5feb8eff9a63c8798f2e64677d0
languageName: node
linkType: hard

"fresh@npm:0.5.2":
version: 0.5.2
resolution: "fresh@npm:0.5.2"
Expand Down Expand Up @@ -7108,6 +7128,7 @@ __metadata:
eslint: "npm:^8.57.0"
eslint-config-next: "npm:14.2.11"
eslint-plugin-react: "npm:^7.36.1"
framer-motion: "npm:^11.11.17"
js-cookie: "npm:^3.0.5"
lucide-react: "npm:^0.441.0"
next: "npm:14.2.11"
Expand Down

0 comments on commit 1de3070

Please sign in to comment.