Skip to content

Commit

Permalink
map editor
Browse files Browse the repository at this point in the history
  • Loading branch information
jesse-moore committed May 25, 2021
1 parent a503e49 commit ee396fd
Show file tree
Hide file tree
Showing 39 changed files with 1,220 additions and 595 deletions.
11 changes: 8 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
"easymde": "^2.15.0",
"gpxparser": "^3.0.7",
"graphql": "15.3.0",
"idb": "^6.1.1",
"mapbox-gl": "^2.2.0",
"markdown-to-jsx": "^7.1.2",
"nanoid": "^3.1.23",
"next": "latest",
"postcss": "^8.1.10",
"react": "^16.13.1",
Expand Down
4 changes: 3 additions & 1 deletion src/components/Event/HeroImg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface HeroImageProps {
name: string | null;
size: number | null;
src: string | null;
dataURL: string | null;
};
children: React.ReactNode;
}
Expand All @@ -30,12 +31,13 @@ export const HeroImg = ({ heroImg, children }: HeroImageProps) => {
const opacity = 0.7;
const rgb = 50;
const overlay = `rgba(${rgb}, ${rgb}, ${rgb}, ${opacity})`;
const src = heroImg.src ?? heroImg.dataURL;
return (
<div
className="rounded-sm h-80 text-center pt-4 text-gray-100"
style={{
background: `linear-gradient(${overlay}, ${overlay}),
url(${heroImg.src}) center center`,
url(${src}) center center`,
}}
>
{children}
Expand Down
15 changes: 8 additions & 7 deletions src/components/EventEditor/EditorForm.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import React, { ChangeEventHandler } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '../../lib/redux/reducers';
import { EventInterface } from '../../types';

import { EventDetailsInput } from './EventDetailsInput';
import { ImageInput } from './ImageInput';
import { Input } from './Input';
import { EventInterface } from '../../types';

interface EditorFormProps {
eventState: EventInterface;
handleChange: ChangeEventHandler<HTMLInputElement>;
handleImageInput: any;
handleEventDetailsInput: any;
}

type State = RootState & { event: EventInterface };

export const EditorForm = ({
eventState,
handleChange,
handleEventDetailsInput,
handleImageInput,
}: EditorFormProps) => {
const eventState = useSelector((state: State) => state.event);
const { date, time, name, address, city, state, heroImg, eventDetails } =
eventState;

Expand Down Expand Up @@ -65,10 +69,7 @@ export const EditorForm = ({
handleChange={handleChange}
/>
<h2>Hero Image</h2>
<ImageInput
handleInput={handleImageInput}
image={heroImg}
/>
<ImageInput handleInput={handleImageInput} image={heroImg} />
<h2>Event Details</h2>
<EventDetailsInput
value={eventDetails}
Expand Down
17 changes: 8 additions & 9 deletions src/components/EventEditor/EventDetailsInput.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { ChangeEventHandler } from 'react'
import dynamic from 'next/dynamic'
import React, { ChangeEventHandler } from 'react';
import dynamic from 'next/dynamic';
const SimpleMDE = dynamic(() => import('react-simplemde-editor'), {
ssr: false,
})
import 'easymde/dist/easymde.min.css'
import { EventActionInterface } from '../../types'
});
import 'easymde/dist/easymde.min.css';

interface EventDetailsProps {
value: string
handleChange: any
value: string;
handleChange: any;
}

export const EventDetailsInput = ({
Expand All @@ -19,5 +18,5 @@ export const EventDetailsInput = ({
<div>
<SimpleMDE onChange={handleChange} value={value} />
</div>
)
}
);
};
17 changes: 9 additions & 8 deletions src/components/EventEditor/ImageInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface ImageInputInterface {
}

export const ImageInput = ({ image, handleInput }: ImageInputInterface) => {
const { error, src, name } = image;
const { error, src, name, dataURL } = image;
return (
<>
<div className="my-2">
Expand All @@ -27,14 +27,15 @@ export const ImageInput = ({ image, handleInput }: ImageInputInterface) => {
</label>
</div>

{src && name && (
<div>
<div>{image.name}</div>
<div className="w-96 max-h-56 overflow-y-auto">
<img src={src} alt={name} />
{src ||
(dataURL && name && (
<div>
<div>{image.name}</div>
<div className="w-96 max-h-56 overflow-y-auto">
<img src={src ?? dataURL} alt={name} />
</div>
</div>
</div>
)}
))}
</>
);
};
2 changes: 1 addition & 1 deletion src/components/EventEditor/ToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const ToolBar = ({ handleDiscard }: ToolBarProps) => {
<a target="_blank" href="/preview-local">
<Button type="blue" name="Live Preview" />
</a>
<Link href="/race-editor">
<Link href="/editor/race">
<ButtonLink type="green" name="Next" />
</Link>
</div>
Expand Down
88 changes: 54 additions & 34 deletions src/components/EventEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,57 @@
import React, { useEffect, useReducer, useState } from 'react';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { actions } from '../../lib/redux/reducers/eventEditor';
import { imageToDataURL, dataURLtoFile } from '../../lib/utils';
import { reducer, init } from './reducer';
import { initDB, putFile, getItem } from '../../lib/utils/indexDB';
import { EditorForm } from './EditorForm';
import { ToolBar } from './ToolBar';
import { DialogModal } from '../Common/DialogModal';
import { EventInterface } from '../../types';
import { RootState } from '../../lib/redux/reducers';

type State = RootState & { event: EventInterface };

const EventEditor = () => {
const [eventState, dispatch] = useReducer(reducer, {}, init);
const dispatch = useDispatch();
const eventState = useSelector((state: State) => state.event);
const [isLoaded, setIsLoaded] = useState(false);
// const [createEvent] = useCreateEventMutation({
// onError: (error) => console.log(error),
// });
const [discardWarning, setDiscardWarning] = useState(false);

useEffect(() => {
const initFromLocalStorage = () => {
const initFromLocalStorage = async () => {
await initDB();
const data = localStorage.getItem('eventState');
if (data) {
const localState: EventInterface = JSON.parse(data);
const heroImgLocal = localState.heroImg;
if (heroImgLocal.src && heroImgLocal.name) {
const heroImgFile = dataURLtoFile(
heroImgLocal.src,
heroImgLocal.name

const heroImgLocalFile: File = await getItem('heroImg');
if (heroImgLocalFile) {
const heroImgDataURL = await imageToDataURL(
heroImgLocalFile
);
if (heroImgFile) heroImgLocal.file = heroImgFile;
localState.heroImg = heroImgDataURL;
}
const initState = {
...localState,
heroImg: { ...heroImgLocal },
};
dispatch({ type: 'init', payload: initState });
dispatch(actions.updateEvent(localState));
}
};
initFromLocalStorage();
window.addEventListener('storage', initFromLocalStorage, true);
setIsLoaded(true);
return () => {
setDiscardWarning(false);
window.removeEventListener('storage', initFromLocalStorage, true);
};
}, []);

useEffect(() => {
localStorage.setItem('eventState', JSON.stringify(eventState));
if (isLoaded) {
const { heroImg } = eventState;
const { dataURL, ...rest } = heroImg;
const localState = { ...eventState, heroImg: rest };
localStorage.setItem('eventState', JSON.stringify(localState));
}
}, [eventState]);

const handleImageInput = async ({
Expand All @@ -53,37 +62,49 @@ const EventEditor = () => {
const { files } = target;
if (files) {
try {
const image = await imageToDataURL(files);
dispatch({
type: 'updateHeroImg',
payload: image,
});
await putFile('heroImg', files[0]);
const image = await imageToDataURL(files[0]);
dispatch(actions.updateHeroImg(image));
} catch ({ error }) {
dispatch({
type: 'updateHeroImg',
payload: { error },
});
dispatch(actions.updateHeroImg(error));
}
}
};

const handleEventDetailsInput = (value: string) => {
dispatch({
type: 'updateEventDetails',
payload: value,
});
dispatch(actions.updateEventDetails(value));
};

const handleChange = ({ target }: { target: HTMLInputElement }) => {
const { name, value } = target;
const actionType = `update${name[0].toUpperCase()}${name.substr(1)}`;
dispatch({ type: actionType, payload: value });
switch (name) {
case 'name':
dispatch(actions.updateName(value));
break;
case 'address':
dispatch(actions.updateAddress(value));
break;
case 'city':
dispatch(actions.updateCity(value));
break;
case 'state':
dispatch(actions.updateState(value));
break;
case 'date':
dispatch(actions.updateDate(value));
break;
case 'time':
dispatch(actions.updateTime(value));
break;
default:
break;
}
};

const handleDiscard = (confirm?: boolean) => {
if (confirm === true) {
localStorage.removeItem('eventState');
dispatch({ type: 'init' });
dispatch(actions.init());
setDiscardWarning(false);
} else {
setDiscardWarning(!discardWarning);
Expand Down Expand Up @@ -113,7 +134,6 @@ const EventEditor = () => {
<ToolBar handleDiscard={() => handleDiscard()} />
<EditorForm
{...{
eventState,
handleChange,
handleEventDetailsInput,
handleImageInput,
Expand Down
52 changes: 0 additions & 52 deletions src/components/EventEditor/reducer.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const Hero = () => {
className="text-xl absolute top-1/2"
style={{ transform: 'translate(20%, -50%)' }}
>
<Link href="/create_event">
<Link href="/editor/event">
<ButtonLink name="Create Event" type="primary" />
</Link>
<Button name="See Demo" type="primary" />
Expand Down
Loading

0 comments on commit ee396fd

Please sign in to comment.