Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/components/ContentMapping/ContentMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { Stub, StubEditor } from '../ContentWidgets/_Stub/Stub';
import { ContentSingularData } from '../_data/ContentSingularData';
import { ExampleImage } from '../ContentWidgets/ExampleImage/ExampleImage';
import { ExampleImageEditor } from '../ContentWidgets/ExampleImage/ExampleImageEditor';
import { ToDoList } from '../ContentWidgets/ToDoList/ToDoList';
import { ToDoListEditor } from '../ContentWidgets/ToDoList/ToDoListEditor';
import { Homepage } from '../ContentWidgets/Homepage/Homepage';
import { HomepageEditor } from '../ContentWidgets/Homepage/HomepageEditor';

export type WidgetEditorProps = {
originalContent: ContentSingularData,
Expand All @@ -22,7 +26,9 @@ type ContentMappingType = {
export enum WidgetTypes {
PLAIN_TEXT = "PLAIN_TEXT",
STUB = "STUB",
EXAMPLE_IMAGE = "EXAMPLE_IMAGE"
EXAMPLE_IMAGE = "EXAMPLE_IMAGE",
TO_DO_LIST = "TO_DO_LIST",
HOMEPAGE = "HOMEPAGE"
}

export const ContentMapping: ContentMappingType = {
Expand All @@ -37,5 +43,13 @@ export const ContentMapping: ContentMappingType = {
EXAMPLE_IMAGE: {
widget: ExampleImage,
editor: ExampleImageEditor
},
TO_DO_LIST: {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the ToDoList. This was from the tutorial.

widget: ToDoList,
editor: ToDoListEditor
},
HOMEPAGE: {
widget: Homepage,
editor: HomepageEditor
}
}
14 changes: 14 additions & 0 deletions src/components/ContentWidgets/Homepage/Homepage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not override global styles for this. You should wrap your component in some .homepage class and then use it within your CSS.

box-sizing: border-box;
}

body, html {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also stick to the global font family we provide

}

h1, h2 {
color: white
}
45 changes: 45 additions & 0 deletions src/components/ContentWidgets/Homepage/Homepage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { ContentSingularData } from "../../_data/ContentSingularData";

export type HomepageItem = {
title: string,
subtitle: string,
backgroundImage: string,
blur: string,
bgLightness: string,
bgOpacity: string
}

/**
* A widget for the Home page
*
* Last Modified
* Allison Lee
* July 19, 2019
**/
export const Homepage: React.FC<ContentSingularData> = ({
homepage_content
}) => {
if (!homepage_content) {
return <></>
}

return (
<>
<div style={{
backgroundImage: `url(${homepage_content.backgroundImage})`,
height: `100vh`,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe have these be constants broken out into another file?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with the others

backgroundPosition: `center`,
backgroundRepeat: `no-repeat`,
backgroundSize: `cover`,
backgroundColor: `hsla(0, 0% ,${homepage_content.bgLightness}%, ${homepage_content.bgOpacity})`,
filter: `blur(${homepage_content.blur}px)`,
}}>
</div>
<div style={{textAlign: `center`, transform: `translate(0, -400%)`}}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something about this -400 translation seems a bit hacky.

<h1>{homepage_content.title}</h1>
<h2>{homepage_content.subtitle}</h2>
</div>
</>
)
}
73 changes: 73 additions & 0 deletions src/components/ContentWidgets/Homepage/HomepageEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { FormEvent, ChangeEvent } from 'react';
import { WidgetEditorProps } from '../../ContentMapping/ContentMapping';
import './Homepage.css';

export const HomepageEditor: React.FC<WidgetEditorProps> = ({
originalContent,
editedContent,
setEditedContentOnChange
}) => {
let homepage_content = editedContent.homepage_content ||
{title: "Title not set", subtitle: "Subtitle not set", backgroundImage: "", blur: "", bgLightness: "", bgOpacity: ""};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have this object be put into a constant defaultHomepageContent or something and also split it up for one property per line eg

{
  title: "",
  subtitle: ""
  ...
}


const updateTitle = (e: React.ChangeEvent<HTMLInputElement>) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions can be condensed into one function by taking advantage of the e.target.name property.

const generalUpdate = (e) => {
  homepage_content[e.target.name] = e.target.value;
  setEditedContentOnChange("homepage_content", homepage_content);
}

then you just add a name="___" property to the input component

homepage_content.title = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

const updateSubtitle = (e: React.ChangeEvent<HTMLInputElement>) => {
homepage_content.subtitle = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

const updateBackgroundImage = (e: React.ChangeEvent<HTMLInputElement>) => {
homepage_content.backgroundImage = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

const updateBlur = (e: React.ChangeEvent<HTMLInputElement>) => {
homepage_content.blur = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

const updateBgLightness = (e: React.ChangeEvent<HTMLInputElement>) => {
homepage_content.bgLightness = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

const updateBgOpacity = (e: React.ChangeEvent<HTMLInputElement>) => {
homepage_content.bgOpacity = e.target.value;
setEditedContentOnChange("homepage_content", homepage_content);
}

return <>
<div style={{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are free to actually just call the view component here. That would be more scalable so when we update the view component we dont have to update the editor component's view too.

backgroundImage: `url(${homepage_content.backgroundImage})`,
height: `100vh`,
backgroundPosition: `center`,
backgroundRepeat: `no-repeat`,
backgroundSize: `cover`,
backgroundColor: `hsla(0, 0% ,${homepage_content.bgLightness}%, ${homepage_content.bgOpacity})`,
filter: `blur(${homepage_content.blur}px)`,
}}>
</div>
<div style={{textAlign: `center`, transform: `translate(0, -400%)`}}>
<h1>{homepage_content.title}</h1>
<h2>{homepage_content.subtitle}</h2>
</div>
<div>
<h3>Title</h3>
<input type="text" onChange={(e) => updateTitle(e)} />
<h3>Subtitle</h3>
<input type="text" onChange={(e) => updateSubtitle(e)} />
<h3>Background Image</h3>
<input type="text" onChange={(e) => updateBackgroundImage(e)} />
<h3>Blur</h3>
<input type="number" onChange={(e) => updateBlur(e)} />
<h3>Background Lightness</h3>
<input type="number" onChange={(e) => updateBgLightness(e)} />
<h3>Background Opacity</h3>
<input type="number" onChange={(e) => updateBgOpacity(e)} />
</div>
</>
}
3 changes: 3 additions & 0 deletions src/components/ContentWidgets/ToDoList/ToDoList.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ul {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this file.

list-style-type: none;
}
34 changes: 34 additions & 0 deletions src/components/ContentWidgets/ToDoList/ToDoList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this file

import { ContentSingularData } from "../../_data/ContentSingularData";

export type ToDoListItem = {
toDoListItem_hash: string
toDoListItem_task: string
}

/**
* A to-do list widget
*
* Last Modified
* Allison Lee
* July 11, 2019
**/
export const ToDoList: React.FC<ContentSingularData> = ({
toDoList_content
}) => {
if (!toDoList_content) {
return <></>
}

return (
<ul>
{toDoList_content.map((item) => {
return (
<li key={item.toDoListItem_hash}>
{item.toDoListItem_task}
</li>
)
})}
</ul>
)
}
66 changes: 66 additions & 0 deletions src/components/ContentWidgets/ToDoList/ToDoListEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { FormEvent, ChangeEvent } from 'react';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this file

import { WidgetEditorProps } from '../../ContentMapping/ContentMapping';
import './ToDoList.css';
import { ToDoListItem } from './ToDoList';

export const ToDoListEditor: React.FC<WidgetEditorProps> = ({
originalContent,
editedContent,
setEditedContentOnChange
}) => {
let toDoList_content = editedContent.toDoList_content || [];
let taskText = "";

const generateHash: () => string = () => {
const lengthOfGeneratedHash = 24;

let randomInt8s = new Uint8Array(lengthOfGeneratedHash / 2);
window.crypto.getRandomValues(randomInt8s);
return randomInt8s.reduce((accumulator, randomInt) => {
return accumulator + ('0' + randomInt.toString(16)).substr(2)
}, "")
}

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
taskText = e.target.value;
}

const addToDo = (e: FormEvent) => {
e.preventDefault();
let listCopy = [...toDoList_content];
let newKey = generateHash();
listCopy.push({toDoListItem_hash: newKey, toDoListItem_task: taskText});
setEditedContentOnChange("toDoList_content", listCopy);
}

const removeToDo = (hashToRemove: string) => {
let listCopy = [...toDoList_content];
let newList: ToDoListItem[] = [];

listCopy.forEach(item => {
if (item.toDoListItem_hash !== hashToRemove) {
newList.push(item)
}
});
setEditedContentOnChange("toDoList_content", newList);
}

return <>
<ul>
{
toDoList_content.map((item) => {
return (
<li key={item.toDoListItem_hash}>{item.toDoListItem_task}
<button onClick={() => removeToDo(item.toDoListItem_hash)}>&times;</button>
</li>
);
})
}
</ul>
<h3>Add New To-Do Item</h3>
<form onSubmit={(e) => addToDo(e)}>
<input type="text" placeholder="Type task to do..." onChange={(e) => handleChange(e)}/>
<button type="submit">Add Task</button>
</form>
</>
}
5 changes: 5 additions & 0 deletions src/components/_data/ContentSingularData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ToDoListItem } from '../ContentWidgets/ToDoList/ToDoList';
import { HomepageItem } from '../ContentWidgets/Homepage/Homepage';

export type ContentSingularData = {
plainText_content?: string
exampleImage_imageLink?: string
exampleImage_percentageSize?: number
toDoList_content?: ToDoListItem[]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this todolist stuff

homepage_content?: HomepageItem
[idx: string]: any
}