Skip to content

Commit c3e2c08

Browse files
committed
Merge remote-tracking branch 'origin/main' into Add-a-Landing-Page-#10
2 parents 8429df6 + 7b6c6f7 commit c3e2c08

6 files changed

Lines changed: 280 additions & 135 deletions

File tree

components/core/App.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const App = (props) => {
1818
const [loading, setLoading] = useState(true); // shapes loading
1919

2020
const [searchTerm, setSearchTerm] = useState(""); // search
21+
const [sort, setSort] = useState("popularity"); // sort
2122

2223
const { user } = props;
2324

@@ -92,7 +93,9 @@ const App = (props) => {
9293
<>
9394
<Header {...props}
9495
searchTerm={searchTerm}
95-
setSearchTerm={setSearchTerm}/>
96+
setSearchTerm={setSearchTerm}
97+
sort={sort}
98+
setSort={setSort} />
9699
{loading ? (
97100
<Loader
98101
style={{margin: '20% auto auto 42%'}}
@@ -102,7 +105,7 @@ const App = (props) => {
102105
width={300}
103106
/>
104107
) : (
105-
<ShapeList {...props} data={ data } searchTerm={searchTerm} />
108+
<ShapeList {...props} data={ data } searchTerm={searchTerm} sort={sort} />
106109
)}
107110
</>
108111
);

components/core/CopyShapeSource.js

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import React, { useState } from "react";
2+
3+
// dynamic from Next.js
4+
import dynamic from "next/dynamic";
5+
6+
// Bootstrap
7+
import Modal from "react-bootstrap/Modal";
8+
import Container from 'react-bootstrap/Container'
9+
import Row from 'react-bootstrap/Row'
10+
import Col from 'react-bootstrap/Col'
11+
import Button from "react-bootstrap/Button";
12+
import Form from 'react-bootstrap/Form';
13+
import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup'
14+
import ToggleButton from 'react-bootstrap/ToggleButton'
15+
16+
// Styled Component
17+
import styled from "styled-components";
18+
19+
// Clip-Path
20+
const Shape = dynamic(import("react-clip-path"), { ssr: false });
21+
22+
const ShapeContainer = styled.section`
23+
border: solid 1px var(--color-neutral-30);
24+
padding: 1rem;
25+
`;
26+
27+
// Toast
28+
import toast from "react-hot-toast";
29+
30+
// icons
31+
import { FiCopy } from 'react-icons/fi';
32+
33+
// misc utilities
34+
import { getShapeId } from "../../utils/misc";
35+
36+
const CSSDisplay = styled.span`
37+
white-space: pre-line;
38+
`;
39+
40+
const CopyIcon = styled(FiCopy)`
41+
cursor: pointer;
42+
`;
43+
44+
const CopyShapeSource = ({ show, setShow, shape }) => {
45+
const [type, setType] = useState('css');
46+
const [selector, setSelector] = useState(shape.name);
47+
48+
console.log(shape);
49+
50+
const handleSelectorChange = evt => {
51+
const value = evt.target.value;
52+
if (!value) {
53+
setSelector(shape.name);
54+
} else {
55+
setSelector(value);
56+
}
57+
}
58+
59+
const getCSSSelector = () => {
60+
61+
return selector.toLowerCase().split(' ').join('-');
62+
}
63+
64+
const getCSS = formula => {
65+
const css = `.${getCSSSelector()} { \n clip-path: ${formula}; \n background-color: #809000; \n width: 300px; \n height: 300px; \n }`;
66+
console.log(css);
67+
return css;
68+
}
69+
70+
const copy = async (formula, css) => {
71+
let text = formula;
72+
if (css) {
73+
text = getCSS(formula);
74+
}
75+
try {
76+
await navigator.clipboard.writeText(text);
77+
toast.success("Successfully Copied!");
78+
console.log("The CSS copied to clipboard");
79+
} catch (err) {
80+
console.error("Failed to copy: ", err);
81+
}
82+
}
83+
84+
return(
85+
<>
86+
{true && (
87+
<Modal
88+
size="lg"
89+
aria-labelledby="contained-modal-title-vcenter"
90+
show={show}
91+
onHide={() => setShow(false)}
92+
centered
93+
>
94+
<Modal.Header closeButton>
95+
<Modal.Title>Copy Source for {shape.name} </Modal.Title>
96+
</Modal.Header>
97+
<Modal.Body>
98+
<Container fluid>
99+
<Row>
100+
<Col>
101+
<Form>
102+
<div>
103+
<Form.Group>
104+
<Form.Label>Export As</Form.Label>
105+
<div>
106+
<ToggleButtonGroup type="radio" name="options" defaultValue={1} variant="outline-dark" size="sm" defaultValue={type}>
107+
<ToggleButton id="tbg-radio-1" value={'css'} variant="outline-dark" onClick={() => setType('css')}>
108+
Show CSS
109+
</ToggleButton>
110+
<ToggleButton id="tbg-radio-2" value={'clip-path'} variant="outline-dark" onClick={() => setType('clip-path')}>
111+
Show Clip-Path
112+
</ToggleButton>
113+
</ToggleButtonGroup>
114+
</div>
115+
</Form.Group>
116+
</div>
117+
{
118+
(type === 'css' && <Form.Group className="mb-3" id="export-name">
119+
<Form.Label>CSS Selector Name</Form.Label>
120+
<Form.Control type="text" name="name" value={selector} onChange={handleSelectorChange}/>
121+
</Form.Group>)
122+
}
123+
{
124+
(type &&
125+
<div>
126+
{type === 'css' &&
127+
<>
128+
<h3>CSS Snippet</h3>
129+
<CSSDisplay>
130+
<code>{getCSS(shape.formula)}</code>
131+
</CSSDisplay>
132+
<CopyIcon size={20} onClick={() => copy(shape.formula, true)}/>
133+
</>
134+
}
135+
{type === 'clip-path' &&
136+
<div>
137+
<h3>Clip-Path Value</h3>
138+
<code>{shape.formula}</code>
139+
<CopyIcon size={20} onClick={() => copy(shape.formula, false)}/>
140+
</div>
141+
}
142+
</div>
143+
)
144+
}
145+
</Form>
146+
</Col>
147+
<Col>
148+
<ShapeContainer>
149+
<Shape
150+
name={shape.name}
151+
formula={shape.formula}
152+
width="300px"
153+
height="300px"
154+
backgroundColor={shape.backgroundColor}
155+
id={getShapeId(shape.name, true)}
156+
/>
157+
</ShapeContainer>
158+
</Col>
159+
</Row>
160+
</Container>
161+
</Modal.Body>
162+
163+
<Modal.Footer>
164+
<Button variant="outline-info" onClick={() => setShow(false)}>
165+
Cancel
166+
</Button>
167+
</Modal.Footer>
168+
</Modal>
169+
)}
170+
</>
171+
)
172+
173+
};
174+
175+
export default CopyShapeSource;

components/core/ExportShape.js

Lines changed: 30 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ import download from "downloadjs";
3636
// misc utilities
3737
import { getShapeId } from "../../utils/misc";
3838

39-
// Radios
40-
import { Radios } from "..";
41-
4239
// Component
4340
const ExportShape = ({ show, setShow, shape }) => {
4441
console.log({ shape });
@@ -85,6 +82,13 @@ const ExportShape = ({ show, setShow, shape }) => {
8582
console.log({exportData});
8683
};
8784

85+
const setExportType = value => {
86+
setExportData({
87+
...exportData,
88+
'type': value
89+
});
90+
}
91+
8892
// Export method
8993
const doExport = (id, name) => {
9094
console.log(`Save as ${exportData.type}`);
@@ -146,7 +150,7 @@ const ExportShape = ({ show, setShow, shape }) => {
146150
<Row>
147151
<Col>
148152
<Form>
149-
<Form.Group className="mb-3" controlId="export-name">
153+
<Form.Group className="mb-3" id="export-name">
150154
<Form.Label>Name</Form.Label>
151155
<Form.Control type="text" name="name" value={exportData.name} onChange={handleChange}/>
152156
</Form.Group>
@@ -162,8 +166,8 @@ const ExportShape = ({ show, setShow, shape }) => {
162166
/>
163167
</Form.Group>
164168
<Row>
165-
<Form.Group as={Col} controlId="export-width">
166-
<Form.Label>Set a width(in px)</Form.Label>
169+
<Form.Group as={Col} id="export-width">
170+
<Form.Label>Set a width({exportData.width}px)</Form.Label>
167171
<Form.Control
168172
type="range"
169173
min="100"
@@ -173,8 +177,8 @@ const ExportShape = ({ show, setShow, shape }) => {
173177
name="width"
174178
onChange={handleChange}/>
175179
</Form.Group>
176-
<Form.Group as={Col} controlId="export-height">
177-
<Form.Label>Set a height(in px)</Form.Label>
180+
<Form.Group as={Col} id="export-height">
181+
<Form.Label>Set a height({exportData.height}px)</Form.Label>
178182
<Form.Control
179183
type="range"
180184
min="100"
@@ -186,78 +190,24 @@ const ExportShape = ({ show, setShow, shape }) => {
186190
</Form.Group>
187191
</Row>
188192

189-
{/* <div>
190-
<label htmlFor="export-name">Name</label>
191-
<input
192-
type="text"
193-
name="name"
194-
id="export-name"
195-
value={exportData.name}
196-
onChange={handleChange} />
197-
</div> */}
198-
199-
{/* <div>
200-
<label htmlFor="export-color">Color</label>
201-
<input
202-
type="color"
203-
name="backgroundColor"
204-
id="export-color"
205-
value={exportData.backgroundColor}
206-
onChange={handleChange} />
207-
</div> */}
208-
209-
{/* <div>
210-
<label htmlFor="export-width">Set a width(in px)</label>
211-
<input
212-
type="range"
213-
min="100"
214-
max="700"
215-
value={exportData.width}
216-
id="export-width"
217-
name="width"
218-
onChange={handleChange} />
219-
220-
<label htmlFor="export-height">Set a height(in px)</label>
221-
<input
222-
type="range"
223-
min="100"
224-
max="700"
225-
value={exportData.height}
226-
id="export-height"
227-
name="height"
228-
onChange={handleChange} />
229-
</div> */}
230-
231193
<div>
232-
<Form.Group>
233-
<Form.Label>File Format</Form.Label>
234-
<div>
235-
<ToggleButtonGroup type="radio" name="options" defaultValue={1} variant="outline-dark" size="sm" defaultValue={'png'}>
236-
<ToggleButton id="tbg-radio-1" value={'png'} variant="outline-dark">
237-
PNG
238-
</ToggleButton>
239-
<ToggleButton id="tbg-radio-2" value={'jpeg'} variant="outline-dark">
240-
JPEG
241-
</ToggleButton>
242-
<ToggleButton id="tbg-radio-3" value={'svg'} variant="outline-dark">
243-
SVG
244-
</ToggleButton>
245-
</ToggleButtonGroup>
246-
</div>
247-
</Form.Group>
248-
<Radios
249-
groupName="type"
250-
heading="Export as:"
251-
options={[
252-
{ value: "png", displayValue: "PNG" },
253-
{ value: "jpeg", displayValue: "JPEG" },
254-
{ value: "svg", displayValue: "SVG" },
255-
]}
256-
selectedOption={exportData.type}
257-
onValueChange={handleChange}
258-
/>
259-
</div>
260-
194+
<Form.Group>
195+
<Form.Label>Export As</Form.Label>
196+
<div>
197+
<ToggleButtonGroup type="radio" name="options" defaultValue={1} variant="outline-dark" size="sm" defaultValue={exportData.type}>
198+
<ToggleButton id="tbg-radio-1" value={'png'} variant="outline-dark" onClick={() => setExportType('png')}>
199+
PNG
200+
</ToggleButton>
201+
<ToggleButton id="tbg-radio-2" value={'jpeg'} variant="outline-dark" onClick={() => setExportType('jpeg')}>
202+
JPEG
203+
</ToggleButton>
204+
<ToggleButton id="tbg-radio-3" value={'svg'} variant="outline-dark" onClick={() => setExportType('svg')}>
205+
SVG
206+
</ToggleButton>
207+
</ToggleButtonGroup>
208+
</div>
209+
</Form.Group>
210+
</div>
261211
</Form>
262212
</Col>
263213
<Col>
@@ -277,7 +227,7 @@ const ExportShape = ({ show, setShow, shape }) => {
277227
</Modal.Body>
278228

279229
<Modal.Footer>
280-
<Button variant="outline-info">
230+
<Button variant="outline-info" onClick={() => setShow(false)}>
281231
Cancel
282232
</Button>
283233
<Button variant="secondary"

components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export { default as App } from "./core/App";
33
export { default as Landing } from "./core/Landing";
44
export { default as SignInModal } from "./core/SignInModal";
55
export { default as ExportShape } from "./core/ExportShape";
6+
export {default as CopyShapeSource} from "./core/CopyShapeSource";
67

78
// utils
89
export { default as Header } from "./utils/Header";

0 commit comments

Comments
 (0)