Can set member country
This commit is contained in:
		@@ -148,6 +148,17 @@ export class Member implements MemberDataApi {
 | 
			
		||||
      day: this.death_day,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get hasContactInfo(): boolean {
 | 
			
		||||
    return this.email ||
 | 
			
		||||
      this.phone ||
 | 
			
		||||
      this.address ||
 | 
			
		||||
      this.city ||
 | 
			
		||||
      this.postal_code ||
 | 
			
		||||
      this.country
 | 
			
		||||
      ? true
 | 
			
		||||
      : false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function fmtDate(d?: DateValue): string {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import ClearIcon from "@mui/icons-material/Clear";
 | 
			
		||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
			
		||||
import EditIcon from "@mui/icons-material/Edit";
 | 
			
		||||
import FileDownloadIcon from "@mui/icons-material/FileDownload";
 | 
			
		||||
import SaveIcon from "@mui/icons-material/Save";
 | 
			
		||||
import { Button, Grid, Stack } from "@mui/material";
 | 
			
		||||
import * as EmailValidator from "email-validator";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import FileDownloadIcon from "@mui/icons-material/FileDownload";
 | 
			
		||||
import { useNavigate, useParams } from "react-router-dom";
 | 
			
		||||
import { Member, MemberApi } from "../../api/MemberApi";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
@@ -16,15 +16,16 @@ import { AsyncWidget } from "../../widgets/AsyncWidget";
 | 
			
		||||
import { useFamily } from "../../widgets/BaseFamilyRoute";
 | 
			
		||||
import { ConfirmLeaveWithoutSaveDialog } from "../../widgets/ConfirmLeaveWithoutSaveDialog";
 | 
			
		||||
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
 | 
			
		||||
import { MemberPhoto } from "../../widgets/MemberPhoto";
 | 
			
		||||
import { PropertiesBox } from "../../widgets/PropertiesBox";
 | 
			
		||||
import { RouterLink } from "../../widgets/RouterLink";
 | 
			
		||||
import { DateInput } from "../../widgets/forms/DateInput";
 | 
			
		||||
import { MemberInput } from "../../widgets/forms/MemberInput";
 | 
			
		||||
import { PropCheckbox } from "../../widgets/forms/PropCheckbox";
 | 
			
		||||
import { PropEdit } from "../../widgets/forms/PropEdit";
 | 
			
		||||
import { PropSelect } from "../../widgets/forms/SelectInput";
 | 
			
		||||
import { SexSelection } from "../../widgets/forms/SexSelection";
 | 
			
		||||
import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
 | 
			
		||||
import { MemberPhoto } from "../../widgets/MemberPhoto";
 | 
			
		||||
import { RouterLink } from "../../widgets/RouterLink";
 | 
			
		||||
import { MemberInput } from "../../widgets/forms/MemberInput";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new member route
 | 
			
		||||
@@ -494,34 +495,50 @@ export function MemberPage(p: {
 | 
			
		||||
        </Grid>
 | 
			
		||||
 | 
			
		||||
        {/* Contact */}
 | 
			
		||||
        <Grid item sm={12} md={6}>
 | 
			
		||||
          <PropertiesBox title="Contact">
 | 
			
		||||
            {/* Email */}
 | 
			
		||||
            <PropEdit
 | 
			
		||||
              label="Adresse mail"
 | 
			
		||||
              editable={p.editing}
 | 
			
		||||
              value={member.email}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                member.email = v;
 | 
			
		||||
                updatedMember();
 | 
			
		||||
              }}
 | 
			
		||||
              size={ServerApi.Config.constraints.member_email}
 | 
			
		||||
              checkValue={(e) => EmailValidator.validate(e)}
 | 
			
		||||
            />
 | 
			
		||||
        {(p.editing || member.hasContactInfo) && (
 | 
			
		||||
          <Grid item sm={12} md={6}>
 | 
			
		||||
            <PropertiesBox title="Contact">
 | 
			
		||||
              {/* Email */}
 | 
			
		||||
              <PropEdit
 | 
			
		||||
                label="Adresse mail"
 | 
			
		||||
                editable={p.editing}
 | 
			
		||||
                value={member.email}
 | 
			
		||||
                onValueChange={(v) => {
 | 
			
		||||
                  member.email = v;
 | 
			
		||||
                  updatedMember();
 | 
			
		||||
                }}
 | 
			
		||||
                size={ServerApi.Config.constraints.member_email}
 | 
			
		||||
                checkValue={(e) => EmailValidator.validate(e)}
 | 
			
		||||
              />
 | 
			
		||||
 | 
			
		||||
            {/* Phone number */}
 | 
			
		||||
            <PropEdit
 | 
			
		||||
              label="Téléphone"
 | 
			
		||||
              editable={p.editing}
 | 
			
		||||
              value={member.phone}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                member.phone = v;
 | 
			
		||||
                updatedMember();
 | 
			
		||||
              }}
 | 
			
		||||
              size={ServerApi.Config.constraints.member_phone}
 | 
			
		||||
            />
 | 
			
		||||
          </PropertiesBox>
 | 
			
		||||
        </Grid>
 | 
			
		||||
              {/* Phone number */}
 | 
			
		||||
              <PropEdit
 | 
			
		||||
                label="Téléphone"
 | 
			
		||||
                editable={p.editing}
 | 
			
		||||
                value={member.phone}
 | 
			
		||||
                onValueChange={(v) => {
 | 
			
		||||
                  member.phone = v;
 | 
			
		||||
                  updatedMember();
 | 
			
		||||
                }}
 | 
			
		||||
                size={ServerApi.Config.constraints.member_phone}
 | 
			
		||||
              />
 | 
			
		||||
 | 
			
		||||
              {/* Country */}
 | 
			
		||||
              <PropSelect
 | 
			
		||||
                label="Pays"
 | 
			
		||||
                editing={p.editing}
 | 
			
		||||
                onValueChange={(o) => {
 | 
			
		||||
                  member.country = o;
 | 
			
		||||
                  updatedMember();
 | 
			
		||||
                }}
 | 
			
		||||
                value={member.country}
 | 
			
		||||
                options={ServerApi.Config.countries.map((c) => {
 | 
			
		||||
                  return { label: c.fr, value: c.code };
 | 
			
		||||
                })}
 | 
			
		||||
              />
 | 
			
		||||
            </PropertiesBox>
 | 
			
		||||
          </Grid>
 | 
			
		||||
        )}
 | 
			
		||||
 | 
			
		||||
        {/* Bio */}
 | 
			
		||||
        <Grid item sm={12} md={6}>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,8 @@ export function PropEdit(p: {
 | 
			
		||||
  label: string;
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  value?: string;
 | 
			
		||||
  onValueChange: (newVal: string | undefined) => void;
 | 
			
		||||
  size: LenConstraint;
 | 
			
		||||
  onValueChange?: (newVal: string | undefined) => void;
 | 
			
		||||
  size?: LenConstraint;
 | 
			
		||||
  checkValue?: (s: string) => boolean;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  if (((!p.editable && p.value) ?? "") === "") return <></>;
 | 
			
		||||
@@ -19,12 +19,12 @@ export function PropEdit(p: {
 | 
			
		||||
      label={p.label}
 | 
			
		||||
      value={p.value}
 | 
			
		||||
      onChange={(e) =>
 | 
			
		||||
        p.onValueChange(
 | 
			
		||||
        p.onValueChange?.(
 | 
			
		||||
          e.target.value.length === 0 ? undefined : e.target.value
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
      inputProps={{
 | 
			
		||||
        maxLength: p.size.max,
 | 
			
		||||
        maxLength: p.size?.max,
 | 
			
		||||
      }}
 | 
			
		||||
      InputProps={{
 | 
			
		||||
        readOnly: !p.editable,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								geneit_app/src/widgets/forms/SelectInput.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								geneit_app/src/widgets/forms/SelectInput.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
 | 
			
		||||
import { PropEdit } from "./PropEdit";
 | 
			
		||||
 | 
			
		||||
export interface SelectOption {
 | 
			
		||||
  value: string;
 | 
			
		||||
  label: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function PropSelect(p: {
 | 
			
		||||
  value?: string;
 | 
			
		||||
  editing: boolean;
 | 
			
		||||
  label: string;
 | 
			
		||||
  options: SelectOption[];
 | 
			
		||||
  onValueChange: (o?: string) => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  if (!p.editing && !p.value) return <></>;
 | 
			
		||||
 | 
			
		||||
  if (!p.editing) {
 | 
			
		||||
    const value = p.options.find((o) => o.value === p.value)?.label;
 | 
			
		||||
    return <PropEdit label={p.label} editable={p.editing} value={value} />;
 | 
			
		||||
  }
 | 
			
		||||
  return (
 | 
			
		||||
    <FormControl fullWidth variant="filled">
 | 
			
		||||
      <InputLabel>{p.label}</InputLabel>
 | 
			
		||||
      <Select
 | 
			
		||||
        value={p.value}
 | 
			
		||||
        label={p.label}
 | 
			
		||||
        onChange={(e) => p.onValueChange(e.target.value)}
 | 
			
		||||
      >
 | 
			
		||||
        {p.options.map((e) => (
 | 
			
		||||
          <MenuItem key={e.value} value={e.value}>
 | 
			
		||||
            {e.label}
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
        ))}
 | 
			
		||||
      </Select>
 | 
			
		||||
    </FormControl>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user