diff --git a/webclient/package.json b/webclient/package.json index 2bec7d3..ffa6bd1 100644 --- a/webclient/package.json +++ b/webclient/package.json @@ -12,6 +12,7 @@ "react": "^16.13.1", "react-datetime": "~2.16.3", "react-dom": "^16.13.1", + "react-image-crop": "^8.6.4", "react-quill": "~1.3.3", "react-router-dom": "~5.1.2", "react-scripts": "3.4.1", @@ -33,11 +34,11 @@ ">0.2%", "not dead", "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] } } diff --git a/webclient/src/Account.js b/webclient/src/Account.js index de4d5ea..2cc8553 100644 --- a/webclient/src/Account.js +++ b/webclient/src/Account.js @@ -1,5 +1,7 @@ import React, { useState, useEffect } from 'react'; 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 { 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'; @@ -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 && setCrop(percentCrop)} + /> + ); +} + export function AccountForm(props) { const { token, user, refreshUser } = props; const member = user.member; const [input, setInput] = useState({ ...member, set_details: true }); const [error, setError] = useState({}); const [loading, setLoading] = useState(false); + const [crop, setCrop] = useState({ unit: '%', height: 100, aspect: 3/4 }); const history = useHistory(); const handleValues = (e, v) => setInput({ ...input, [v.name]: v.value }); @@ -126,7 +146,7 @@ export function AccountForm(props) { const handleSubmit = (e) => { if (loading) return; 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) .then(res => { setError({}); @@ -222,6 +242,13 @@ export function AccountForm(props) { onChange={handleUpload} /> + {input.photo && + <> + +

Move the box above to crop your image.

+ + } + Submit diff --git a/webclient/yarn.lock b/webclient/yarn.lock index 6a3a597..7049de2 100644 --- a/webclient/yarn.lock +++ b/webclient/yarn.lock @@ -2966,6 +2966,11 @@ clone@^2.1.1: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" 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: version "4.6.0" 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" 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: version "3.6.4" 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" 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: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"