Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: impression du dossier social #1748

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions dashboard/src/scenes/person/components/InfosMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ export function InfosMain({ person, isMedicalFile }) {
</div>
</div>
<div className="tw-mt-4 tw-flex tw-flex-row tw-items-center tw-justify-center tw-gap-2">
{!!isMedicalFile && (
<button className="tw-block tw-px-2 tw-py-1 tw-text-sm tw-text-white tw-underline tw-opacity-80" onClick={() => window.print()}>
Imprimer
</button>
)}
<button className="tw-block tw-px-2 tw-py-1 tw-text-sm tw-text-white tw-underline tw-opacity-80" onClick={() => window.print()}>
Imprimer
</button>
<button
className={['tw-block tw-rounded tw-bg-white tw-px-2 tw-py-1 tw-text-sm', isMedicalFile ? '!tw-text-blue-900' : '!tw-text-main'].join(
' '
Expand Down
8 changes: 5 additions & 3 deletions dashboard/src/scenes/person/components/Summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import PassagesRencontres from './PassagesRencontres';
import OutOfActiveList from '../OutOfActiveList';
import MergeTwoPersons from '../MergeTwoPersons';
import { customFieldsPersonsSelector } from '../../../recoil/persons';
import { SummaryPrint } from './SummaryPrint';

export default function Summary({ person }) {
const user = useRecoilValue(userState);
Expand All @@ -18,7 +19,8 @@ export default function Summary({ person }) {

return (
<>
<div className="tw-grid tw-grid-cols-12 tw-gap-4 tw-pt-4">
{!process.env.REACT_APP_TEST_PLAYWRIGHT && <SummaryPrint person={person} />}
<div className="noprint tw-grid tw-grid-cols-12 tw-gap-4 tw-pt-4">
<div className="tw-col-span-3">
<InfosMain person={person} />
</div>
Expand All @@ -32,7 +34,7 @@ export default function Summary({ person }) {
</div>
{!['restricted-access'].includes(user.role) && (
<>
<div className="tw-grid tw-grid-cols-12 tw-gap-4 tw-pt-4">
<div className="noprint tw-grid tw-grid-cols-12 tw-gap-4 tw-pt-4">
<div className="tw-col-span-8 tw-flex tw-flex-col tw-gap-4">
{customFieldsPersons.map(({ name, fields }) => {
return <PersonCustomFields key={name} person={person} sectionName={name} fields={fields} />;
Expand All @@ -50,7 +52,7 @@ export default function Summary({ person }) {
</div>
</div>
</div>
<div className="tw-mt-4 tw-flex tw-justify-end tw-gap-2">
<div className="noprint tw-mt-4 tw-flex tw-justify-end tw-gap-2">
<MergeTwoPersons person={person} />
<OutOfActiveList person={person} />
<DeletePersonButton person={person} />
Expand Down
216 changes: 216 additions & 0 deletions dashboard/src/scenes/person/components/SummaryPrint.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { customFieldsPersonsSelector } from '../../../recoil/persons';
import { currentTeamAuthentifiedState, teamsState, userState, usersState } from '../../../recoil/auth';
import { dayjsInstance, formatDateTimeWithNameOfDay, formatDateWithNameOfDay, formatTime } from '../../../services/date';
import CustomFieldDisplay from '../../../components/CustomFieldDisplay';
import { CANCEL, DONE, getName } from '../../../recoil/actions';
import { PersonPopulated } from '../../../types/person';
import UserName from '../../../components/UserName';

export function SummaryPrint({ person }: { person: PersonPopulated }) {
const user = useRecoilValue(userState);
const users = useRecoilValue(usersState);
const team = useRecoilValue(currentTeamAuthentifiedState);
const teams = useRecoilValue(teamsState);
const customFieldsPersons = useRecoilValue(customFieldsPersonsSelector);
const actions = person.actions || [];
const personPassages = useMemo(
() => [...(person?.passages || [])].sort((r1, r2) => (dayjsInstance(r1.date).isBefore(dayjsInstance(r2.date), 'day') ? 1 : -1)),
[person]
);
const personRencontres = useMemo(
() => [...(person?.rencontres || [])].sort((r1, r2) => (dayjsInstance(r1.date).isBefore(dayjsInstance(r2.date), 'day') ? 1 : -1)),
[person]
);
const comments = useMemo(
() =>
[...(person?.comments || [])].sort((r1, r2) =>
dayjsInstance(r1.date || r1.createdAt).isBefore(dayjsInstance(r2.date || r2.createdAt), 'day') ? 1 : -1
),
[person]
);

console.log(actions);

return (
<div className="printonly">
<h1>Dossier social de {person?.name}</h1>
<small>extrait le {formatDateTimeWithNameOfDay()}</small>
<div className="tw-mx-0 tw-mt-8 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">Informations générales</h2>
</div>
<div>
{person.alertness && <div>Personne très vulnérable, ou ayant besoin d'une attention particulière</div>}
<div>
Date de naissance&nbsp;: <CustomFieldDisplay type="date" value={person.birthdate} />
</div>
<div>
Genre&nbsp;: <CustomFieldDisplay type="text" value={person.gender} />
</div>
<div>
Suivi·e depuis le : <CustomFieldDisplay type="date" value={person.followedSince || person.createdAt} />
</div>
{person.wanderingAt ? (
<div>
En rue depuis le :<CustomFieldDisplay type="date" value={person.wanderingAt} />
</div>
) : null}
<div>
Téléphone : <CustomFieldDisplay type="text" value={person.phone} />
</div>
</div>
<hr className="tw-my-8" />
{customFieldsPersons.map(({ name, fields }) => {
const enabledFields = fields.filter((f) => f.enabled || f.enabledTeams?.includes(team._id));
return (
<>
<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">{name}</h2>
</div>
<div>
{enabledFields.map((field) => {
return (
<div>
{field.label} : {person[field.name]}
</div>
);
})}
</div>
</>
);
})}
<hr className="tw-my-8" />
<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">Actions</h2>
</div>
<div>
{Boolean(actions.length > 0) &&
actions.map((action) => {
const date = formatDateWithNameOfDay([DONE, CANCEL].includes(action.status) ? action.completedAt : action.dueAt);
const time = action.withTime && action.dueAt ? ` ${formatTime(action.dueAt)}` : '';
return (
<div key={action._id}>
<div>
<b>{getName(action)}</b>
</div>
<div>{`${date}${time}`}</div>
{Boolean(action.categories) && (
<div>
Catégories :{' '}
{action.categories?.map((category: string) => (
<span key={category}>{category}</span>
))}
</div>
)}
{action.urgent ? <div>Action prioritaire</div> : null}
{action.description ? <div>Description : {action.description}</div> : null}
{action.status ? <div>Statut : {action.status}</div> : null}

<div>
<span>Créée par</span>
<UserName id={action.user} />
</div>
{Boolean(action.group) && <div>Action familiale</div>}
<div>
Équipe(s) :{' '}
{Array.isArray(action?.teams) ? (
action.teams.map((e: string) => {
const team = teams.find((u) => u._id === e);
return (
<div style={{ marginLeft: '20px' }} key={team?.name}>
{team?.name}
</div>
);
})
) : (
<span>{teams.find((u) => u._id === action.team)?.name}</span>
)}
</div>
<br />
</div>
);
})}
</div>

{!['restricted-access'].includes(user!.role) && (
<>
<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">Commentaires</h2>
</div>
<div>
{Boolean(comments.length > 0) &&
comments.map((comment) => (
<div key={comment._id}>
{Boolean(comment.urgent) && <div>Commentaire prioritaire</div>}
<div>Date : {formatDateTimeWithNameOfDay(comment.date || comment.createdAt)}</div>
{Boolean(comment.group) && <div>Commentaire familial</div>}
<div>
{(comment.comment || '').split('\n').map((e: string, i: number) => (
<p key={e + i} className="tw-mb-0">
{e}
</p>
))}
</div>
<br />
</div>
))}
</div>

<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">Passages</h2>
</div>
<div>
{Boolean(personPassages.length > 0) &&
personPassages.map((passage: any) => (
<div key={passage._id}>
<div>
<b>{formatDateTimeWithNameOfDay(passage.date || passage.createdAt)}</b>
</div>
<div>
{(passage.comment || '')
.split('\n')
.filter((e: string) => e)
.map((e: string, i: number) => (
<p key={e + i} className="tw-mb-0">
{e}
</p>
))}
</div>
<div>Créée par {users.find((e) => e._id === passage.user)?.name}</div>
<div className="tw-max-w-fit">{teams.find((u) => u._id === passage.team)?.name}</div>
<br />
</div>
))}
</div>
<div className="tw-mx-0 tw-mt-16 tw-mb-5 tw-flex tw-items-center">
<h2 className="tw-flex tw-justify-between tw-text-xl tw-font-extrabold">Rencontres</h2>
</div>
<div>
{Boolean(personRencontres.length > 0) &&
personRencontres.map((rencontre: any) => (
<div key={rencontre._id}>
<div>
<b>{formatDateTimeWithNameOfDay(rencontre.date || rencontre.createdAt)}</b>
</div>
<div>
{(rencontre.comment || '')
.split('\n')
.filter((e: string) => e)
.map((e: string, i: number) => (
<p key={e + i} className="tw-mb-0">
{e}
</p>
))}
</div>
<div>Créée par {users.find((e) => e._id === rencontre.user)?.name}</div>
<div className="tw-max-w-fit">{teams.find((u) => u._id === rencontre.team)?.name}</div>
<br />
</div>
))}
</div>
</>
)}
</div>
);
}
Loading