|
1 | 1 | 'use client' |
2 | 2 |
|
3 | 3 | import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' |
4 | | -import { Edit, Mail, User } from 'lucide-react' |
| 4 | +import { Edit, Mail } from 'lucide-react' |
5 | 5 | import React, { useMemo } from 'react' |
6 | 6 |
|
7 | 7 | import { Button } from '@/components/ui/button' |
8 | 8 | import { Card } from '@/components/ui/card' |
| 9 | +import RecentActivity from '@/features/dashboard/components/RecentActivity' |
9 | 10 | import { getRandomAvatarColor } from '@/utils/avatarColors' |
10 | 11 |
|
11 | 12 | interface OrgRole { |
@@ -56,144 +57,120 @@ const DisplayUserProfile = ({ |
56 | 57 | }, [userProfileInfo]) |
57 | 58 |
|
58 | 59 | return ( |
59 | | - <Card className="flex h-full flex-col p-8 sm:py-6"> |
60 | | - <div className="bg-background mx-auto w-full rounded-lg"> |
61 | | - <div className="mb-8 flex items-start justify-between"> |
62 | | - <div className="flex items-center justify-center gap-32 space-x-6"> |
63 | | - <div className=""> |
64 | | - {userProfileInfo?.profileImg ? ( |
65 | | - <img |
66 | | - src={userProfileInfo.profileImg} |
67 | | - alt="Profile Preview" |
68 | | - className="h-48 w-48 rounded-full object-cover" |
69 | | - /> |
70 | | - ) : ( |
71 | | - <Avatar className="h-48 w-48"> |
72 | | - <AvatarImage |
73 | | - src="" |
74 | | - alt={userProfileInfo?.email || 'Unknown'} |
75 | | - /> |
76 | | - <AvatarFallback className="text-4xl"> |
77 | | - {userProfileInfo?.firstName?.[0]?.toUpperCase() || |
78 | | - userProfileInfo?.lastName?.[0]?.toUpperCase() || |
79 | | - '?'} |
80 | | - </AvatarFallback> |
81 | | - </Avatar> |
82 | | - )} |
83 | | - </div> |
84 | | - |
85 | | - <div className="flex flex-1 flex-col space-y-4"> |
86 | | - <div> |
87 | | - <h2 className="text-foreground mb-1 text-3xl font-bold"> |
88 | | - {userProfileInfo?.firstName} {userProfileInfo?.lastName} |
89 | | - </h2> |
90 | | - <p className="text-muted-foreground mb-2 flex items-center gap-2 text-lg font-medium"> |
91 | | - <User width={16} height={16} /> |
92 | | - {userProfileInfo?.username} |
93 | | - </p> |
94 | | - |
95 | | - <p className="text-muted-foreground mb-2 flex items-center gap-2 text-lg font-medium"> |
96 | | - <Mail width={16} height={16} /> |
97 | | - {userProfileInfo?.email} |
98 | | - </p> |
99 | | - </div> |
100 | | - |
101 | | - <div className="flex space-x-8"> |
102 | | - <div className="text-center"> |
103 | | - <div className="text-foreground text-2xl font-bold"> |
104 | | - {userProfileInfo?.userOrgRoles?.filter( |
105 | | - (role) => role.orgRole.name === 'owner', |
106 | | - ).length || 0} |
107 | | - </div> |
108 | | - <div className="text-muted-foreground text-sm font-medium"> |
109 | | - Organizations Owned |
110 | | - </div> |
111 | | - </div> |
112 | | - <div className="text-center"> |
113 | | - <div className="text-foreground text-2xl font-bold"> |
114 | | - {userProfileInfo?.userOrgRoles?.filter( |
115 | | - (role) => role.orgRole.name === 'member', |
116 | | - ).length || 0} |
117 | | - </div> |
118 | | - <div className="text-muted-foreground text-sm font-medium"> |
119 | | - Member organizations |
120 | | - </div> |
121 | | - </div> |
122 | | - </div> |
123 | | - </div> |
124 | | - </div> |
125 | | - |
| 60 | + <div className="space-y-6"> |
| 61 | + <div className="grid grid-cols-2 gap-6 md:grid-cols-3"> |
| 62 | + <Card className="relative col-span-1 flex flex-col items-center space-y-4 p-6 text-center shadow"> |
126 | 63 | <Button |
127 | | - variant={'ghost'} |
128 | | - type="button" |
| 64 | + variant="ghost" |
129 | 65 | size="icon" |
130 | 66 | onClick={toggleEditProfile} |
| 67 | + className="absolute top-4 right-4" |
131 | 68 | > |
132 | | - <span> |
133 | | - <Edit className="" /> |
134 | | - </span> |
| 69 | + <Edit className="h-4 w-4" /> |
135 | 70 | </Button> |
136 | | - </div> |
| 71 | + {userProfileInfo?.profileImg ? ( |
| 72 | + <img |
| 73 | + src={userProfileInfo.profileImg} |
| 74 | + alt="Profile" |
| 75 | + className="h-28 w-28 rounded-full object-cover" |
| 76 | + /> |
| 77 | + ) : ( |
| 78 | + <Avatar className="h-28 w-28"> |
| 79 | + <AvatarImage src="" alt={userProfileInfo?.email || 'Unknown'} /> |
| 80 | + <AvatarFallback className="text-2xl"> |
| 81 | + {userProfileInfo?.firstName?.[0]?.toUpperCase() || |
| 82 | + userProfileInfo?.lastName?.[0]?.toUpperCase() || |
| 83 | + '?'} |
| 84 | + </AvatarFallback> |
| 85 | + </Avatar> |
| 86 | + )} |
| 87 | + |
| 88 | + <div> |
| 89 | + <h2 className="text-2xl font-bold"> |
| 90 | + {userProfileInfo?.firstName} {userProfileInfo?.lastName} |
| 91 | + </h2> |
| 92 | + <p className="text-muted-foreground text-sm"> |
| 93 | + {userProfileInfo?.username} |
| 94 | + </p> |
| 95 | + <p className="text-muted-foreground flex items-center justify-center gap-1 text-sm"> |
| 96 | + <Mail className="h-4 w-4" /> |
| 97 | + {userProfileInfo?.email} |
| 98 | + </p> |
| 99 | + </div> |
137 | 100 |
|
138 | | - <div className="space-y-6"> |
139 | | - <div className="rounded-lg"> |
140 | | - <div className="mt-4"> |
141 | | - {orgPresent && orgPresent.length > 0 ? ( |
142 | | - <> |
143 | | - <div className="text-foreground mb-4 text-lg font-semibold"> |
144 | | - Organizations associated |
145 | | - </div> |
146 | | - <hr /> |
147 | | - <div className="mt-4 flex flex-wrap gap-2"> |
148 | | - {orgPresent.map((role) => { |
149 | | - const { bg, text } = getRandomAvatarColor( |
150 | | - role.organisation.name, |
151 | | - ) |
152 | | - return ( |
153 | | - <Card |
154 | | - key={role.id} |
155 | | - className="inline-flex items-center border px-3 py-1 text-xs font-medium" |
156 | | - > |
157 | | - {role.organisation.logoUrl ? ( |
158 | | - <img |
159 | | - src={role.organisation.logoUrl} |
160 | | - alt={role.organisation.name} |
161 | | - className="h-5 w-5 rounded-full object-cover" |
162 | | - /> |
163 | | - ) : ( |
164 | | - <Avatar className="h-8 w-8"> |
165 | | - <AvatarFallback |
166 | | - className={`${bg} ${text} text-xs font-bold`} |
167 | | - > |
168 | | - {role.organisation.name |
169 | | - .substring(0, 2) |
170 | | - .toUpperCase()} |
171 | | - </AvatarFallback> |
172 | | - </Avatar> |
173 | | - )} |
174 | | - <span className="pl-2">{role.organisation.name}</span> |
175 | | - </Card> |
176 | | - ) |
177 | | - })} |
178 | | - </div> |
179 | | - </> |
180 | | - ) : ( |
181 | | - <div className="flex h-full items-center justify-center border-t pt-6"> |
182 | | - <div className="text-center"> |
183 | | - <div className="mb-4 text-2xl font-bold"> |
184 | | - No Organization |
185 | | - </div> |
186 | | - <p className="text-lg"> |
187 | | - Get started by creating a new Organization |
188 | | - </p> |
189 | | - </div> |
190 | | - </div> |
191 | | - )} |
| 101 | + {/* Stats */} |
| 102 | + <div className="text-muted-foreground mt-2 grid w-full grid-cols-2 gap-4 text-sm"> |
| 103 | + <div className="text-center"> |
| 104 | + <p className="text-lg font-semibold"> |
| 105 | + {userProfileInfo?.userOrgRoles?.filter( |
| 106 | + (role) => role.orgRole.name === 'owner', |
| 107 | + ).length || 0} |
| 108 | + </p> |
| 109 | + <p>Organizations Owned</p> |
| 110 | + </div> |
| 111 | + <div className="text-center"> |
| 112 | + <p className="text-lg font-semibold"> |
| 113 | + {userProfileInfo?.userOrgRoles?.filter( |
| 114 | + (role) => role.orgRole.name === 'member', |
| 115 | + ).length || 0} |
| 116 | + </p> |
| 117 | + <p>Member Organizations</p> |
192 | 118 | </div> |
193 | 119 | </div> |
| 120 | + </Card> |
| 121 | + |
| 122 | + <div className="col-span-1 md:col-span-2"> |
| 123 | + <RecentActivity /> |
194 | 124 | </div> |
195 | 125 | </div> |
196 | | - </Card> |
| 126 | + |
| 127 | + <Card className="p-6"> |
| 128 | + {orgPresent && orgPresent.length > 0 ? ( |
| 129 | + <> |
| 130 | + <h3 className="mb-4 text-lg font-semibold"> |
| 131 | + Organizations Associated |
| 132 | + </h3> |
| 133 | + <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4"> |
| 134 | + {orgPresent.map((role) => { |
| 135 | + const { bg, text } = getRandomAvatarColor( |
| 136 | + role.organisation.name, |
| 137 | + ) |
| 138 | + return ( |
| 139 | + <Card |
| 140 | + key={role.id} |
| 141 | + className="inline-flex items-center border px-3 py-1 text-xs font-medium" |
| 142 | + > |
| 143 | + {role.organisation.logoUrl ? ( |
| 144 | + <img |
| 145 | + src={role.organisation.logoUrl} |
| 146 | + alt={role.organisation.name} |
| 147 | + className="h-12 w-12 rounded-full object-cover" |
| 148 | + /> |
| 149 | + ) : ( |
| 150 | + <Avatar className="h-12 w-12"> |
| 151 | + <AvatarFallback |
| 152 | + className={`${bg} ${text} text-xs font-bold`} |
| 153 | + > |
| 154 | + {role.organisation.name.substring(0, 2).toUpperCase()} |
| 155 | + </AvatarFallback> |
| 156 | + </Avatar> |
| 157 | + )} |
| 158 | + <span className="pl-2">{role.organisation.name}</span> |
| 159 | + </Card> |
| 160 | + ) |
| 161 | + })} |
| 162 | + </div> |
| 163 | + </> |
| 164 | + ) : ( |
| 165 | + <div className="text-center"> |
| 166 | + <div className="mb-2 text-2xl font-bold">No Organization</div> |
| 167 | + <p className="text-sm"> |
| 168 | + Get started by creating a new organization. |
| 169 | + </p> |
| 170 | + </div> |
| 171 | + )} |
| 172 | + </Card> |
| 173 | + </div> |
197 | 174 | ) |
198 | 175 | } |
199 | 176 |
|
|
0 commit comments