diff --git a/portal/api_mobile.go b/portal/api_mobile.go index 73dbf25..0307ec7 100644 --- a/portal/api_mobile.go +++ b/portal/api_mobile.go @@ -8,6 +8,7 @@ import ( "net/http" "strconv" "strings" + "time" "inou/lib" ) @@ -185,6 +186,12 @@ type APIDossierEntry struct { Name string `json:"name"` Relation string `json:"relation"` CanAdd bool `json:"can_add"` + Initials string `json:"initials"` + Color string `json:"color"` + Age string `json:"age"` // e.g. "8y", "42y", "" if unknown + DOB string `json:"dob"` // YYYY-MM-DD or "" + Sex int `json:"sex"` // 0=unknown, 1=male, 2=female + IsSelf bool `json:"is_self"` } type APIDashboardResponse struct { @@ -206,9 +213,15 @@ func handleAPIDashboard(w http.ResponseWriter, r *http.Request) { // Add self first dossiers = append(dossiers, APIDossierEntry{ GUID: formatHexID(d.DossierID), - Name: "", // Empty means "self" + Name: d.Name, Relation: "self", CanAdd: true, + Initials: apiInitials(d.Name), + Color: apiColor(d.DossierID), + Age: apiAge(d.DateOfBirth), + DOB: apiDOB(d.DateOfBirth), + Sex: d.Sex, + IsSelf: true, }) // Add others @@ -223,8 +236,13 @@ func handleAPIDashboard(w http.ResponseWriter, r *http.Request) { dossiers = append(dossiers, APIDossierEntry{ GUID: formatHexID(a.DossierID), Name: target.Name, - Relation: "other", // Relation removed from RBAC + Relation: relationName(a.Relation), CanAdd: (a.Ops & lib.PermWrite) != 0, + Initials: apiInitials(target.Name), + Color: apiColor(a.DossierID), + Age: apiAge(target.DateOfBirth), + DOB: apiDOB(target.DateOfBirth), + Sex: target.Sex, }) } @@ -306,3 +324,41 @@ func relationName(rel int) string { default: return "other" } } + +func apiInitials(name string) string { + parts := strings.Fields(name) + if len(parts) == 0 { return "?" } + first := []rune(parts[0]) + if len(parts) == 1 { + if len(first) == 0 { return "?" } + return strings.ToUpper(string(first[:1])) + } + last := []rune(parts[len(parts)-1]) + if len(first) == 0 || len(last) == 0 { return "?" } + return strings.ToUpper(string(first[:1]) + string(last[:1])) +} + +var apiAvatarColors = []string{ + "#C47A3D", "#5AAD8A", "#7E8FC2", "#C26E6E", + "#9A82B8", "#C2963D", "#6BA0B8", "#B87898", + "#7DAD6B", "#8B7D6B", +} + +func apiColor(id string) string { + if len(id) < 2 { return apiAvatarColors[0] } + b, _ := strconv.ParseUint(id[len(id)-2:], 16, 8) + return apiAvatarColors[b%uint64(len(apiAvatarColors))] +} + +func apiAge(dob string) string { + if len(dob) < 10 { return "" } + t, err := time.Parse("2006-01-02", dob[:10]) + if err != nil { return "" } + years := int(time.Since(t).Hours() / 8766) + return fmt.Sprintf("%dy", years) +} + +func apiDOB(dob string) string { + if len(dob) < 10 { return "" } + return dob[:10] +}