mirror of
https://github.com/bendtherules/piktochart-create-editor.git
synced 2026-08-18 13:52:56 +00:00
Add node delete + server url constant
This commit is contained in:
@@ -6,16 +6,49 @@
|
||||
|
||||
.canvas-area .block {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
|
||||
.canvas-area .image-node {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.canvas-area .text-node {
|
||||
.canvas-area .image-node img{
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.canvas-area .text-node .value{
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.canvas-area .image-node, .canvas-area .text-node {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.canvas-area .image-node .delete, .canvas-area .text-node .delete{
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
|
||||
right: -.75em;
|
||||
top: -.75em;
|
||||
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
|
||||
border-radius: 50%;
|
||||
border: 1px solid black;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.canvas-area .image-node:hover .delete, .canvas-area .text-node:hover .delete{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.canvas-area .delete-text {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
font-size: 1em;
|
||||
}
|
||||
@@ -14,6 +14,8 @@ interface CanvasAreaProps {
|
||||
[nodeId: string]: CanvasImageNode;
|
||||
};
|
||||
};
|
||||
|
||||
deleteNode(type: 'text' | 'image', nodeId: string): void;
|
||||
}
|
||||
interface CanvasAreaState {
|
||||
}
|
||||
@@ -27,13 +29,26 @@ export class CanvasArea extends React.Component<CanvasAreaProps, CanvasAreaState
|
||||
this.containerId = 'container-' + uuid();
|
||||
}
|
||||
|
||||
renderDeleteNode(type: 'text' | 'image', nodeId: string) {
|
||||
return (
|
||||
<div className="delete" onClick={() => { this.props.deleteNode(type, nodeId); }}>
|
||||
<div className="delete-text">
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTextNodes() {
|
||||
return Object.keys(this.props.nodes.text).map((nodeId) => {
|
||||
const tmpTextNode = this.props.nodes.text[nodeId];
|
||||
return (
|
||||
<DraggableNode key={nodeId} id={nodeId} containerId={this.containerId}>
|
||||
<div className="text-node">
|
||||
{tmpTextNode.value}
|
||||
{this.renderDeleteNode('text', nodeId)}
|
||||
<div className="value">
|
||||
{tmpTextNode.value}
|
||||
</div>
|
||||
</div>
|
||||
</DraggableNode>
|
||||
);
|
||||
@@ -45,7 +60,10 @@ export class CanvasArea extends React.Component<CanvasAreaProps, CanvasAreaState
|
||||
const tmpImageNode = this.props.nodes.image[nodeId];
|
||||
return (
|
||||
<DraggableNode key={nodeId} id={nodeId} containerId={this.containerId}>
|
||||
<img className="image-node" draggable={false} src={tmpImageNode.url} />
|
||||
<div className="image-node">
|
||||
{this.renderDeleteNode('image', nodeId)}
|
||||
<img draggable={false} src={tmpImageNode.url} />
|
||||
</div>
|
||||
</DraggableNode>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import './CreateEditorApp.css';
|
||||
import { Sidebar } from '../Sidebar';
|
||||
import { CanvasArea } from '../CanvasArea';
|
||||
import { deppCloneNaive, CanvasTextNode, CanvasImageNode } from '../../Helpers';
|
||||
import { deepCloneNaive, CanvasTextNode, CanvasImageNode, serverURL } from '../../Helpers';
|
||||
|
||||
interface CreateEditorAppState {
|
||||
imageURLs: string[];
|
||||
@@ -31,6 +31,7 @@ export class CreateEditorApp extends React.Component<{}, CreateEditorAppState> {
|
||||
this.addOrUpdateTextNode = this.addOrUpdateTextNode.bind(this);
|
||||
this.addOrUpdateImageNode = this.addOrUpdateImageNode.bind(this);
|
||||
this.onImageUploadSuccess = this.onImageUploadSuccess.bind(this);
|
||||
this.deleteNode = this.deleteNode.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -43,7 +44,7 @@ export class CreateEditorApp extends React.Component<{}, CreateEditorAppState> {
|
||||
}
|
||||
|
||||
fetchImages() {
|
||||
fetch('http://localhost:8000/images/')
|
||||
fetch(`${serverURL}/images/`)
|
||||
.then((response: Response) => {
|
||||
return response.json();
|
||||
}).then((responseJSON: string[]) => {
|
||||
@@ -77,7 +78,7 @@ export class CreateEditorApp extends React.Component<{}, CreateEditorAppState> {
|
||||
|
||||
addOrUpdateTextNode(nodeId: string, textNode: CanvasTextNode): void {
|
||||
this.setState((prevState) => {
|
||||
const newState = deppCloneNaive(prevState as CreateEditorAppState);
|
||||
const newState = deepCloneNaive(prevState as CreateEditorAppState);
|
||||
newState.text[nodeId] = textNode;
|
||||
|
||||
return newState;
|
||||
@@ -86,13 +87,28 @@ export class CreateEditorApp extends React.Component<{}, CreateEditorAppState> {
|
||||
|
||||
addOrUpdateImageNode(nodeId: string, imageNode: CanvasImageNode): void {
|
||||
this.setState((prevState) => {
|
||||
const newState = deppCloneNaive(prevState as CreateEditorAppState);
|
||||
const newState = deepCloneNaive(prevState as CreateEditorAppState);
|
||||
newState.image[nodeId] = imageNode;
|
||||
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
|
||||
deleteNode(type: 'text' | 'image', nodeId: string): void {
|
||||
this.setState((prevState) => {
|
||||
const newState = deepCloneNaive(prevState as CreateEditorAppState);
|
||||
|
||||
if (type === 'text') {
|
||||
delete newState.text[nodeId];
|
||||
}
|
||||
if (type === 'image') {
|
||||
delete newState.image[nodeId];
|
||||
}
|
||||
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="create-editor-app">
|
||||
@@ -102,7 +118,7 @@ export class CreateEditorApp extends React.Component<{}, CreateEditorAppState> {
|
||||
addTextNode={this.addOrUpdateTextNode}
|
||||
addImageNode={this.addOrUpdateImageNode}
|
||||
/>
|
||||
<CanvasArea nodes={this.state} />
|
||||
<CanvasArea nodes={this.state} deleteNode={this.deleteNode} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import './UploadResourcesInput.css';
|
||||
import { serverURL } from '../../Helpers';
|
||||
|
||||
interface UploadResourcesInputProps {
|
||||
notifyImageUploadSuccess(): void;
|
||||
@@ -29,7 +30,7 @@ export class UploadResourcesInput extends React.Component<UploadResourcesInputPr
|
||||
|
||||
onFileSubmit(ev: React.MouseEvent<HTMLButtonElement>) {
|
||||
if (this.state.file !== undefined) {
|
||||
const url = 'http://localhost:8000/uploads';
|
||||
const url = `${serverURL}/uploads`;
|
||||
const formData = new FormData();
|
||||
formData.append('upload', this.state.file);
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export { DragContextProvider, DragStartFn, DragSharedInfo } from './DragContextProvider';
|
||||
export { XYPair, deppCloneNaive, CanvasTextNode, CanvasImageNode } from './utils';
|
||||
export { XYPair, deepCloneNaive, CanvasTextNode, CanvasImageNode } from './utils';
|
||||
export {serverURL} from './urls';
|
||||
@@ -0,0 +1 @@
|
||||
export const serverURL = 'http://localhost:8000';
|
||||
@@ -3,7 +3,7 @@ export interface XYPair {
|
||||
y: number;
|
||||
}
|
||||
|
||||
export function deppCloneNaive<T>(originalObject: T): T {
|
||||
export function deepCloneNaive<T>(originalObject: T): T {
|
||||
return JSON.parse(JSON.stringify(originalObject));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user