From 84bdead8bdd494516be71beed47358bd18aeaf42 Mon Sep 17 00:00:00 2001
From: Andreas Ellewsen <ae@uio.no>
Date: Tue, 18 Jan 2022 11:33:24 +0100
Subject: [PATCH] Make role info page match sketch

Resolves: GREG-177
---
 frontend/public/locales/en/common.json        |   2 +
 frontend/public/locales/nb/common.json        |   2 +
 frontend/public/locales/nn/common.json        |   3 +-
 frontend/src/interfaces/index.ts              |   2 +
 .../sponsor/guest/guestRoleInfo/index.tsx     | 113 +++++++++++++-----
 frontend/src/utils/index.ts                   |   1 +
 greg/api/serializers/role.py                  |  16 ++-
 7 files changed, 108 insertions(+), 31 deletions(-)

diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index c796419a..9c54bd7d 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -31,7 +31,9 @@
   },
   "sponsor": {
     "addRole": "Add role",
+    "roleInfoHead": "Changes",
     "roleInfoText": "You can change the start and end dates for the role.",
+    "contactPerson": "Contact person",
     "choose": "Choose",
     "details": "Details",
     "modifyEnd": "Change end date",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index ebb93f46..f7bd841a 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -31,7 +31,9 @@
   },
   "sponsor": {
     "addRole": "Legg til rolle",
+    "roleInfoHead": "Endringer",
     "roleInfoText": "Her kan du endre på start- og sluttdato for gjesterollen eller avslutte perioden",
+    "contactPerson": "Kontaktperson",
     "choose": "Velg",
     "details": "Detaljer",
     "modifyEnd": "Endre sluttdato",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index 5ba389a4..68cb2b61 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -1,6 +1,5 @@
 {
   "language": {
-    "languageName": "Språk",
     "change": "Bytt språk til {{lang}}"
   },
   "header": {
@@ -32,7 +31,9 @@
   },
   "sponsor": {
     "addRole": "Legg til rolle",
+    "roleInfoHead": "Endringar",
     "roleInfoText": "Her kan du endre på start- og sluttdato for gjesterolla eller avslutte perioden",
+    "contactPerson": "Kontaktperson",
     "choose": "Vel",
     "details": "Detaljer",
     "modifyEnd": "Endre sluttdato",
diff --git a/frontend/src/interfaces/index.ts b/frontend/src/interfaces/index.ts
index 04121b7b..59043ef3 100644
--- a/frontend/src/interfaces/index.ts
+++ b/frontend/src/interfaces/index.ts
@@ -51,6 +51,7 @@ export type Role = {
   start_date: Date
   end_date: Date
   max_days: number
+  contact_person_unit: string | null
 }
 
 export type FetchedRole = {
@@ -62,6 +63,7 @@ export type FetchedRole = {
   start_date: string
   end_date: string
   max_days: number
+  contact_person_unit: string | null
 }
 
 export interface User {
diff --git a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
index 82c67530..97790761 100644
--- a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
+++ b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx
@@ -1,16 +1,12 @@
 import format from 'date-fns/format'
 import { addDays } from 'date-fns/fp'
-import {
-  Button,
-  Paper,
-  Table,
-  TableBody,
-  TableCell,
-  TableContainer,
-  TableHead,
-  TableRow,
-  TextField,
-} from '@mui/material'
+import { Button, Table, TableBody, TextField } from '@mui/material'
+import TableHeadMui from '@mui/material/TableHead'
+import { styled } from '@mui/system'
+import TableContainerMui from '@mui/material/TableContainer'
+import TableRowMui from '@mui/material/TableRow'
+import TableCellMui from '@mui/material/TableCell'
+
 import Page from 'components/page'
 import { Guest } from 'interfaces'
 import { useTranslation } from 'react-i18next'
@@ -55,6 +51,45 @@ type RoleFormData = {
   start_date: Date
   end_date: Date
 }
+const TableHeadCell = styled(TableCellMui)({
+  fontWeight: 'bold',
+  border: 'none',
+})
+
+const TableHead = styled(TableHeadMui)(({ theme }) => ({
+  borderTop: '0',
+  borderLeft: '0',
+  borderRight: '0',
+  borderBottom: '3px solid',
+  borderColor: theme.palette.secondary.main,
+  borderRadius: '0',
+}))
+
+const TableRow = styled(TableRowMui)({
+  borderTop: '0',
+  borderLeft: '0',
+  borderRight: '0',
+  borderBottom: '0px solid',
+  borderColor: 'black',
+  borderRadius: '0',
+})
+
+const TableCell = styled(TableCellMui)({
+  borderBottom: 'none',
+})
+
+const TableContainer = styled(TableContainerMui)({
+  marginBottom: '0.8rem',
+  borderRadius: '1%',
+  borderStyle: 'solid',
+  borderColor: 'black',
+  borderWidth: '2px',
+  boxShadow: 'none',
+  paddingLeft: '50px',
+  paddingRight: '50px',
+  paddingTop: '25px',
+  paddingBottom: '25px',
+})
 
 export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
   const { pid, id } = useParams<GuestRoleInfoParams>()
@@ -101,7 +136,11 @@ export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
       })
   }
 
-  const { control, handleSubmit } = useForm()
+  const {
+    control,
+    handleSubmit,
+    formState: { isDirty, isValid },
+  } = useForm({ mode: 'onChange' })
   const onSubmit = handleSubmit(submit)
   return (
     <Page>
@@ -109,27 +148,31 @@ export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
         to={`/sponsor/guest/${pid}`}
         name={`${guest.first} ${guest.last}`}
       />
-      <h4>{t('sponsor.roleInfoText')}</h4>
+      <h4>{t('sponsor.roleInfoHead')}</h4>
+      <p>{t('sponsor.roleInfoText')}</p>
       <form onSubmit={onSubmit}>
-        <TableContainer component={Paper}>
+        <TableContainer>
           <Table sx={{ minWidth: 650 }} aria-label="simple table">
-            <TableHead sx={{ backgroundColor: 'primary.light' }}>
+            <TableHead sx={{ backgroundColor: 'none' }}>
               <TableRow>
-                <TableCell align="left">{t('sponsor.details')}</TableCell>
-                <TableCell />
-                <TableCell />
-                <TableCell />
+                <TableHeadCell align="left">
+                  {t('sponsor.details')}
+                </TableHeadCell>
               </TableRow>
             </TableHead>
             <TableBody>
               <TableRow>
-                <TableCell align="left">{t('common:role')}</TableCell>
+                <TableCell align="left" sx={{ fontWeight: 'bold' }}>
+                  {t('common:role')}
+                </TableCell>
                 <TableCell>
                   {i18n.language === 'en' ? roleInfo.name_en : roleInfo.name_nb}
                 </TableCell>
               </TableRow>
               <TableRow>
-                <TableCell align="left">{t('common:period')}</TableCell>
+                <TableCell align="left" sx={{ fontWeight: 'bold' }}>
+                  {t('common:period')}
+                </TableCell>
                 <TableCell align="left">
                   <Controller
                     name="start_date"
@@ -166,24 +209,38 @@ export default function GuestRoleInfo({ guest }: GuestRoleInfoProps) {
                     )}
                   />
                 </TableCell>
-                <TableCell>
-                  <Button color="secondary" onClick={endPeriod()}>
-                    {t('sponsor.endNow')}
-                  </Button>
-                </TableCell>
               </TableRow>
               <TableRow>
-                <TableCell align="left">{t('common:ou')}</TableCell>
+                <TableCell align="left" sx={{ fontWeight: 'bold' }}>
+                  {t('common:ou')}
+                </TableCell>
                 <TableCell align="left">
                   {i18n.language === 'en' ? roleInfo.ou_en : roleInfo.ou_nb}
                 </TableCell>
                 <TableCell align="left" />
               </TableRow>
+              <TableRow>
+                <TableCell align="left" sx={{ fontWeight: 'bold' }}>
+                  {t('sponsor.contactPerson')}
+                </TableCell>
+                <TableCell align="left">
+                  {roleInfo.contact_person_unit}
+                </TableCell>
+                <TableCell align="left" />
+              </TableRow>
             </TableBody>
           </Table>
         </TableContainer>
-        <Button variant="contained" color="secondary" type="submit">
+        <Button
+          variant="contained"
+          color="success"
+          type="submit"
+          disabled={!isDirty || !isValid}
+        >
           {t('button.save')}
+        </Button>{' '}
+        <Button color="primary" onClick={endPeriod()}>
+          {t('sponsor.endNow')}
         </Button>
       </form>
     </Page>
diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts
index 35eb41c8..ce96e719 100644
--- a/frontend/src/utils/index.ts
+++ b/frontend/src/utils/index.ts
@@ -138,6 +138,7 @@ export function parseRole(role: FetchedRole): Role {
     start_date: parseISO(role.start_date),
     end_date: parseISO(role.end_date),
     max_days: role.max_days,
+    contact_person_unit: role.contact_person_unit,
   }
 }
 
diff --git a/greg/api/serializers/role.py b/greg/api/serializers/role.py
index 72589d6e..99ad317d 100644
--- a/greg/api/serializers/role.py
+++ b/greg/api/serializers/role.py
@@ -6,6 +6,12 @@ from greg.models import Role, RoleType
 
 
 class RoleSerializer(serializers.ModelSerializer):
+    """
+    Serializer for use with GET.
+
+    When doing GET we want the complete orgunit object, not just the id.
+    """
+
     type = serializers.SlugRelatedField(
         queryset=RoleType.objects.all(), slug_field="identifier"
     )
@@ -23,14 +29,16 @@ class RoleSerializer(serializers.ModelSerializer):
             "updated",
             "type",
             "available_in_search",
+            "contact_person_unit",
         ]
+        read_only_fields = ["contact_person_unit"]
 
 
 class RoleWriteSerializer(RoleSerializer):
     """
-    Serializer for use with GET.
+    Serializer for use when writing.
 
-    When doing GET we want the complete orgunit object, not just the id.
+    When writing we only want the id of the orgunit object.
     """
 
     orgunit = IntegerField(source="orgunit_id")  # type: ignore
@@ -69,4 +77,8 @@ class SpecialRoleSerializer(serializers.ModelSerializer):
             "start_date",
             "end_date",
             "max_days",
+            "contact_person_unit",
+        ]
+        read_only_fields = [
+            "contact_person_unit",
         ]
-- 
GitLab