diff --git a/src/components/UserCard.tsx b/src/components/UserCard.tsx
index af4efe1..0d8958e 100644
--- a/src/components/UserCard.tsx
+++ b/src/components/UserCard.tsx
@@ -9,7 +9,7 @@ const UserCard: React.FC<{ user: User }> = ({ user }) => {
{user.bio}
{user.specialties.map((s) => (
- {s}
+ {s} ({user.endorsements[s] ?? 0})
))}
diff --git a/src/routes/Profile.tsx b/src/routes/Profile.tsx
index 5091b77..5e9d434 100644
--- a/src/routes/Profile.tsx
+++ b/src/routes/Profile.tsx
@@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom'
import useAppStore from '../store/useAppStore'
import EndorseButton from '../components/EndorseButton'
import UserCard from '../components/UserCard'
+import { formatTime } from '../utils/fileHelpers'
const Profile: React.FC = () => {
const { id } = useParams<{ id: string }>()
@@ -10,6 +11,8 @@ const Profile: React.FC = () => {
const posts = useAppStore((s) => s.posts.filter((p) => p.authorId === id))
const endorseUser = useAppStore((s) => s.endorseUser)
const currentUserId = useAppStore((s) => s.currentUserId)
+ const endorsementHistory = useAppStore((s) => s.endorsementHistory)
+ const allUsers = useAppStore((s) => s.users)
if (!user) return User not found
@@ -31,6 +34,20 @@ const Profile: React.FC = () => {
+ {(() => {
+ const recent = endorsementHistory.filter((e) => e.type === 'user' && e.toUserId === id).slice(0,5)
+ if (recent.length === 0) return null
+ return (
+
+
Recent endorsements
+ {recent.map((r) => {
+ const byName = allUsers.find((u) => u.id === r.by)?.name ?? 'Someone'
+ return
{byName} endorsed {r.specialty} ยท {formatTime(r.createdAt)} ago
+ })}
+
+ )
+ })()}
+
Posts
{posts.length === 0 && No posts yet.
}
{posts.map((p) => (
diff --git a/src/store/useAppStore.ts b/src/store/useAppStore.ts
index ca256d2..3bd4fb1 100644
--- a/src/store/useAppStore.ts
+++ b/src/store/useAppStore.ts
@@ -11,6 +11,7 @@ type AppState = {
currentUserId: string | null
selectedPostId: string | null
ui: UIState
+ endorsementHistory: { id: string; type: 'user' | 'post'; by?: string | null; toUserId?: string; postId?: string; specialty?: string; createdAt: number }[]
seedData: () => void
createUser: (data: { name: string; email: string; bio: string; specialties: string[] }) => User
setCurrentUser: (id: string | null) => void
@@ -30,6 +31,7 @@ const useAppStore = create((set, get) => ({
currentUserId: null,
selectedPostId: null,
ui: { isCreatePostOpen: false },
+ endorsementHistory: [],
seedData: () => {
const users = seedUsers()
@@ -69,6 +71,7 @@ const useAppStore = create((set, get) => ({
},
endorseUser: (userId, specialty) => {
+ const by = get().currentUserId ?? null
set((state) => ({
users: state.users.map((u) => {
if (u.id !== userId) return u
@@ -76,15 +79,20 @@ const useAppStore = create((set, get) => ({
current[specialty] = (current[specialty] || 0) + 1
return { ...u, endorsements: current }
}),
+ endorsementHistory: [{ id: makeId(), type: 'user', by, toUserId: userId, specialty, createdAt: Date.now() }, ...(state.endorsementHistory || [])],
}))
},
+
endorsePost: (postId) => {
+ const by = get().currentUserId ?? null
set((state) => ({
posts: state.posts.map((p) => (p.id === postId ? { ...p, endorsements: p.endorsements + 1 } : p)),
+ endorsementHistory: [{ id: makeId(), type: 'post', by, postId, createdAt: Date.now() }, ...(state.endorsementHistory || [])],
}))
},
+
attachPDFToPost: (postId, file) => {
const url = URL.createObjectURL(file)
set((state) => ({