diff --git a/frontend/src/routes/sponsor/frontpage/index.tsx b/frontend/src/routes/sponsor/frontpage/index.tsx
index c509c658304ed5681817b236aa96d877456be24c..33833ef8a5914bbd79b9a4a41e7afe18de3396a7 100644
--- a/frontend/src/routes/sponsor/frontpage/index.tsx
+++ b/frontend/src/routes/sponsor/frontpage/index.tsx
@@ -13,6 +13,7 @@ import {
   TableContainer,
   TableHead,
   TableRow,
+  TableSortLabel,
   TextField,
   Typography,
 } from '@mui/material'
@@ -54,6 +55,14 @@ interface FrontPageProps {
   loading: boolean
 }
 
+type SortDirection = 'desc' | 'asc'
+type SortField = 'name' | 'role' | 'status' | 'endDate' | 'department'
+
+interface GuestRole {
+  guest: Guest
+  role: Role
+}
+
 const StyledTableRow = styled(TableRow)({
   borderTop: '0',
   borderLeft: '0',
@@ -172,22 +181,65 @@ const Status = ({ person, role }: StatusProps) => {
   }
 }
 
-const sortByDate = (
-  guestRole: { guest: Guest; role: Role }[]
-): { guest: Guest; role: Role }[] =>
-  guestRole.sort(
-    (a, b) => a.role.end_date.getTime() - b.role.end_date.getTime()
+function createGuestsRoles(guests: Guest[]): GuestRole[] {
+  const guestRoles: GuestRole[] = []
+  guests.forEach((guest) =>
+    guest.roles.forEach((role) => {
+      guestRoles.push({ guest, role })
+    })
+  )
+  return guestRoles
+}
+
+function sortByName(
+  guestA: Guest,
+  guestB: Guest,
+  direction: SortDirection
+): number {
+  const firstA = guestA.first.toLowerCase()
+  const firstB = guestB.first.toLowerCase()
+  if (firstA < firstB) {
+    return direction === 'asc' ? -1 : 1
+  }
+  if (firstA > firstB) {
+    return direction === 'asc' ? 1 : -1
+  }
+  return 0
+}
+
+function sortGuestsByName(guests: Guest[], direction: SortDirection) {
+  return createGuestsRoles(guests).sort((a, b) =>
+    sortByName(a.guest, b.guest, direction)
   )
+}
+
+function sortGuestRolesByEndDate(
+  guestRole: GuestRole[],
+  direction: SortDirection
+): GuestRole[] {
+  return guestRole.sort((a, b) => {
+    const aEndDate = a.role.end_date.getTime()
+    const bEndDate = b.role.end_date.getTime()
+
+    if (aEndDate < bEndDate) {
+      return direction === 'asc' ? -1 : 1
+    }
+    if (aEndDate > bEndDate) {
+      return direction === 'asc' ? 1 : -1
+    }
+    // Secondary sort on guest name, always asc
+    return sortByName(a.guest, b.guest, 'asc')
+  })
+}
 
-const sortByStatus = (guests: Guest[]): { guest: Guest; role: Role }[] => {
+function sortByStatus(guests: Guest[], direction: SortDirection): GuestRole[] {
   let activeRoleAndPerson: { guest: Guest; role: Role }[] = []
   let expiringRoleAndPerson: { guest: Guest; role: Role }[] = []
   let expiredRoleAndPerson: { guest: Guest; role: Role }[] = []
-  let status
 
   guests.forEach((guest) =>
     guest.roles.forEach((role) => {
-      ;[status] = calculateStatus(guest, role)
+      const [status] = calculateStatus(guest, role)
       if (status === 'active') {
         activeRoleAndPerson.push({ guest, role })
       } else if (status === 'expiring') {
@@ -198,13 +250,71 @@ const sortByStatus = (guests: Guest[]): { guest: Guest; role: Role }[] => {
     })
   )
 
-  activeRoleAndPerson = sortByDate(activeRoleAndPerson)
-  expiringRoleAndPerson = sortByDate(expiringRoleAndPerson)
-  expiredRoleAndPerson = sortByDate(expiredRoleAndPerson)
+  // Always use 'asc' for secondary sorting
+  activeRoleAndPerson = sortGuestRolesByEndDate(activeRoleAndPerson, 'asc')
+  expiringRoleAndPerson = sortGuestRolesByEndDate(expiringRoleAndPerson, 'asc')
+  expiredRoleAndPerson = sortGuestRolesByEndDate(expiredRoleAndPerson, 'asc')
 
-  return expiringRoleAndPerson
+  if (direction === 'asc') {
+    return expiringRoleAndPerson
+      .concat(activeRoleAndPerson)
+      .concat(expiredRoleAndPerson)
+  }
+  return expiredRoleAndPerson
     .concat(activeRoleAndPerson)
-    .concat(expiredRoleAndPerson)
+    .concat(expiringRoleAndPerson)
+}
+
+function sortGuestsByRoleName(guests: Guest[], direction: SortDirection) {
+  return createGuestsRoles(guests).sort((a, b) => {
+    const aRoleName = getRoleName(a.role).toLowerCase()
+    const bRoleName = getRoleName(b.role).toLowerCase()
+    if (aRoleName < bRoleName) {
+      return direction === 'asc' ? -1 : 1
+    }
+    if (aRoleName > bRoleName) {
+      return direction === 'asc' ? 1 : -1
+    }
+    // Secondary sort on guest name, always asc
+    return sortByName(a.guest, b.guest, 'asc')
+  })
+}
+
+function sortGuestsByDepartmentName(guests: Guest[], direction: SortDirection) {
+  return createGuestsRoles(guests).sort((a, b) => {
+    const aRoleOUName = getRoleOuName(a.role).toLowerCase()
+    const bRoleOUName = getRoleOuName(b.role).toLowerCase()
+    if (aRoleOUName < bRoleOUName) {
+      return direction === 'asc' ? -1 : 1
+    }
+    if (aRoleOUName > bRoleOUName) {
+      return direction === 'asc' ? 1 : -1
+    }
+    // Secondary sort on guest name, always asc
+    return sortByName(a.guest, b.guest, 'asc')
+  })
+}
+
+function sortGuestsAndRoles(
+  guests: Guest[],
+  sortField: SortField,
+  direction: SortDirection
+): { guest: Guest; role: Role }[] {
+  switch (sortField) {
+    case 'department':
+      return sortGuestsByDepartmentName(guests, direction)
+    case 'endDate':
+      return sortGuestRolesByEndDate(createGuestsRoles(guests), direction)
+    case 'name':
+      return sortGuestsByName(guests, direction)
+    case 'role':
+      return sortGuestsByRoleName(guests, direction)
+    case 'status':
+      return sortByStatus(guests, direction)
+    default:
+      // Fallback to original sort
+      return createGuestsRoles(guests)
+  }
 }
 
 const PersonLine = ({ person, role }: PersonLineProps) => {
@@ -236,6 +346,17 @@ const PersonLine = ({ person, role }: PersonLineProps) => {
 const GuestTable = ({ guests, emptyText, marginWidth }: GuestTableProps) => {
   const { t } = useTranslation('common')
 
+  const [direction, setDirection] = useState<SortDirection>('asc')
+  const [orderBy, setOrderBy] = useState<SortField>('status')
+
+  const handleRequestSort =
+    (sortBy: SortField) => (event: React.MouseEvent<unknown>) => {
+      event.preventDefault()
+      const isAsc = orderBy === sortBy && direction === 'asc'
+      setDirection(isAsc ? 'desc' : 'asc')
+      setOrderBy(sortBy)
+    }
+
   return (
     <TableContainer
       component={Paper}
@@ -248,17 +369,63 @@ const GuestTable = ({ guests, emptyText, marginWidth }: GuestTableProps) => {
       <Table sx={{ minWidth: marginWidth }} aria-label="simple table">
         <StyledTableHead>
           <TableRow>
-            <StyledTableHeadCell>{t('common:name')}</StyledTableHeadCell>
-            <StyledTableHeadCell>{t('common:role')}</StyledTableHeadCell>
-            <StyledTableHeadCell>{t('common:status')}</StyledTableHeadCell>
-            <StyledTableHeadCell>{t('common:endDate')}</StyledTableHeadCell>
-            <StyledTableHeadCell>{t('common:department')}</StyledTableHeadCell>
+            <StyledTableHeadCell>
+              <TableSortLabel
+                key="name"
+                active={orderBy === 'name'}
+                direction={orderBy === 'name' ? direction : 'asc'}
+                onClick={handleRequestSort('name')}
+              >
+                {t('common:name')}
+              </TableSortLabel>
+            </StyledTableHeadCell>
+            <StyledTableHeadCell>
+              <TableSortLabel
+                key="role"
+                active={orderBy === 'role'}
+                direction={orderBy === 'role' ? direction : 'asc'}
+                onClick={handleRequestSort('role')}
+              >
+                {t('common:role')}
+              </TableSortLabel>
+            </StyledTableHeadCell>
+
+            <StyledTableHeadCell>
+              <TableSortLabel
+                key="status"
+                active={orderBy === 'status'}
+                direction={orderBy === 'status' ? direction : 'asc'}
+                onClick={handleRequestSort('status')}
+              >
+                {t('common:status')}
+              </TableSortLabel>
+            </StyledTableHeadCell>
+            <StyledTableHeadCell>
+              <TableSortLabel
+                key="endDate"
+                active={orderBy === 'endDate'}
+                direction={orderBy === 'endDate' ? direction : 'asc'}
+                onClick={handleRequestSort('endDate')}
+              >
+                {t('common:endDate')}
+              </TableSortLabel>
+            </StyledTableHeadCell>
+            <StyledTableHeadCell>
+              <TableSortLabel
+                key="department"
+                active={orderBy === 'department'}
+                direction={orderBy === 'department' ? direction : 'asc'}
+                onClick={handleRequestSort('department')}
+              >
+                {t('common:department')}
+              </TableSortLabel>
+            </StyledTableHeadCell>
             <StyledTableHeadCell />
           </TableRow>
         </StyledTableHead>
         <TableBody>
           {guests.length > 0 ? (
-            sortByStatus(guests).map((personRole) => (
+            sortGuestsAndRoles(guests, orderBy, direction).map((personRole) => (
               <PersonLine
                 key={`${personRole.guest.first} ${personRole.guest.last} ${personRole.role.id}`}
                 role={personRole.role}
@@ -267,7 +434,7 @@ const GuestTable = ({ guests, emptyText, marginWidth }: GuestTableProps) => {
             ))
           ) : (
             <StyledTableRow>
-              <TableCell> {emptyText}</TableCell>
+              <TableCell>{emptyText}</TableCell>
             </StyledTableRow>
           )}
         </TableBody>