104 Commits

Author SHA1 Message Date
8652007906 Update dependency @fontsource/roboto to v5.0.12
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-03-04 00:11:35 +00:00
29c18807d8 Update Rust crate base64 to 0.22.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-03-03 00:21:16 +00:00
eb00b4e7b8 Update dependency @mui/x-data-grid to v6.19.6
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-03-03 00:12:39 +00:00
61082619fe Update Rust crate tempfile to 3.10.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-27 00:12:21 +00:00
79126ebbd7 Update dependency @mui/icons-material to v5.15.11
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-25 00:11:44 +00:00
d87f04b76b Update dependency @mui/x-data-grid to v6.19.5
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-24 00:18:24 +00:00
da476ea4d7 Update Rust crate image to 0.24.9
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-24 00:12:14 +00:00
0266c0c8b3 Update dependency vite to v5.1.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-22 00:11:53 +00:00
5863c346d0 Update dependency vite to v5.1.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-17 00:12:29 +00:00
b0087f2dfb Update dependency vite to v5.1.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-15 00:11:50 +00:00
97340b4ae8 Update dependency @mui/icons-material to v5.15.10
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-13 00:12:14 +00:00
7dcc5e1d29 Update Rust crate thiserror to 1.0.57
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-12 00:12:44 +00:00
240d830526 Update dependency vite to v5.1.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-10 00:20:06 +00:00
c1e7ed9034 Update dependency @mui/x-data-grid to v6.19.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-10 00:12:35 +00:00
8324f9c501 Update dependency vite to v5.1.0
All checks were successful
continuous-integration/drone/push Build is passing
2024-02-09 00:18:19 +00:00
d715a61255 Update dependency @mui/icons-material to v5.15.9
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-09 00:12:25 +00:00
eaee7f601e Update dependency @mui/icons-material to v5.15.8
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-07 00:12:02 +00:00
042776d491 Update Rust crate tempfile to 3.10.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-06 00:12:34 +00:00
900f6b8af8 Update Rust crate actix-web to 4.5.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-05 00:31:52 +00:00
86ada0da5d Update dependency @mui/x-data-grid to v6.19.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-02 00:33:46 +00:00
3d59629f7a Update dependency @mui/icons-material to v5.15.7
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-02-01 00:30:54 +00:00
dffc00382a Update dependency react-easy-crop to v5.0.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-31 00:30:57 +00:00
2dd9fc3469 Update dependency @mui/x-data-grid to v6.19.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-26 00:31:35 +00:00
cfd0cb37f5 Update dependency @mui/icons-material to v5.15.6
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-23 00:31:43 +00:00
d14557ac49 Update dependency @mui/x-data-grid to v6.19.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-20 00:40:40 +00:00
e188949ac0 Update dependency vite to v5.0.12
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-20 00:31:40 +00:00
d2bddb62bc Update dependency @mui/icons-material to v5.15.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-18 00:31:02 +00:00
b382f6bb85 Merge pull request 'Update Rust crate serde_json to 1.0.110' (#65) from renovate/serde_json-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #65
2024-01-16 18:32:11 +00:00
16ccb39b36 Update Rust crate image to 0.24.8
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-14 00:26:28 +00:00
60cc8a2401 Update Rust crate base64 to 0.21.7
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-12 00:09:51 +00:00
11715864a4 Update dependency @mui/icons-material to v5.15.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-11 00:10:35 +00:00
a79febee92 Update Rust crate base64 to 0.21.6
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-09 00:09:37 +00:00
554188e511 Update Rust crate actix-cors to 0.7.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-07 00:10:00 +00:00
a628bdee49 Update dependency vite to v5.0.11
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-06 00:14:51 +00:00
873a2aae95 Update dependency @mui/x-data-grid to v6.18.7
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-06 00:09:36 +00:00
1fe01ff893 Update dependency @mui/lab to v5.0.0-alpha.159
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-05 00:09:42 +00:00
ceb0f11128 Update dependency @mui/x-data-grid to v6.18.6
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-04 00:38:54 +00:00
bf3562c9e0 Update dependency @mui/icons-material to v5.15.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-04 00:35:43 +00:00
1251d61352 Update Rust crate thiserror to 1.0.56
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-04 00:28:26 +00:00
f2a58b5dcd Update Rust crate serde_json to 1.0.110
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-01-04 00:28:14 +00:00
d74f4aee61 Merge pull request 'Update Rust crate clap to 4.4.12' (#61) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #61
2024-01-03 10:43:56 +00:00
0788b6462c Merge pull request 'Update Rust crate serde to 1.0.194' (#66) from renovate/serde-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #66
2024-01-03 10:43:17 +00:00
26ee9e5d72 Update Rust crate serde to 1.0.194
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-01-03 00:20:02 +00:00
4c12a3c56b Update Rust crate thiserror to 1.0.53
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-31 00:19:17 +00:00
de767c90b9 Update Rust crate tempfile to 3.9.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-30 00:18:35 +00:00
be8066de17 Update dependency @mui/lab to v5.0.0-alpha.158
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-29 00:20:32 +00:00
7262c66c90 Update Rust crate clap to 4.4.12
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-12-29 00:20:09 +00:00
73ff552104 Update dependency @mui/icons-material to v5.15.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-28 00:31:26 +00:00
98920a485f Update Rust crate thiserror to 1.0.52
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-28 00:20:03 +00:00
4a2d95f64f Update Rust crate actix-web to 4.4.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-25 00:18:47 +00:00
c55b6f724e Update dependency @mui/lab to v5.0.0-alpha.157
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-20 00:28:12 +00:00
2ad40c4ba0 Update dependency @mui/icons-material to v5.15.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-20 00:11:12 +00:00
5cb64ad015 Update Rust crate thiserror to 1.0.51
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-17 00:13:23 +00:00
a60179eb0e Update dependency vite to v5.0.10
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-16 00:38:36 +00:00
2956777cf5 Update dependency react-easy-crop to v5.0.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-16 00:14:24 +00:00
65842c7f30 Update dependency vite to v5.0.9
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-15 00:11:55 +00:00
b7b759f5e9 Update dependency @mui/icons-material to v5.15.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-14 00:29:04 +00:00
10594732ba Update dependency @mui/lab to v5.0.0-alpha.156
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-14 00:11:37 +00:00
36ee8bf5b7 Update Rust crate clap to 4.4.11
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-13 00:29:36 +00:00
3dbbe50b83 Update Rust crate actix-cors to 0.6.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-13 00:13:48 +00:00
35d7bd493e Update installation instructions
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-12 19:06:22 +01:00
e4ae43f182 Update Docker image
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-12 19:01:41 +01:00
cef5d3c416 Finish vite migration
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-12 19:45:54 +01:00
34efa48c3e WIP vite migration 2023-12-12 19:37:41 +01:00
cba850251f Fix issue 2023-12-12 18:30:19 +01:00
9f25f88695 Updated frontend dependencies 2023-12-12 18:27:57 +01:00
2043afadbb Updated backend dependencies 2023-12-12 18:21:35 +01:00
74503d1eaa Update dependency @mui/lab to v5.0.0-alpha.155
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-12-07 00:11:47 +00:00
c3a173128e Update Rust crate tempfile to 3.8.1
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-06 00:17:20 +00:00
6005955884 Update Rust crate diesel to 2.1.4
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-30 00:12:53 +00:00
3aef093883 Update Rust crate serde_json to 1.0.108
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-11-29 00:08:19 +00:00
fb9ec24986 Update dependency @mui/x-tree-view to v6.0.0-beta.0
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2023-10-19 00:06:55 +00:00
49899defa9 Update dependency @mui/lab to v5.0.0-alpha.149
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2023-10-18 00:04:39 +00:00
549d12b392 Update Rust crate diesel to 2.1.3
Some checks failed
continuous-integration/drone/push Build is failing
2023-10-17 00:07:29 +00:00
eff5ee9609 Merge pull request 'Update Rust crate clap to 4.4.3' (#35) from renovate/clap-4.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #35
2023-10-16 16:40:17 +00:00
65f6f80303 Merge pull request 'Update Rust crate thiserror to 1.0.48' (#20) from renovate/thiserror-1.x into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #20
2023-10-16 12:00:25 +00:00
93053d5077 Merge pull request 'Update Rust crate httpdate to 1.0.3' (#3) from renovate/httpdate-1.x into master
Some checks failed
continuous-integration/drone/push Build is failing
Reviewed-on: #3
2023-10-16 12:00:08 +00:00
4d53f8a122 Update Rust crate clap to 4.4.3
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2023-09-13 00:28:34 +00:00
9a3914660f Update dockage/mailcatcher Docker tag to v0.9.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-11 00:26:36 +00:00
961b4b07c4 Update dependency @mui/x-data-grid to v6.13.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-10 01:09:27 +00:00
0f6c68b1fc Update Rust crate tempfile to 3.8.0
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
2023-09-10 00:27:25 +00:00
b528e6fdbb Update dependency react-easy-crop to v5.0.2
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-09 01:02:50 +00:00
2018174ed5 Update dependency @mui/x-tree-view to v6.0.0-alpha.2
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is failing
2023-09-09 00:26:01 +00:00
935deeca2c Switch tree view to its new package
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-08 11:28:24 +02:00
8ac79020d6 Update Rust crate diesel to 2.1.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-08 00:31:35 +00:00
c1972c7930 Update dependency react-easy-crop to v5.0.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-07 00:24:24 +00:00
f686003f19 Update dependency @mui/material to v5.14.8
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-06 01:20:18 +00:00
42a494a15b Update dependency @mui/lab to v5.0.0-alpha.143
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
2023-09-06 00:35:11 +00:00
faa668550c Update Rust crate clap to 4.4.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-05 00:35:43 +00:00
cb797074cb Update Rust crate actix-web to 4.4.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-04 00:32:51 +00:00
ede195ce57 Update dependency filesize to v10.0.12
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-03 00:26:40 +00:00
738dee1f0c Update Rust crate thiserror to 1.0.48
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-09-03 00:26:17 +00:00
7f0ea4f04c Update Rust crate redis to 0.23.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-02 00:27:12 +00:00
49d27e5849 Update dependency @types/node to v16.18.46
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-01 01:17:31 +00:00
03b9dfc60a Update dependency @mui/material to v5.14.7
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
2023-09-01 00:35:31 +00:00
433f8384a0 Emphasis missing mother and father
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-31 20:39:17 +02:00
2c0b6356b6 Fix bug 2023-08-31 20:36:33 +02:00
c6c984c34c Handle particular cases in simple family tree
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-31 20:26:34 +02:00
c84fb50087 Fix type declaration issue 2023-08-31 20:14:36 +02:00
79ce616781 Show a feedback when saving couple information
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-31 19:30:16 +02:00
e4a1817d7f Simplify navigation to set member photo 2023-08-31 19:27:14 +02:00
2a69c89065 Automatically trim values before saving 2023-08-31 19:23:21 +02:00
0899835fab Update dependency @mui/lab to v5.0.0-alpha.142
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-31 00:58:23 +00:00
574dd8b16b Update Rust crate httpdate to 1.0.3
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2023-08-26 00:32:00 +00:00
30 changed files with 2656 additions and 15146 deletions

View File

@@ -19,7 +19,7 @@ docker-compose up
3. Install Diesel CLI:
```bash
sudo apt install libpq5 libpq-dev
sudo apt install libpq5 libpq-dev pkg-config libssl-dev
cargo install diesel_cli --no-default-features --features postgres
```
@@ -51,4 +51,4 @@ evan@qlik.example
franklin@qlik.example
```
Password: `Password1!`
Password: `Password1!`

View File

@@ -1 +1 @@
REACT_APP_BACKEND=http://localhost:8000
VITE_APP_BACKEND=http://localhost:8000

View File

@@ -1 +1 @@
REACT_APP_BACKEND=https://geneit-backend.communiquons.org
VITE_APP_BACKEND=https://geneit-backend.communiquons.org

View File

@@ -10,6 +10,7 @@
# production
/build
/dist
# misc
.DS_Store

View File

@@ -2,25 +2,25 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="apple-touch-icon" href="/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
@@ -39,5 +39,7 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script type="module" src="/src/index.tsx"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
"name": "geneit_app",
"version": "0.1.0",
"private": true,
"type": "module",
"dependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@emotion/react": "^11.11.0",
@@ -13,33 +14,33 @@
"@mui/lab": "^5.0.0-alpha.140",
"@mui/material": "^5.14.5",
"@mui/x-data-grid": "^6.9.2",
"@mui/x-tree-view": "^6.0.0-alpha.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.34",
"@types/react": "^18.2.8",
"@types/react-dom": "^18.2.4",
"@vitejs/plugin-react": "^4.2.1",
"date-and-time": "^3.0.1",
"email-validator": "^2.0.4",
"family-chart": "^0.0.0-beta-1",
"filesize": "^10.0.9",
"jspdf": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-easy-crop": "^5.0.0",
"react-router-dom": "^6.11.2",
"react-scripts": "^5.0.1",
"react-zoom-pan-pinch": "^3.1.0",
"svg2pdf.js": "^2.2.2",
"svg2pdf.js": "^2.2.3",
"typescript": "^4.9.5",
"vite": "^5.0.8",
"vite-tsconfig-paths": "^4.2.2",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"start": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"eslintConfig": {
"extends": [

View File

@@ -16,7 +16,7 @@ export class APIClient {
* Get backend URL
*/
static backendURL(): string {
const URL = process.env.REACT_APP_BACKEND ?? "";
const URL = import.meta.env.VITE_APP_BACKEND ?? "";
if (URL.length === 0) throw new Error("Backend URL undefined!");
return URL;
}

View File

@@ -1 +0,0 @@
/// <reference types="react-scripts" />

View File

@@ -25,6 +25,7 @@ import { MemberInput } from "../../widgets/forms/MemberInput";
import { PropSelect } from "../../widgets/forms/PropSelect";
import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
import { useQuery } from "../../hooks/useQuery";
import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider";
/**
* Create a new couple route
@@ -165,7 +166,8 @@ export function FamilyEditCoupleRoute(): React.ReactElement {
const cancel = () => {
setShouldQuit(true);
n(-1);
n(family.family.coupleURL(couple!));
//n(-1);
};
const save = async (c: Couple) => {
@@ -210,13 +212,14 @@ export function CouplePage(p: {
shouldAllowLeaving?: boolean;
children?: Member[];
onCancel?: () => void;
onSave?: (m: Couple) => void;
onSave?: (m: Couple) => Promise<void>;
onRequestEdit?: () => void;
onRequestDelete?: () => void;
onForceReload?: () => void;
}): React.ReactElement {
const confirm = useConfirm();
const snackbar = useSnackbar();
const loadingMessage = useLoadingMessage();
const family = useFamily();
@@ -230,8 +233,12 @@ export function CouplePage(p: {
setCouple(new Couple(structuredClone(couple)));
};
const save = () => {
p.onSave!(couple);
const save = async () => {
loadingMessage.show(
"Enregistrement des informations du couple en cours..."
);
await p.onSave!(couple);
loadingMessage.hide();
};
const cancel = async () => {

View File

@@ -39,6 +39,7 @@ import { UploadPhotoButton } from "../../widgets/forms/UploadPhotoButton";
import { useQuery } from "../../hooks/useQuery";
import { mdiFamilyTree } from "@mdi/js";
import Icon from "@mdi/react";
import { useLoadingMessage } from "../../hooks/context_providers/LoadingMessageProvider";
/**
* Create a new member route
@@ -185,8 +186,8 @@ export function FamilyEditMemberRoute(): React.ReactElement {
const cancel = () => {
setShouldQuit(true);
//n(family.family.URL(`member/${member!.id}`));
n(-1);
n(family.family.memberURL(member!));
//n(-1);
};
const save = async (m: Member) => {
@@ -233,7 +234,7 @@ export function MemberPage(p: {
siblings?: Member[];
couples?: Couple[];
onCancel?: () => void;
onSave?: (m: Member) => void;
onSave?: (m: Member) => Promise<void>;
onRequestEdit?: () => void;
onRequestDelete?: () => void;
onForceReload?: () => void;
@@ -241,6 +242,7 @@ export function MemberPage(p: {
}): React.ReactElement {
const confirm = useConfirm();
const snackbar = useSnackbar();
const loadingMessage = useLoadingMessage();
const family = useFamily();
@@ -254,8 +256,12 @@ export function MemberPage(p: {
setMember(new Member(structuredClone(member)));
};
const save = () => {
p.onSave!(member);
const save = async () => {
loadingMessage.show(
"Enregistrement des informations du membre en cours..."
);
await p.onSave!(member);
loadingMessage.hide();
};
const cancel = async () => {

View File

@@ -26,13 +26,11 @@ import { useFamily } from "../../widgets/BaseFamilyRoute";
import { BasicFamilyTree } from "../../widgets/BasicFamilyTree";
import { MemberItem } from "../../widgets/MemberItem";
import { RouterLink } from "../../widgets/RouterLink";
import { ComplexFamilyTree } from "../../widgets/complex_family_tree/ComplexFamilyTree";
import { SimpleFamilyTree } from "../../widgets/simple_family_tree/SimpleFamilyTree";
enum CurrTab {
BasicTree,
SimpleTree,
AdvancedTree,
}
enum TreeMode {
@@ -149,7 +147,6 @@ export function FamilyMemberTreeRoute(): React.ReactElement {
>
<Tab tabIndex={CurrTab.BasicTree} label="Basique" />
<Tab tabIndex={CurrTab.SimpleTree} label="Simple" />
<Tab tabIndex={CurrTab.AdvancedTree} label="Avancé" />
</Tabs>
</div>
@@ -157,14 +154,8 @@ export function FamilyMemberTreeRoute(): React.ReactElement {
<Paper style={{ flex: "1", display: "flex", flexDirection: "column" }}>
{currTab === CurrTab.BasicTree ? (
<BasicFamilyTree tree={tree!} depth={currDepth} />
) : currTab === CurrTab.SimpleTree ? (
<SimpleFamilyTree tree={tree!} depth={currDepth} />
) : (
<ComplexFamilyTree
tree={tree!}
isUp={currMode === TreeMode.Ascending}
depth={currDepth}
/>
<SimpleFamilyTree tree={tree!} depth={currDepth} />
)}
</Paper>
</div>

View File

@@ -4,7 +4,7 @@ import EditIcon from "@mui/icons-material/Edit";
import FemaleIcon from "@mui/icons-material/Female";
import MaleIcon from "@mui/icons-material/Male";
import VisibilityIcon from "@mui/icons-material/Visibility";
import { Button, TextField, Tooltip } from "@mui/material";
import { Button, TextField, Tooltip, Typography } from "@mui/material";
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
import React from "react";
import { useNavigate } from "react-router-dom";
@@ -165,7 +165,8 @@ function MembersTable(p: {
headerName: "Père",
flex: 5,
renderCell(params) {
if (!params.row.father) return <></>;
if (!params.row.father)
return <Typography color="red">Non renseigné</Typography>;
return family.members.get(params.row.father)!.fullName;
},
},
@@ -174,7 +175,8 @@ function MembersTable(p: {
headerName: "Mère",
flex: 5,
renderCell(params) {
if (!params.row.mother) return <></>;
if (!params.row.mother)
return <Typography color="red">Non renseignée</Typography>;
return family.members.get(params.row.mother)!.fullName;
},
},

View File

@@ -1,3 +1,5 @@
export function isDebug(): boolean {
return !process.env.NODE_ENV || process.env.NODE_ENV === "development";
return (
!import.meta.env.NODE_ENV || import.meta.env.NODE_ENV === "development"
);
}

View File

@@ -2,7 +2,7 @@ import { mdiBabyCarriage, mdiCross } from "@mdi/js";
import Icon from "@mdi/react";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { TreeItem, TreeView } from "@mui/lab";
import { TreeItem, TreeView } from "@mui/x-tree-view";
import React from "react";
import { useNavigate } from "react-router-dom";
import { Couple } from "../api/CoupleApi";

View File

@@ -11,7 +11,7 @@ import {
} from "@mui/material";
import React from "react";
import { unstable_useBlocker as useBlocker } from "react-router-dom";
import { useBlocker } from "react-router-dom";
export function ConfirmLeaveWithoutSaveDialog(p: {
shouldBlock: boolean;

View File

@@ -1,339 +0,0 @@
import { mdiXml } from "@mdi/js";
import Icon from "@mdi/react";
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
import { IconButton, Tooltip } from "@mui/material";
import f3, { f3Data } from "family-chart";
import { jsPDF } from "jspdf";
import React from "react";
import "svg2pdf.js";
import { Couple } from "../../api/CoupleApi";
import { Member, fmtDate } from "../../api/MemberApi";
import { useDarkTheme } from "../../hooks/context_providers/DarkThemeProvider";
import {
FamilyTreeNode,
getAvailableMembers,
treeHeight,
treeWidth,
} from "../../utils/family_tree";
import { downloadBlob } from "../../utils/files_utils";
import "./family-chart.css";
export function ComplexFamilyTree(p: {
tree: FamilyTreeNode;
isUp: boolean;
depth: number;
}): React.ReactElement {
const darkTheme = useDarkTheme();
const applyTree = (container: HTMLDivElement) => {
if (!container) return;
const store = f3.createStore({
data: treeToF3Data(p.tree, p.isUp, p.depth),
node_separation: 250,
level_separation: 150,
});
const view = f3.d3AnimationView({
store,
cont: container,
});
const Card = f3.elements.Card({
store,
svg: view.svg,
card_dim: {
w: 210,
h: 120,
text_x: 5,
text_y: 75,
img_w: 60,
img_h: 70,
img_x: 5,
img_y: 5,
},
card_display: [
(d) =>
`${d.data.first_name || ""} ${d.data.last_name || ""} ${
d.data.dead ? "✝" : ""
}`,
(d) => {
let birthDeath = [];
if (d.data.birthday) birthDeath.push(d.data.birthday);
if (d.data.deathday) birthDeath.push(d.data.deathday);
let s = birthDeath.join(" -> ");
if (d.data.wedding_state || d.data.dateOfWedding) {
let weddingInfo = [];
if (d.data.wedding_state) weddingInfo.push(d.data.wedding_state);
if (d.data.dateOfWedding)
weddingInfo.push("Mariage : " + d.data.dateOfWedding);
s += `</tspan> <tspan x="0" dy="14" font-size="10">${weddingInfo.join(
" - "
)}`;
}
return s;
},
],
mini_tree: true,
link_break: false,
});
// Patch generated card
const PatchedCard: f3.F3CardBuilder = (p) => {
const res = Card(p);
// Patch card colors for PDF export
res
.querySelector(".card-male")
?.querySelector(".card-body-rect")
?.setAttribute("fill", "#add8e6");
res
.querySelector(".card-female")
?.querySelector(".card-body-rect")
?.setAttribute("fill", "#ffb6c1");
return res;
};
view.setCard(PatchedCard);
store.setOnUpdate((props) => view.update(props || {}));
store.update.tree({ initial: false, transition_time: 0 });
};
const doExport = async (onlySVG: boolean) => {
const docWidth = treeWidth(p.tree) * 65;
const docHeight = treeHeight(p.tree) * 60;
console.info(`Tree w=${treeWidth(p.tree)} h=${treeHeight(p.tree)}`);
// Clone the SVG to manipulate it
const container = document.createElement("div");
container.classList.add("f3", "f3-export");
container.style.width = docWidth + "px";
container.style.height = docHeight + "px";
document.body.appendChild(container);
applyTree(container);
const target = container.children[0];
await new Promise((res) => setTimeout(() => res(null), 100));
// SVG manipulations (adaptations to export)
let dstSVG = target.innerHTML.replaceAll(
`<path class="link" fill="none" stroke="#fff"`,
`<path class="link" fill="none" stroke="#000"`
);
dstSVG = dstSVG.replaceAll(
`class="text-overflow-mask"`,
`class="text-overflow-mask" fill="transparent"`
);
dstSVG = dstSVG.replaceAll(`>UNKNOWN<`, `fill="#000">INCONNU<`);
dstSVG = dstSVG.replaceAll(
`class="card-outline`,
`fill="transparent" class="card-outline`
);
dstSVG = dstSVG.replaceAll("✝", " ");
// Download in SVG format
if (onlySVG) {
// Fix background color (first rect background)
dstSVG = dstSVG.replace(
`fill="transparent"></rect>`,
`fill="white"></rect>`
);
const blob = new Blob([`<svg>${dstSVG}</svg>`], {
type: "image/svg+xml",
});
downloadBlob(blob, "ArbreGenealogique.svg");
return;
}
// Download in PDF format
//navigator.clipboard.writeText(dstSVG);
target.innerHTML = dstSVG;
const doc = new jsPDF({
orientation: "l",
format: [docHeight, docWidth],
});
await doc.svg(target, {
height: docHeight,
width: docWidth,
});
container.remove();
// Save the created pdf
doc.save("ArbreGenealogique.pdf");
};
const exportPDF = () => doExport(false);
const exportSVG = () => doExport(true);
return (
<div>
<div style={{ textAlign: "right" }}>
<Tooltip title="Exporter le graphique au format PDF">
<IconButton onClick={exportPDF}>
<PictureAsPdfIcon />
</IconButton>
</Tooltip>
<Tooltip title="Exporter le graphique au format SVG">
<IconButton onClick={exportSVG}>
<Icon path={mdiXml} size={1} />
</IconButton>
</Tooltip>
</div>
<div
style={{ width: "100%" }}
className={`f3 ${darkTheme.enabled ? "f3-dark" : "f3-light"}`}
id="FamilyChart"
ref={applyTree}
></div>
</div>
);
}
function treeToF3Data(
node: FamilyTreeNode,
isUp: boolean,
depth: number
): f3Data[] {
const availableMembers = getAvailableMembers(node, depth);
const list: f3Data[] = [];
if (isUp) treeToF3DataUpRecurse(node, list, availableMembers);
else treeToF3DataDownRecurse(node, list, availableMembers);
return list;
}
function memberData(m: Member, c?: Couple): f3.f3DataData {
return {
first_name: m.first_name ?? "_",
last_name: m.last_name ?? "_",
gender: m.sex ?? "M",
avatar: m.thumbnailURL ?? undefined,
dead: m.dead,
birthday: m.dateOfBirth ? fmtDate(m.dateOfBirth) : undefined,
deathday: m.dateOfDeath ? fmtDate(m.dateOfDeath) : undefined,
wedding_state: c?.stateFr,
dateOfWedding: c?.dateOfWedding ? fmtDate(c?.dateOfWedding) : undefined,
};
}
function treeToF3DataUpRecurse(
node: FamilyTreeNode,
array: f3Data[],
availableMembers: Set<number>,
child?: number,
spouses?: number[]
) {
if (!availableMembers.has(node.member.id)) return;
array.push({
data: memberData(node.member),
id: node.member.id.toString(),
rels: {
father:
node.member.father && availableMembers.has(node.member.father)
? node.member.father.toString()
: undefined,
mother:
node.member.mother && availableMembers.has(node.member.mother)
? node.member.mother.toString()
: undefined,
spouses: spouses
?.filter((c) => c !== node.member.id)
.map((c) => c.toString()),
children: child ? [child.toString()] : undefined,
},
});
const parentSpouses = node.down?.map((c) => c.member.id);
node.down?.forEach((d) =>
treeToF3DataUpRecurse(
d,
array,
availableMembers,
node.member.id,
parentSpouses
)
);
}
function treeToF3DataDownRecurse(
node: FamilyTreeNode,
array: f3Data[],
availableMembers: Set<number>
) {
if (!availableMembers.has(node.member.id)) return;
// Get all members ids
let children = node?.down?.map((c) => c.member.id) ?? [];
node.couples?.map((c) => c.down.forEach((m) => children.push(m.member.id)));
children = children.filter((c) => availableMembers.has(c));
array.push({
data: memberData(node.member),
id: node.member.id.toString(),
rels: {
father:
node.member.father && availableMembers.has(node.member.father)
? node.member.father.toString()
: undefined,
mother:
node.member.mother && availableMembers.has(node.member.mother)
? node.member.mother.toString()
: undefined,
spouses: node.couples
?.filter((s) => availableMembers.has(s.member.id))
.map((c) => c.member.id.toString()),
children: children.map((c) => c.toString()),
},
});
node?.down?.forEach((e) =>
treeToF3DataDownRecurse(e, array, availableMembers)
);
if (node.couples) {
for (const c of node.couples) {
if (!availableMembers.has(c.member.id)) continue;
array.push({
data: memberData(c.member, c.couple),
id: c.member.id.toString(),
rels: {
father:
c.member.father && availableMembers.has(c.member.father)
? c.member.father.toString()
: undefined,
mother:
c.member.mother && availableMembers.has(c.member.mother)
? c.member.mother.toString()
: undefined,
spouses: [node.member.id.toString()],
children: c.down
.filter((c) => availableMembers.has(c.member.id))
.map((c) => c.member.id.toString()),
},
});
c.down.forEach((e) =>
treeToF3DataDownRecurse(e, array, availableMembers)
);
}
}
}

View File

@@ -1,111 +0,0 @@
.f3 {
height: 700px;
max-height: calc(100vh - 80px);
width: 900px;
max-width: 100%;
margin: auto;
position: relative;
}
.f3 .cursor-pointer {
cursor: pointer;
}
.f3 svg.main_svg {
width: 100%;
height: 100%;
/*background-color: #3b5560;*/
color: #3b5560;
}
.f3 svg.main_svg text {
fill: currentColor;
}
.f3 rect.card-female,
.f3 .card-female .card-body-rect,
.f3 .card-female .text-overflow-mask {
fill: lightpink;
}
.f3 rect.card-male,
.f3 .card-male .card-body-rect,
.f3 .card-male .text-overflow-mask {
fill: lightblue;
}
.f3 .card-genderless .card-body-rect,
.f3 .card-genderless .text-overflow-mask {
fill: lightgray;
}
.f3 .card_add .card-body-rect {
fill: #3b5560;
stroke-width: 4px;
stroke: #fff;
cursor: pointer;
}
.f3 g.card_add text {
fill: #fff;
}
.f3 .card-main {
stroke: #000;
}
.f3 .card_family_tree rect {
transition: 0.3s;
}
.f3 .card_family_tree:hover rect {
transform: scale(1.1);
}
.f3 .card_add_relative {
cursor: pointer;
color: #fff;
transition: 0.3s;
}
.f3 .card_add_relative circle {
fill: rgba(0, 0, 0, 0);
}
.f3 .card_add_relative:hover {
color: black;
}
.f3 .card_edit.pencil_icon {
color: #fff;
transition: 0.3s;
}
.f3 .card_edit.pencil_icon:hover {
color: black;
}
.f3 .card_break_link,
.f3 .link_upper,
.f3 .link_lower,
.f3 .link_particles {
transform-origin: 50% 50%;
transition: 1s;
}
.f3 .card_break_link {
color: #fff;
}
.f3 .card_break_link.closed .link_upper {
transform: translate(-140.5px, 655.6px);
}
.f3 .card_break_link.closed .link_upper g {
transform: rotate(-58deg);
}
.f3 .card_break_link.closed .link_particles {
transform: scale(0);
}
.f3 .input-field input {
height: 2.5rem !important;
}
.f3 .input-field > label:not(.label-icon).active {
-webkit-transform: translateY(-8px) scale(0.8);
transform: translateY(-8px) scale(0.8);
}
.f3-light .link {
stroke: black;
}
.f3-export {
position: fixed;
top: 0px;
left: 0px;
/*width: 3508px;
height: 2480px;*/
opacity: 0;
}

View File

@@ -1,95 +0,0 @@
declare module "family-chart" {
type f3data = any;
type f3tree = any;
interface f3Rels {
spouses?: string[];
father?: string;
mother?: string;
children?: string[];
}
interface f3DataData {
gender: "M" | "F";
avatar?: string;
dead: boolean;
birthday?: string;
deathday?: string;
first_name: string;
last_name: string;
dateOfWedding?: string;
wedding_state?: string;
}
interface f3Data {
id: string;
rels: f3Rels;
data: f3DataData;
}
type f3State = {
data: f3Data[];
main_id?: any;
tree?: f3tree;
node_separation?: number;
level_separation?: number;
};
interface f3Update {
tree: (props) => void;
mainId: (mainId) => void;
data: (data: f3data) => void;
}
interface f3Store {
state: f3State;
update: f3update;
getData: () => f3data;
getTree: () => f3tree;
setOnUpdate: (cb: (props) => void) => void;
methods: any;
}
function createStore(initial_state: f3State): f3Store;
function CalculateTree({
data_stash,
main_id = null,
is_vertical = true,
node_separation = 250,
level_separation = 150,
});
function d3AnimationView(p: {
store: f3Store;
cont: HTMLElement | null;
Card?: any;
});
const handlers: any;
type F3elements = {
Card: (props: {
store: f3Store;
svg: HTMLElement;
mini_tree: boolean;
link_break: boolean;
cardEditForm?: boolean;
card_dim: {
w: number;
h: number;
text_x: number;
text_y: number;
img_w: number;
img_h: number;
img_x: number;
img_y: number;
};
card_display: ((data: f3Data) => string)[];
}) => F3CardBuilder;
};
type F3CardBuilder = (p: { node; d }) => HTMLElement;
const elements: F3elements;
}

View File

@@ -13,6 +13,7 @@ import { downloadBlob } from "../../utils/files_utils";
import { getTextWidth } from "../../utils/render_utils";
import "./simpletree.css";
import "./Roboto-normal";
import "svg2pdf.js";
const FACE_WIDTH = 60;
const FACE_HEIGHT = 70;
@@ -92,7 +93,8 @@ function buildSimpleTreeNode(
): SimpleTreeNode {
if (depth === 0) throw new Error("Too much recursion reached!");
const lastCouple = tree.couples?.[tree.couples?.length - 1 ?? 0];
const lastCoupleId = tree.couples?.length ?? 1;
const lastCouple = tree.couples?.[lastCoupleId - 1];
// Preprocess children
let childrenToProcess = tree.down;
@@ -254,6 +256,7 @@ function NodeArea(p: {
let pers2 = p.node.spouse?.member;
let didSwap = false;
// Show male of the left (all the time)
if (pers2?.sex === "M") {
let s = pers1;
pers1 = pers2;
@@ -293,10 +296,37 @@ function NodeArea(p: {
let childrenLinkX: number;
let childrenLinkY: number;
if (p.node.spouse) {
// If the father is the father of all the children, while the
// mother is not the mother of any of the children
if (
pers2 &&
p.node.down.every(
(n) => n.member.father === pers1.id && n.member.mother !== pers2!.id
)
) {
childrenLinkX = parent_x_offset + Math.floor(memberCardWidth(pers1) / 2);
childrenLinkY = p.y + CARD_HEIGHT + 2;
}
// If the mother is the mother of all the children, while the
// father is not the father of any of the children
else if (
pers2 &&
p.node.down.every(
(n) => n.member.father !== pers1.id && n.member.mother === pers2!.id
)
) {
childrenLinkX = beginSecondFaceX! + Math.floor(memberCardWidth(pers2) / 2);
childrenLinkY = p.y + CARD_HEIGHT + 2;
}
// Normal couple
else if (p.node.spouse) {
childrenLinkX = Math.floor((endFirstFaceX + beginSecondFaceX!) / 2);
childrenLinkY = middleParentFaceY;
} else {
}
// Single person
else {
childrenLinkX = parent_x_offset + Math.floor(memberCardWidth(pers1) / 2);
childrenLinkY = p.y + CARD_HEIGHT + 2;
}

View File

@@ -1,11 +1,8 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"target": "ESNext",
"lib": ["dom", "dom.iterable", "esnext"],
"types": ["vite/client"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
@@ -20,7 +17,5 @@
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
"include": ["src"]
}

View File

@@ -13,4 +13,4 @@ if [ ! "$DRONE_COMMIT_BRANCH" == "master" ]; then
exit 0
fi
cd build && aws --endpoint-url https://s3.communiquons.org s3 sync . s3://geneit-app
cd dist && aws --endpoint-url https://s3.communiquons.org s3 sync . s3://geneit-app

1
geneit_app/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />

15
geneit_app/vite.config.ts Normal file
View File

@@ -0,0 +1,15 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import viteTsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
// depending on your application, base can also be "/"
base: "/",
plugins: [react(), viteTsconfigPaths()],
server: {
// this ensures that the browser opens upon server start
open: true,
// this sets a default port to 3000
port: 3000,
},
});

1175
geneit_backend/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,34 +6,34 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4.17"
env_logger = "0.10.0"
clap = { version = "4.3.0", features = ["derive", "env"] }
log = "0.4.20"
env_logger = "0.10.1"
clap = { version = "4.4.12", features = ["derive", "env"] }
lazy_static = "1.4.0"
anyhow = "1.0.75"
actix-web = "4.3.1"
actix-cors = "0.6.4"
actix-web = "4.5.1"
actix-cors = "0.7.0"
actix-multipart = "0.6.1"
actix-remote-ip = "0.1.0"
futures-util = "0.3.28"
diesel = { version = "2.0.4", features = ["postgres"] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.96"
mailchecker = "5.0.9"
redis = "0.23.2"
lettre = "0.10.4"
futures-util = "0.3.29"
diesel = { version = "2.1.4", features = ["postgres"] }
serde = { version = "1.0.194", features = ["derive"] }
serde_json = "1.0.110"
mailchecker = "6.0.1"
redis = "0.23.3"
lettre = "0.11.2"
rand = "0.8.5"
bcrypt = "0.15.0"
light-openid = "1.0.1"
thiserror = "1.0.47"
serde_with = "3.1.0"
rust_iso3166 = "0.1.10"
thiserror = "1.0.57"
serde_with = "3.4.0"
rust_iso3166 = "0.1.11"
rust-s3 = "0.33.0"
sha2 = "0.10.7"
image = "0.24.6"
uuid = { version = "1.4.1", features = ["v4"] }
httpdate = "1.0.2"
sha2 = "0.10.8"
image = "0.24.9"
uuid = { version = "1.6.1", features = ["v4"] }
httpdate = "1.0.3"
zip = "0.6.6"
mime_guess = "2.0.4"
tempfile = "3.7.1"
base64 = "0.21.2"
tempfile = "3.10.1"
base64 = "0.22.0"

View File

@@ -1,4 +1,4 @@
FROM debian:bullseye-slim
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y libcurl4 libpq5 \

View File

@@ -27,7 +27,7 @@ services:
- ./storage/db:/var/lib/postgresql/data
mailcatcher:
image: dockage/mailcatcher:0.8.2
image: dockage/mailcatcher:0.9.0
ports:
- 1080:1080
- 1025:1025

View File

@@ -103,8 +103,29 @@ fn check_opt_str_val(
Ok(())
}
fn trim_opt_val(val: &mut Option<String>) {
if let Some(s) = val {
*val = Some(s.trim().to_string());
}
if val.as_deref() == Some("") {
*val = None;
}
}
impl MemberRequest {
pub async fn to_member(self, member: &mut Member) -> anyhow::Result<()> {
pub async fn to_member(mut self, member: &mut Member) -> anyhow::Result<()> {
// Trim values before processing
trim_opt_val(&mut self.first_name);
trim_opt_val(&mut self.last_name);
trim_opt_val(&mut self.birth_last_name);
trim_opt_val(&mut self.email);
trim_opt_val(&mut self.country);
trim_opt_val(&mut self.address);
trim_opt_val(&mut self.city);
trim_opt_val(&mut self.note);
trim_opt_val(&mut self.phone);
let c = StaticConstraints::default();
check_opt_str_val(
&self.first_name,

View File

@@ -6,6 +6,7 @@ diesel::table! {
family_id -> Int4,
wife -> Nullable<Int4>,
husband -> Nullable<Int4>,
#[max_length = 1]
state -> Nullable<Varchar>,
photo_id -> Nullable<Int4>,
time_create -> Int8,
@@ -23,7 +24,9 @@ diesel::table! {
families (id) {
id -> Int4,
time_create -> Int8,
#[max_length = 30]
name -> Varchar,
#[max_length = 7]
invitation_code -> Varchar,
disable_couple_photos -> Bool,
}
@@ -33,16 +36,26 @@ diesel::table! {
members (id) {
id -> Int4,
family_id -> Int4,
#[max_length = 30]
first_name -> Nullable<Varchar>,
#[max_length = 30]
last_name -> Nullable<Varchar>,
#[max_length = 30]
birth_last_name -> Nullable<Varchar>,
photo_id -> Nullable<Int4>,
#[max_length = 255]
email -> Nullable<Varchar>,
#[max_length = 30]
phone -> Nullable<Varchar>,
#[max_length = 155]
address -> Nullable<Varchar>,
#[max_length = 150]
city -> Nullable<Varchar>,
#[max_length = 12]
postal_code -> Nullable<Varchar>,
#[max_length = 2]
country -> Nullable<Varchar>,
#[max_length = 1]
sex -> Nullable<Varchar>,
time_create -> Int8,
time_update -> Int8,
@@ -71,11 +84,15 @@ diesel::table! {
diesel::table! {
photos (id) {
id -> Int4,
#[max_length = 36]
file_id -> Varchar,
time_create -> Int8,
#[max_length = 150]
mime_type -> Varchar,
#[max_length = 130]
sha512 -> Varchar,
file_size -> Int4,
#[max_length = 130]
thumb_sha512 -> Varchar,
}
}
@@ -83,12 +100,16 @@ diesel::table! {
diesel::table! {
users (id) {
id -> Int4,
#[max_length = 30]
name -> Varchar,
#[max_length = 255]
email -> Varchar,
password -> Nullable<Varchar>,
time_create -> Int8,
#[max_length = 150]
reset_password_token -> Nullable<Varchar>,
time_gen_reset_token -> Int8,
#[max_length = 150]
delete_account_token -> Nullable<Varchar>,
time_gen_delete_account_token -> Int8,
time_activate -> Int8,