mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
update profile layout
This commit is contained in:
parent
c91a714e3c
commit
318ea81e7e
@ -8,8 +8,8 @@ function checkResponse(response) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getProfileImageUrl(token) {
|
||||
return '/profile/image?agent=' + token
|
||||
export function getProfileImageUrl(token, revision) {
|
||||
return '/profile/image?agent=' + token + "&revision=" + revision
|
||||
}
|
||||
|
||||
async function fetchWithTimeout(url, options) {
|
||||
@ -61,6 +61,12 @@ export async function setProfileData(token, name, location, description) {
|
||||
return await profile.json()
|
||||
}
|
||||
|
||||
export async function setProfileImage(token, image) {
|
||||
let profile = await fetchWithTimeout('/profile/image?agent=' + token, { method: 'PUT', body: JSON.stringify(image), timeout: FETCH_TIMEOUT });
|
||||
checkResponse(profile)
|
||||
return await profile.json()
|
||||
}
|
||||
|
||||
export async function getGroups(token, revision) {
|
||||
let param = "?agent=" + token
|
||||
if (revision != null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { setProfileData, getProfileImageUrl, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
|
||||
import { setProfileImage, setProfileData, getProfileImageUrl, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
|
||||
|
||||
async function updateProfile(token, updateData) {
|
||||
let profile = await getProfile(token);
|
||||
@ -71,10 +71,13 @@ export function useAppContext() {
|
||||
appLogout(updateState, clearWebsocket);
|
||||
resetData();
|
||||
},
|
||||
setProfile: async (name, location, description) => {
|
||||
setProfileData: async (name, location, description) => {
|
||||
await setProfileData(state.token, name, location, description);
|
||||
},
|
||||
profileImageUrl: () => getProfileImageUrl(state.token)
|
||||
setProfileImage: async (image) => {
|
||||
await setProfileImage(state.token, image);
|
||||
},
|
||||
profileImageUrl: () => getProfileImageUrl(state.token, state.Data?.profile?.revision)
|
||||
}
|
||||
|
||||
const adminActions = {
|
||||
|
@ -45,11 +45,17 @@ export function Profile(props) {
|
||||
}
|
||||
|
||||
const onProfileSave = async () => {
|
||||
if (await actions.setModalProfile()) {
|
||||
if (await actions.setProfileData()) {
|
||||
setInfoVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
const onImageSave = async () => {
|
||||
if (await actions.setProfileImage()) {
|
||||
setLogoVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectImage = () => {
|
||||
imageFile.current.click();
|
||||
};
|
||||
@ -64,12 +70,12 @@ export function Profile(props) {
|
||||
|
||||
const Footer = (
|
||||
<ModalFooter>
|
||||
<input type='file' id='file' ref={imageFile} onChange={e => selected(e)} style={{display: 'none'}}/>
|
||||
<input type='file' id='file' accept="image/*" ref={imageFile} onChange={e => selected(e)} style={{display: 'none'}}/>
|
||||
<div class="select">
|
||||
<Button key="select" class="select" onClick={() => onSelectImage()}>Select Image</Button>
|
||||
</div>
|
||||
<Button key="back" onClick={() => setLogoVisible(false)}>Cancel</Button>
|
||||
<Button key="save" type="primary" onClick={() => setLogoVisible(false)}>Save</Button>
|
||||
<Button key="save" type="primary" onClick={() => onImageSave()}>Save</Button>
|
||||
</ModalFooter>
|
||||
);
|
||||
|
||||
@ -88,7 +94,7 @@ export function Profile(props) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="block" onClick={() => setInfoVisible(true)}>
|
||||
<span class="label">detail:</span>
|
||||
<span class="label">details:</span>
|
||||
<EditIcon class="detailedit" />
|
||||
</div>
|
||||
<div class="details">
|
||||
@ -99,7 +105,7 @@ export function Profile(props) {
|
||||
</div>
|
||||
<div class="contact"></div>
|
||||
</div>
|
||||
<Modal title="Profile Info" centered visible={infoVisible} okText="Save"
|
||||
<Modal title="Profile Details" centered visible={infoVisible} okText="Save"
|
||||
onOk={() => onProfileSave()} onCancel={() => setInfoVisible(false)}>
|
||||
<ProfileInfo state={state} actions={actions} />
|
||||
</Modal>
|
||||
|
@ -84,6 +84,10 @@ export const ProfileWrapper = styled.div`
|
||||
position: absolute;
|
||||
padding-right: 8px;
|
||||
cursor: pointer;
|
||||
background: #f6f5ed;
|
||||
padding-left: 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
.detailedit {
|
||||
@ -98,7 +102,7 @@ export const ProfileWrapper = styled.div`
|
||||
|
||||
.label {
|
||||
padding-right: 8px;
|
||||
font-size: 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
color: #888888;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import Cropper from 'react-easy-crop'
|
||||
import { UserOutlined } from '@ant-design/icons';
|
||||
import { ProfileImageWrapper, ProfileDefaultImage } from './ProfileImage.styled';
|
||||
import { ProfileSpin, ProfileImageWrapper, ProfileDefaultImage } from './ProfileImage.styled';
|
||||
|
||||
export function ProfileImage({ state, actions }) {
|
||||
|
||||
const [crop, setCrop] = useState({ x: 0, y: 0 })
|
||||
const [zoom, setZoom] = useState(1)
|
||||
|
||||
const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
|
||||
console.log("crop complete");
|
||||
const onCropComplete = useCallback((area, crop) => {
|
||||
actions.setModalCrop(crop.width, crop.height, crop.x, crop.y)
|
||||
});
|
||||
|
||||
const Logo = () => {
|
||||
@ -19,15 +19,12 @@ export function ProfileImage({ state, actions }) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onSelect = () => {
|
||||
console.log("ON SELECT");
|
||||
}
|
||||
|
||||
return (
|
||||
<ProfileImageWrapper>
|
||||
<Cropper onClick={() => onSelect()} image={state.modalImage} crop={crop} zoom={zoom} aspect={1}
|
||||
<Cropper image={state.modalImage} crop={crop} zoom={zoom} aspect={1}
|
||||
onCropChange={setCrop} onCropComplete={onCropComplete} onZoomChange={setZoom} />
|
||||
<Logo />
|
||||
<ProfileSpin size="large" spinning={state.modalBusy} />
|
||||
</ProfileImageWrapper>
|
||||
)
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Spin } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const ProfileImageWrapper = styled.div`
|
||||
@ -23,3 +24,8 @@ export const ProfileDefaultImage = styled.div`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
export const ProfileSpin = styled(Spin)`
|
||||
position: absolute;
|
||||
x-index: 10;
|
||||
`;
|
||||
|
||||
|
@ -15,6 +15,7 @@ export function useProfile() {
|
||||
modalLocation: '',
|
||||
modalDescription: '',
|
||||
modalImage: null,
|
||||
crop: { w :0, h: 0, x: 0, y: 0 }
|
||||
});
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -40,12 +41,15 @@ export function useProfile() {
|
||||
setModalImage: (value) => {
|
||||
updateState({ modalImage: value });
|
||||
},
|
||||
setModalProfile: async () => {
|
||||
setModalCrop: (w, h, x, y) => {
|
||||
updateState({ crop: { w: w, h: h, x: x, y: y } });
|
||||
},
|
||||
setProfileData: async () => {
|
||||
let set = false
|
||||
if(!state.modalBusy) {
|
||||
updateState({ modalBusy: true });
|
||||
try {
|
||||
await app.actions.setProfile(state.modalName, state.modalLocation, state.modalDescription);
|
||||
await app.actions.setProfileData(state.modalName, state.modalLocation, state.modalDescription);
|
||||
set = true
|
||||
}
|
||||
catch (err) {
|
||||
@ -55,6 +59,39 @@ export function useProfile() {
|
||||
}
|
||||
return set
|
||||
},
|
||||
setProfileImage: async () => {
|
||||
let set = false
|
||||
if(!state.modalBusy) {
|
||||
updateState({ modalBusy: true });
|
||||
try {
|
||||
const processImg = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let img = new Image();
|
||||
img.onload = () => {
|
||||
var canvas = document.createElement("canvas");
|
||||
var context = canvas.getContext('2d');
|
||||
canvas.width = state.crop.w;
|
||||
canvas.height = state.crop.h;
|
||||
context.drawImage(img, state.crop.x, state.crop.y, state.crop.w, state.crop.h,
|
||||
0, 0, state.crop.w, state.crop.h);
|
||||
resolve(canvas.toDataURL());
|
||||
}
|
||||
img.onerror = reject;
|
||||
img.src = state.modalImage;
|
||||
});
|
||||
};
|
||||
let dataUrl = await processImg();
|
||||
let data = dataUrl.split(",")[1];
|
||||
await app.actions.setProfileImage(data);
|
||||
set = true
|
||||
}
|
||||
catch (err) {
|
||||
window.alert(err);
|
||||
}
|
||||
updateState({ modalBusy: false });
|
||||
}
|
||||
return set;
|
||||
},
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -10,6 +10,7 @@ export function Identity() {
|
||||
const { state, actions } = useIdentity()
|
||||
|
||||
const Logo = () => {
|
||||
console.log(state);
|
||||
if (state.imageUrl != null) {
|
||||
if (state.imageUrl === '') {
|
||||
return <UserOutlined />
|
||||
|
Loading…
Reference in New Issue
Block a user