create delete button from /snippets

main
Mike Fix 5 years ago
parent d693a54437
commit 1372a4066d

@ -8,6 +8,7 @@ const Button = ({
onClick = () => {}, onClick = () => {},
background = COLORS.BLACK, background = COLORS.BLACK,
color = COLORS.SECONDARY, color = COLORS.SECONDARY,
textColor,
hoverBackground = COLORS.HOVER, hoverBackground = COLORS.HOVER,
hoverColor, hoverColor,
disabled, disabled,
@ -33,7 +34,7 @@ const Button = ({
display: ${display || 'flex'}; display: ${display || 'flex'};
flex: ${flex}; flex: ${flex};
background-color: ${background}; background-color: ${background};
color: ${color}; color: ${textColor || color};
box-shadow: ${border ? `inset 0px 0px 0px ${selected ? 2 : 1}px ${color}` : 'initial'}; box-shadow: ${border ? `inset 0px 0px 0px ${selected ? 2 : 1}px ${color}` : 'initial'};
cursor: ${disabled ? 'not-allowed' : 'pointer'}; cursor: ${disabled ? 'not-allowed' : 'pointer'};
outline: none; outline: none;

@ -0,0 +1,22 @@
import React from 'react'
import Button from './Button'
export default function ConfirmButton(props) {
const [confirmed, setConfirmed] = React.useState(false)
return (
<Button
{...props}
onClick={e => {
if (confirmed) {
props.onClick(e)
setConfirmed(false)
} else {
setConfirmed(true)
}
}}
onBlur={() => setConfirmed(false)}
>
{confirmed ? 'Are you sure?' : props.children}
</Button>
)
}

@ -3,31 +3,11 @@ import { useAsyncCallback, useOnline } from '@dawnlabs/tacklebox'
import Button from './Button' import Button from './Button'
import Toolbar from './Toolbar' import Toolbar from './Toolbar'
import ConfirmButton from './ConfirmButton'
import { useAuth } from './AuthContext' import { useAuth } from './AuthContext'
import { COLORS } from '../lib/constants' import { COLORS } from '../lib/constants'
function ConfirmButton(props) {
const [confirmed, setConfirmed] = React.useState(false)
return (
<Button
{...props}
onClick={e => {
if (confirmed) {
props.onClick(e)
setConfirmed(false)
} else {
setConfirmed(true)
}
}}
onBlur={() => setConfirmed(false)}
>
{confirmed ? 'Are you sure?' : props.children}
</Button>
)
}
function DeleteButton(props) { function DeleteButton(props) {
const [onClick, { loading }] = useAsyncCallback(props.onClick) const [onClick, { loading }] = useAsyncCallback(props.onClick)

@ -7,6 +7,7 @@ import { useAsyncCallback } from '@dawnlabs/tacklebox'
import Button from '../components/Button' import Button from '../components/Button'
import LoginButton from '../components/LoginButton' import LoginButton from '../components/LoginButton'
import ConfirmButton from '../components/ConfirmButton'
import { useAuth } from '../components/AuthContext' import { useAuth } from '../components/AuthContext'
import { useAPI } from '../components/ApiContext' import { useAPI } from '../components/ApiContext'
@ -29,95 +30,122 @@ function Snippet(props) {
const config = { ...DEFAULT_SETTINGS, ...props, fontSize: '2px', windowControls: false } const config = { ...DEFAULT_SETTINGS, ...props, fontSize: '2px', windowControls: false }
return ( return (
<Link prefetch={false} href={`/${props.id}`}> <div className="snippet">
<a href={`/${props.id}`}> <div className="column">
<div className="snippet"> <div className="carbon-container">
<div className="column"> <Carbon key={config.language} readOnly={true} config={config} loading={props.loading}>
<div className="carbon-container"> {props.code}
<Carbon key={config.language} readOnly={true} config={config} loading={props.loading}> </Carbon>
{props.code}
</Carbon>
</div>
<div className="id">{props.title || props.id}</div>
<div className="meta">
Edited {formatDistanceToNow(correctTimestamp(props.updatedAt), { addSuffix: true })}
</div>
</div>
</div> </div>
<style jsx> <div className="id">{props.title || props.id}</div>
{` <div className="meta">
.snippet { Edited {formatDistanceToNow(correctTimestamp(props.updatedAt), { addSuffix: true })}
position: relative; </div>
width: 266px; </div>
height: 266px; <div className="overlay">
border: 1px solid ${COLORS.SECONDARY}; <Link prefetch={false} href={`/${props.id}`}>
border-radius: 3px; <Button
cursor: pointer !important; large
overflow: hidden; border
} center
.snippet:hover { flex="unset"
background: ${COLORS.HOVER}; margin="0 auto 1.5rem"
} padding="0.5rem 16px"
.snippet:hover:after { color="#fff"
position: absolute; >
content: '↗'; Open
display: flex; </Button>
align-items: center; </Link>
justify-content: center; <ConfirmButton
background: ${COLORS.HOVER}; large
opacity: 0.8; border
top: 0px; center
right: 0px; flex="unset"
bottom: 0px; margin="0 auto"
left: 0px; padding="0.5rem 20px"
font-size: 48px; color="#fff"
z-index: 999; textColor={COLORS.RED}
} hoverColor={COLORS.RED}
.column { onClick={props.deleteSnippet}
display: flex; >
flex-direction: column; Delete
justify-content: space-between; </ConfirmButton>
height: 100%; </div>
overflow: hidden; <style jsx>
} {`
.id { .snippet {
position: absolute; position: relative;
top: 0.25rem; width: 266px;
right: 0.125rem; height: 266px;
border-radius: 3px; border: 1px solid ${COLORS.SECONDARY};
background: ${COLORS.SECONDARY}; border-radius: 3px;
color: ${COLORS.BLACK}; cursor: pointer !important;
font-size: 10px; overflow: hidden;
padding: 0.125rem; }
max-width: 80%; .overlay {
text-overflow: ellipsis; display: none;
white-space: nowrap; position: absolute;
overflow: hidden; content: '↗';
z-index: 200; flex-direction: column;
} align-items: center;
.carbon-container { justify-content: center;
width: 100%; background: ${COLORS.HOVER};
height: 100%; opacity: 0.8;
top: 0px;
overflow: hidden; right: 0px;
color: ${COLORS.SECONDARY}; bottom: 0px;
width: 266px; left: 0px;
} font-size: 48px;
.carbon-container :global(.CodeMirror__container .CodeMirror span) { z-index: 999;
font-size: 2px !important; }
} .snippet:hover .overlay {
.meta { display: flex;
background: ${COLORS.SECONDARY}; background: ${COLORS.HOVER};
color: ${COLORS.DARK_GRAY}; }
width: 100%; .column {
font-size: 10px; display: flex;
padding: 0.24rem; flex-direction: column;
bottom: 0px; justify-content: space-between;
} height: 100%;
`} overflow: hidden;
</style> }
</a> .id {
</Link> position: absolute;
top: 0.25rem;
right: 0.25rem;
border-radius: 3px;
background: ${COLORS.SECONDARY};
color: ${COLORS.BLACK};
font-size: 10px;
padding: 0.125rem;
max-width: 80%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
z-index: 200;
}
.carbon-container {
width: 100%;
height: 100%;
overflow: hidden;
color: ${COLORS.SECONDARY};
width: 266px;
}
.carbon-container :global(.CodeMirror__container .CodeMirror span) {
font-size: 2px !important;
}
.meta {
background: ${COLORS.SECONDARY};
color: ${COLORS.DARK_GRAY};
width: 100%;
font-size: 10px;
padding: 0.24rem;
bottom: 0px;
}
`}
</style>
</div>
) )
} }
@ -127,9 +155,9 @@ function ActionButton(props) {
border border
center center
margin="0.5rem" margin="0.5rem"
flex="0 0 266px" flex="unset"
color={COLORS.GRAY} color={COLORS.GRAY}
style={{ minHeight: 266 }} style={{ width: 266, minHeight: 266 }}
{...props} {...props}
/> />
) )
@ -164,6 +192,10 @@ function SnippetsPage() {
} }
}, [loadMore, page, user]) }, [loadMore, page, user])
function deleteSnippet(id) {
return api.snippet.delete(id).then(() => setSnippets(curr => curr.filter(s => s.id !== id)))
}
if (!user) { if (!user) {
return <LoginButton /> return <LoginButton />
} }
@ -171,7 +203,12 @@ function SnippetsPage() {
return ( return (
<div className="container"> <div className="container">
{snippets.map(snippet => ( {snippets.map(snippet => (
<Snippet key={snippet.id} {...snippet} loading={!mounted} /> <Snippet
key={snippet.id}
{...snippet}
loading={!mounted}
deleteSnippet={deleteSnippet.bind(null, snippet.id)}
/>
))} ))}
{snippets.length && previousRes && previousRes.length < 10 ? null : ( {snippets.length && previousRes && previousRes.length < 10 ? null : (
<ActionButton <ActionButton

Loading…
Cancel
Save