Skip to content

Commit 695de95

Browse files
committed
CRUD tags in localStorage
1 parent 4997016 commit 695de95

File tree

3 files changed

+82
-9
lines changed

3 files changed

+82
-9
lines changed
Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,55 @@
11
import React from 'react'
22
import styled from 'styled-components'
3-
import { Drawing } from '../../types'
3+
import { Drawing, TagDrawingSets } from '../../types'
44
import Modal from 'react-modal'
5+
import { addTagToDrawing, loadTagDrawingSets, drawingHasTag, removeTagFromDrawing } from '../../lib/hashtags'
56

67
export const AddTagModal: React.FC<{ drawing: Drawing; isOpen: boolean; closeModal: () => void }> = ({
78
drawing,
89
isOpen,
910
closeModal,
1011
}) => {
11-
const onNewTagSubmit: (e: React.FormEvent) => void = (e) => {
12+
const [newTag, setNewTag] = React.useState('')
13+
const [tagDrawingSets, setTagDrawingSets] = React.useState<TagDrawingSets>(loadTagDrawingSets())
14+
15+
function onNewTagSubmit(e: React.FormEvent<HTMLFormElement>) {
16+
addTagToDrawing(newTag, drawing)
17+
setNewTag('')
18+
setTagDrawingSets(loadTagDrawingSets())
1219
e.preventDefault()
1320
}
21+
const tags = Object.keys(tagDrawingSets)
1422

1523
return (
1624
<Modal
1725
isOpen={isOpen}
1826
onRequestClose={closeModal}
1927
>
20-
<CloseButton onClick={closeModal}>close</CloseButton>
21-
<Title>Add Hashtags</Title>
22-
<pre>{JSON.stringify(drawing, null, 2)}</pre>
23-
<form onSubmit={onNewTagSubmit}>
24-
New: <input /> <input type='submit' />
25-
</form>
28+
<div onKeyDown={e => e.stopPropagation()}>
29+
<CloseButton onClick={closeModal}>close</CloseButton>
30+
<Title>Add Hashtags</Title>
31+
<pre style={{ fontSize: '9px' }}>{JSON.stringify(drawing, null, 2)}</pre>
32+
<form onSubmit={onNewTagSubmit}>
33+
New: <input value={newTag} onChange={e => setNewTag(e.currentTarget.value)} /> <input type='submit' />
34+
</form>
35+
<br />
36+
<ul>
37+
{tags.sort().map(tag => (
38+
<Tag key={tag}>
39+
<label>
40+
<input
41+
type='checkbox'
42+
checked={drawingHasTag(drawing, tag)}
43+
onChange={e => {
44+
e.currentTarget.checked ? addTagToDrawing(tag, drawing) : removeTagFromDrawing(tag, drawing)
45+
setTagDrawingSets(loadTagDrawingSets())
46+
}}
47+
/> {tag}
48+
</label>
49+
</Tag>
50+
))}
51+
</ul>
52+
</div>
2653
</Modal>
2754
)
2855
}
@@ -34,6 +61,13 @@ const CloseButton = styled.button.attrs({ classNames: 'Explorer__AddTagModal__Cl
3461
top: 24px;
3562
`
3663

37-
const Title = styled.h1.attrs({ classNames: 'Explorer__AddTagModal__CloseButton' })`
64+
const Title = styled.h1.attrs({ classNames: 'Explorer__AddTagModal__Title' })`
3865
text-align: center;
3966
`
67+
68+
const Tag = styled.li.attrs({ classNames: 'Explorer__AddTagModal__Tag' })`
69+
border-right: 1px solid #DDD;
70+
display: inline-block;
71+
margin: 8px 0;
72+
padding: 0 8px;
73+
`

explorer/lib/hashtags.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Drawing, TagDrawingSets } from '../types'
2+
3+
export function loadTagDrawingSets(): TagDrawingSets {
4+
if (typeof window === 'undefined') return {} as TagDrawingSets
5+
return JSON.parse(localStorage.getItem('tagDrawingSets') || '{}') as TagDrawingSets
6+
}
7+
8+
export function saveTagDrawingSets(tagDrawingSets: TagDrawingSets) {
9+
localStorage.setItem('tagDrawingSets', JSON.stringify(tagDrawingSets))
10+
}
11+
12+
export function drawingHasTag(drawing: Drawing, tag: string) {
13+
const tagDrawingSets: TagDrawingSets = loadTagDrawingSets()
14+
const drawings: Drawing[] = tagDrawingSets[tag] ?? []
15+
return drawings.some(o => o.slug === drawing.slug)
16+
}
17+
18+
export function addTagToDrawing(tag: string, drawing: Drawing) {
19+
const tagDrawingSets: TagDrawingSets = loadTagDrawingSets()
20+
const drawings: Drawing[] = tagDrawingSets[tag] ?? []
21+
if (!drawings.includes(drawing)) {
22+
drawings.push(drawing)
23+
tagDrawingSets[tag] = drawings
24+
saveTagDrawingSets(tagDrawingSets)
25+
}
26+
}
27+
28+
export function removeTagFromDrawing(tag: string, drawing: Drawing) {
29+
const tagDrawingSets: TagDrawingSets = loadTagDrawingSets()
30+
const drawings: Drawing[] | undefined = tagDrawingSets[tag]
31+
if (!drawings) return
32+
tagDrawingSets[tag] = drawings.filter(o => o.slug !== drawing.slug)
33+
if (!tagDrawingSets[tag].length) delete tagDrawingSets[tag]
34+
saveTagDrawingSets(tagDrawingSets)
35+
}

explorer/types/drawing-models.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ export interface DayDrawingSetsByYear
2323
extends Readonly<{
2424
[year: number]: DayDrawingSets
2525
}> {}
26+
27+
export interface TagDrawingSets {
28+
[tag: string]: Drawing[]
29+
}

0 commit comments

Comments
 (0)