mirror of
https://github.com/morten-olsen/parcel.git
synced 2026-02-08 01:36:24 +01:00
cleanup
This commit is contained in:
@@ -1,49 +1,49 @@
|
||||
import React, { useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Theme } from '../theme';
|
||||
import React, { Fragment, useState } from 'react';
|
||||
import { Menu, Dropdown, Form } from 'antd';
|
||||
import { DownOutlined, FileOutlined, FileTextOutlined } from '@ant-design/icons';
|
||||
import AddText from './AddText';
|
||||
import AddFile from './AddFile';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
`;
|
||||
|
||||
const Top = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const Button = styled.button<{
|
||||
active: boolean;
|
||||
theme: Theme;
|
||||
}>`
|
||||
background: ${({ active }) => active ? '#2c3e50' : 'transparent'};
|
||||
padding: ${({ theme }) => theme.margin.medium}px;
|
||||
border: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
`;
|
||||
|
||||
const Panel = styled.div<{
|
||||
theme: Theme;
|
||||
}>`
|
||||
background: #2c3e50;
|
||||
color: #fff;
|
||||
padding: ${({ theme }) => theme.margin.medium}px;
|
||||
`;
|
||||
const layout = {
|
||||
labelCol: { span: 2 },
|
||||
};
|
||||
|
||||
const Add: React.FC = () => {
|
||||
const [type, setType] = useState<'file' | 'text'>('text');
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={() => setType('file')}
|
||||
active={type === 'file'}
|
||||
icon={<FileOutlined />}
|
||||
>
|
||||
File
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
onClick={() => setType('text')}
|
||||
active={type === 'text'}
|
||||
icon={<FileTextOutlined />}
|
||||
>
|
||||
Text
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Top>
|
||||
<Button active={type==='text'} onClick={() => setType('text')}>Text</Button>
|
||||
<Button active={type==='file'} onClick={() => setType('file')}>File</Button>
|
||||
</Top>
|
||||
<Panel>
|
||||
{type === 'file' && <AddFile />}
|
||||
{type === 'text' && <AddText />}
|
||||
</Panel>
|
||||
</Wrapper>
|
||||
<>
|
||||
<Form {...layout}>
|
||||
<Form.Item
|
||||
label="I want to encrypt a"
|
||||
>
|
||||
<Dropdown overlay={menu}>
|
||||
<a>{type} <DownOutlined /></a>
|
||||
</Dropdown>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{type === 'text' && <AddText />}
|
||||
{type === 'file' && <AddFile />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import React, { useContext, useCallback } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Layout } from 'antd';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import EncryptionContext from '../contexts/Encryption';
|
||||
import { Upload } from 'react-feather';
|
||||
|
||||
const DropWrapper = styled.div`
|
||||
const Icon = styled(UploadOutlined)`
|
||||
font-size: 100px;
|
||||
`;
|
||||
|
||||
const DropWrapper = styled(Layout)`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -19,13 +24,11 @@ const AddFile: React.FC = () => {
|
||||
}, [])
|
||||
const {getRootProps, getInputProps} = useDropzone({ onDrop });
|
||||
return (
|
||||
<div>
|
||||
<DropWrapper {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<Upload size={200} />
|
||||
<Icon />
|
||||
<p>Drag 'n' drop some files here, or click to select files</p>
|
||||
</DropWrapper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,39 +1,57 @@
|
||||
import React, { useState, useCallback, useContext } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Input, Form, Button } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import EncryptionContext from '../contexts/Encryption';
|
||||
import { Theme } from '../theme';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
`;
|
||||
const layout = {
|
||||
labelCol: { span: 2 },
|
||||
};
|
||||
|
||||
const Text = styled.textarea<{
|
||||
theme: Theme;
|
||||
}>`
|
||||
border: none;
|
||||
height: 200px;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
padding: ${({ theme }) => theme.margin.medium}px;
|
||||
font: inherit;
|
||||
`;
|
||||
const tailLayout = {
|
||||
wrapperCol: { offset: 2 },
|
||||
};
|
||||
|
||||
const AddText : React.FC = () => {
|
||||
const { addText } = useContext(EncryptionContext);
|
||||
const [name, setName] = useState('');
|
||||
const [text, setText] = useState('');
|
||||
|
||||
const add = useCallback(() => {
|
||||
addText(text);
|
||||
addText(text, name || 'untitled');
|
||||
setText('');
|
||||
setName('');
|
||||
}, [text, addText]);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Text placeholder="Enter you message..." value={text} onChange={evt => setText(evt.target.value)} />
|
||||
<button onClick={add}>Save</button>
|
||||
</Wrapper>
|
||||
<Form {...layout}>
|
||||
<Form.Item
|
||||
label="Name"
|
||||
>
|
||||
<Input
|
||||
value={name}
|
||||
onChange={evt => setName(evt.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Message"
|
||||
>
|
||||
<Input.TextArea
|
||||
value={text}
|
||||
rows={10}
|
||||
onChange={evt => setText(evt.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item {...tailLayout}>
|
||||
<Button
|
||||
onClick={add}
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
disabled={!text}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { File } from '../contexts/Encryption';
|
||||
import {
|
||||
List,
|
||||
Button,
|
||||
} from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
SyncOutlined,
|
||||
IssuesCloseOutlined,
|
||||
LockOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { FileType } from '../contexts/Encryption';
|
||||
import { CheckCircle, XCircle, Download, Trash, Loader } from 'react-feather';
|
||||
import Row, { Cell } from './Row';
|
||||
|
||||
interface Props {
|
||||
remove: () => void;
|
||||
file: File;
|
||||
file: FileType;
|
||||
}
|
||||
|
||||
const downloadLink = (name: string, url: string) => {
|
||||
@@ -18,42 +26,51 @@ const downloadLink = (name: string, url: string) => {
|
||||
document.body.removeChild(downloadLink);
|
||||
};
|
||||
|
||||
const Button = styled.button`
|
||||
background: none;
|
||||
border: none;
|
||||
color: green;
|
||||
`;
|
||||
|
||||
const icons: {[name: string]: typeof CheckCircle} = {
|
||||
encrypting: Loader,
|
||||
failed: XCircle,
|
||||
encrypted: CheckCircle,
|
||||
const icons: {[name: string]: any} = {
|
||||
encrypting: <SyncOutlined spin />,
|
||||
failed: <IssuesCloseOutlined />,
|
||||
encrypted: <LockOutlined />,
|
||||
};
|
||||
|
||||
const IconText = ({ icon, text, ...props }) => (
|
||||
<Button
|
||||
{...props}
|
||||
icon={React.createElement(icon)}
|
||||
>
|
||||
{text}
|
||||
</Button>
|
||||
);
|
||||
|
||||
const FileView: React.FC<Props> = ({
|
||||
file,
|
||||
remove,
|
||||
}) => {
|
||||
const Icon = icons[file.status];
|
||||
const icon = icons[file.status];
|
||||
|
||||
return (
|
||||
<Row
|
||||
left={(
|
||||
<Cell><Icon /></Cell>
|
||||
)}
|
||||
title={file.name}
|
||||
body={`encrypted for ${file.reciever}`}
|
||||
right={!!file.link && (
|
||||
<>
|
||||
<Cell>
|
||||
<Button onClick={() => downloadLink(file.name, file.link)}><Download /></Button>
|
||||
</Cell>
|
||||
<Cell>
|
||||
<Button onClick={remove}><Trash /></Button>
|
||||
</Cell>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<List.Item
|
||||
actions={file.link ? [(
|
||||
<IconText
|
||||
icon={DeleteOutlined}
|
||||
danger
|
||||
text="Delete"
|
||||
onClick={remove}
|
||||
/>
|
||||
), (
|
||||
<IconText
|
||||
icon={DeleteOutlined}
|
||||
type="primary"
|
||||
text="Download"
|
||||
onClick={() => downloadLink(file.name, file.link!)}
|
||||
/>
|
||||
)]: []}
|
||||
>
|
||||
<List.Item.Meta
|
||||
avatar={icon}
|
||||
title={file.name}
|
||||
description={`Encrypted for ${file.reciever}`}
|
||||
/>
|
||||
</List.Item>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { List, Empty } from 'antd';
|
||||
import EncryptionContext from '../contexts/Encryption';
|
||||
import File from './File';
|
||||
|
||||
const Encrypt: React.FC = () => {
|
||||
const { files, deleteFile } = useContext(EncryptionContext);
|
||||
|
||||
if (Object.keys(files).length === 0) {
|
||||
return <Empty />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<List>
|
||||
{Object.entries(files).map(([id, file]) => (
|
||||
<File
|
||||
key={id}
|
||||
@@ -14,7 +19,7 @@ const Encrypt: React.FC = () => {
|
||||
remove={() => deleteFile(id)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
71
src/components/Profile.tsx
Normal file
71
src/components/Profile.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import {
|
||||
Card,
|
||||
Avatar,
|
||||
Button,
|
||||
Modal,
|
||||
} from 'antd';
|
||||
import { KeyOutlined, GithubOutlined } from '@ant-design/icons'
|
||||
import GithubContext from '../contexts/Github';
|
||||
|
||||
const IconText = ({ icon, text, ...props }) => (
|
||||
<Button
|
||||
{...props}
|
||||
icon={React.createElement(icon)}
|
||||
>
|
||||
{text}
|
||||
</Button>
|
||||
);
|
||||
|
||||
const Profile: React.FC = () => {
|
||||
const { user, keys } = useContext(GithubContext);
|
||||
const [showKeys, setShowKeys] = useState(false);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
visible={showKeys}
|
||||
onOk={() => setShowKeys(false)}
|
||||
onCancel={() => setShowKeys(false)}
|
||||
title="Keys"
|
||||
>
|
||||
<pre>
|
||||
{keys!.join('\n\n')}
|
||||
</pre>
|
||||
</Modal>
|
||||
<Card
|
||||
style={{ width: 300, marginTop: 16, alignSelf: 'center' }}
|
||||
actions={[(
|
||||
<IconText
|
||||
key="showkeys"
|
||||
text="Show keys"
|
||||
icon={KeyOutlined}
|
||||
onClick={() => setShowKeys(true)}
|
||||
/>
|
||||
), (
|
||||
<a target="_blank" href={`https://github.com/${user.login}`}>
|
||||
<IconText
|
||||
key="gotogithub"
|
||||
text="Go to Github"
|
||||
icon={GithubOutlined}
|
||||
/>
|
||||
</a>
|
||||
)]}
|
||||
>
|
||||
<Card.Meta
|
||||
title={user.name}
|
||||
avatar={(
|
||||
<Avatar src={user.avatar_url} size={80} />
|
||||
)}
|
||||
description={user.location}
|
||||
/>
|
||||
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Profile;
|
||||
Reference in New Issue
Block a user