Add UI to crop member photo

This commit is contained in:
Tanner Collin 2020-07-17 04:48:40 +00:00
parent 892bb09e4c
commit 792a7ed62b
3 changed files with 54 additions and 7 deletions

View File

@ -12,6 +12,7 @@
"react": "^16.13.1", "react": "^16.13.1",
"react-datetime": "~2.16.3", "react-datetime": "~2.16.3",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-image-crop": "^8.6.4",
"react-quill": "~1.3.3", "react-quill": "~1.3.3",
"react-router-dom": "~5.1.2", "react-router-dom": "~5.1.2",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
@ -33,11 +34,11 @@
">0.2%", ">0.2%",
"not dead", "not dead",
"not op_mini all" "not op_mini all"
], ],
"development": [ "development": [
"last 1 chrome version", "last 1 chrome version",
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
} }
} }

View File

@ -1,5 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom'; import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
import ReactCrop from 'react-image-crop';
import 'react-image-crop/dist/ReactCrop.css';
import './light.css'; import './light.css';
import { Button, Container, Checkbox, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react'; import { Button, Container, Checkbox, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react';
import { BasicTable, staticUrl, requester } from './utils.js'; import { BasicTable, staticUrl, requester } from './utils.js';
@ -110,12 +112,30 @@ function ChangePasswordForm(props) {
); );
}; };
export function ImageCrop(props) {
const { file, crop, setCrop } = props;
const [src, setSrc] = useState(false);
const reader = new FileReader();
reader.onload = (e) => setSrc(e.target.result);
reader.readAsDataURL(file);
return (
src && <ReactCrop
src={src}
crop={crop}
locked
onChange={(crop, percentCrop) => setCrop(percentCrop)}
/>
);
}
export function AccountForm(props) { export function AccountForm(props) {
const { token, user, refreshUser } = props; const { token, user, refreshUser } = props;
const member = user.member; const member = user.member;
const [input, setInput] = useState({ ...member, set_details: true }); const [input, setInput] = useState({ ...member, set_details: true });
const [error, setError] = useState({}); const [error, setError] = useState({});
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [crop, setCrop] = useState({ unit: '%', height: 100, aspect: 3/4 });
const history = useHistory(); const history = useHistory();
const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value });
@ -126,7 +146,7 @@ export function AccountForm(props) {
const handleSubmit = (e) => { const handleSubmit = (e) => {
if (loading) return; if (loading) return;
setLoading(true); setLoading(true);
const data = { ...input, email: input.email.toLowerCase() }; const data = { ...input, email: input.email.toLowerCase(), crop: JSON.stringify(crop) };
requester('/members/' + member.id + '/', 'PATCH', token, data) requester('/members/' + member.id + '/', 'PATCH', token, data)
.then(res => { .then(res => {
setError({}); setError({});
@ -222,6 +242,13 @@ export function AccountForm(props) {
onChange={handleUpload} onChange={handleUpload}
/> />
{input.photo &&
<>
<ImageCrop file={input.photo} crop={crop} setCrop={setCrop} />
<p>Move the box above to crop your image.</p>
</>
}
<Form.Button loading={loading} error={error.non_field_errors}> <Form.Button loading={loading} error={error.non_field_errors}>
Submit Submit
</Form.Button> </Form.Button>

View File

@ -2966,6 +2966,11 @@ clone@^2.1.1:
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
clsx@^1.0.4:
version "1.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
co@^4.6.0: co@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@ -3206,6 +3211,11 @@ core-js@^2.4.0, core-js@^2.6.10:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
core-js@^3.4.2:
version "3.6.5"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
core-js@^3.5.0: core-js@^3.5.0:
version "3.6.4" version "3.6.4"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647"
@ -8924,6 +8934,15 @@ react-error-overlay@^6.0.7:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
react-image-crop@^8.6.4:
version "8.6.4"
resolved "https://registry.yarnpkg.com/react-image-crop/-/react-image-crop-8.6.4.tgz#51289c22baf7d116575102e885f879af71376388"
integrity sha512-5buyhUg9slzW+QGvN2dbpGSI1VqPxxmfEwe19TZXUB7LjW5+ljZOnrTSsteIzeBqmz6ngVucc8l+OrwgcDOSNg==
dependencies:
clsx "^1.0.4"
core-js "^3.4.2"
prop-types "^15.7.2"
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: react-is@^16.12.0, react-is@^16.6.0, react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6:
version "16.13.1" version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"