Final polish + cleaning

This commit is contained in:
Adi Thakral 2021-04-05 11:00:14 -04:00 committed by Steven Xu
parent ba210c7c4e
commit 7b07f8a9dc
10 changed files with 46 additions and 96 deletions

View File

@ -0,0 +1,4 @@
.input {
width: 100%;
padding-right: 16px;
}

View File

@ -1,5 +1,6 @@
import React from "react";
import { Draggable } from "react-beautiful-dnd";
import styles from "./Link.module.css";
export type EditableLink = {
name: string;
@ -56,6 +57,7 @@ const Link: React.FC<LinkProps> = ({ index, link, onChange, onDelete }) => {
type="text"
placeholder="Edit Title"
value={link.name}
className={styles.input}
onChange={(e) => onChange({ ...link, name: e.target.value })}
/>
@ -74,6 +76,7 @@ const Link: React.FC<LinkProps> = ({ index, link, onChange, onDelete }) => {
type="url"
placeholder="https://url"
value={link.url}
className={styles.input}
onChange={(e) => onChange({ ...link, url: e.target.value })}
/>

View File

@ -15,26 +15,26 @@ interface EditorProps {
const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
const { displayDragDrop } = useDragDrop();
const { headers } = useAuth();
const [formState, setFormState] = useState<EditableLink[]>(links);
const [editableLinks, setEditableLinks] = useState<EditableLink[]>(links);
useEffect(() => {
setFormState(links);
setEditableLinks(links);
}, [links]);
const handleOnDragEnd = (result: DropResult) => {
if (!result?.destination) return;
const items = Array.from(formState);
const items = Array.from(editableLinks);
const [reorderedItem] = items.splice(result.source.index, 1);
items.splice(result.destination.index, 0, reorderedItem);
setFormState(items);
setEditableLinks(items);
};
/*note that we need to make the new links name render with nothing*/
const handleOnClickAdd = () =>
setFormState([
...formState,
setEditableLinks([
...editableLinks,
{
name: "",
url: "",
@ -44,21 +44,20 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
]);
const onSubmit = async () => {
// const res = await updateLinks(formState);
const res = await fetch("/api/editor/links", {
method: "POST",
headers: {
"Content-Type": "application/json",
...headers,
},
body: JSON.stringify({ links: formState }),
body: JSON.stringify({ links: editableLinks }),
});
const updatedLinks = await res.json();
setLinks(updatedLinks);
};
const onCancel = () => {
setFormState(links);
setEditableLinks(links);
};
return (
@ -80,22 +79,22 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
{...provided.droppableProps}
ref={provided.innerRef}
>
{formState.map((link, index) => (
{editableLinks.map((link, index) => (
<Link
key={index}
index={index}
link={link}
onChange={(newLink: EditableLink) =>
setFormState([
...formState.slice(0, index),
setEditableLinks([
...editableLinks.slice(0, index),
newLink,
...formState.slice(index + 1),
...editableLinks.slice(index + 1),
])
}
onDelete={() =>
setFormState([
...formState.slice(0, index),
...formState.slice(index + 1),
setEditableLinks([
...editableLinks.slice(0, index),
...editableLinks.slice(index + 1),
])
}
/>
@ -111,7 +110,7 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
<button
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
onClick={onSubmit}
disabled={equal(formState, links)}
disabled={equal(editableLinks, links)}
>
Submit
</button>
@ -119,13 +118,13 @@ const Editor: React.FC<EditorProps> = ({ links, setLinks }) => {
<button
className="block flex py-2 items-center justify-center rounded-md bg-purple-600 hover:bg-purple-500 cursor-pointer text-white w-full disabled:opacity-50"
onClick={onCancel}
disabled={equal(formState, links)}
disabled={equal(editableLinks, links)}
>
Cancel
</button>
</div>
</div>
<Preview links={formState} />
<Preview links={editableLinks.filter((link) => link.active)} />
</div>
);
};

View File

@ -1,27 +1,30 @@
import React, { ComponentPropsWithoutRef } from "react";
import { Link } from "utils/types";
import React from "react";
export interface Link {
name: string;
url: string;
}
interface LinkProps extends ComponentPropsWithoutRef<"div"> {
interface Props {
links: Link[];
logClicks?: boolean;
}
export const Links: React.FC<LinkProps> = ({ links, className }) => {
const handleClick = (name: string, url: string) =>
fetch("/api/clicks", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name, url }),
});
export const Links: React.FC<Props> = ({ links, logClicks = false }) => {
const handleClick = (name: string, url: string) => {
if (logClicks) {
fetch("/api/clicks", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name, url }),
});
}
};
return (
<div
className={`text-s flex flex-col items-center w-full top-6 font-karla ${className}`}
className={`text-s flex flex-col items-center w-full top-6 font-karla`}
>
<img className="mb-3" src="csc_logo.png" alt="CSC Logo" width="100px" />
<h1 className="font-bold">@uwcsclub</h1>

View File

@ -1,9 +1,7 @@
import { Links } from "components/Links";
import { Link, Links } from "components/Links";
import React from "react";
import styles from "./styles.module.css";
import { Link } from "utils/types";
interface PreviewProps {
links: Link[];
}
@ -14,7 +12,9 @@ const Preview: React.FC<PreviewProps> = ({ links }) => {
<div
className={`box-border bg-white rounded-preview border-preview border-black ${styles.parent}`}
>
<Links links={links} className={styles.child} />
<div className={styles.child}>
<Links links={links} />
</div>
</div>
</div>
);

View File

@ -1,3 +0,0 @@
{
"greeting": "Hello from JSON"
}

View File

@ -1,48 +0,0 @@
import React from "react";
import { GetStaticProps } from "next";
import GreetingJSON from "./hello-world.json";
import { fetchExample } from "utils/api";
interface Props {
greeting: string;
}
export const getStaticProps: GetStaticProps<Props> = async () => {
return {
props: { greeting: GreetingJSON.greeting }, // will be passed to the page component as props
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every second
revalidate: 1,
};
};
function HelloWorld({ greeting }: Props): JSX.Element {
const [greetings, setGreetings] = React.useState([greeting]);
const getMoreGreetings = async () => {
const greetingFromBackend = await fetchExample();
setGreetings([
...greetings,
`"${greetingFromBackend}" --- ${new Date().toISOString()}`,
]);
};
return (
<div style={{ padding: "50px" }}>
<button
style={{ border: "2px solid black", padding: "5px" }}
onClick={getMoreGreetings}
>
Get greeting from the server
</button>
<ol style={{ listStyleType: "decimal" }}>
{greetings.map((greeting) => (
<li key={greeting}>{greeting}</li>
))}
</ol>
</div>
);
}
export default HelloWorld;

View File

@ -17,7 +17,7 @@ interface Props {
}
const Home: React.FC<Props> = ({ links }) => {
return <Links links={links} />;
return <Links links={links} logClicks={true} />;
};
export default Home;

View File

@ -1,4 +0,0 @@
export async function fetchExample(): Promise<string> {
const response = await fetch("/api");
return await response.text();
}

View File

@ -1,4 +0,0 @@
export interface Link {
name: string;
url: string;
}