tie it all together
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
import { useAuth } from "../providers/AuthProvider";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function Header() {
|
||||
const auth = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-1 py-4">
|
||||
<h1 className="font-bold">
|
||||
Alex <span className="font-normal text-blue-500">/</span> dev + QA
|
||||
</h1>
|
||||
<a href="#" onClick={() => navigate("/")}>
|
||||
<h1 className="font-bold">
|
||||
Alex <span className="font-normal text-blue-500">/</span> dev + QA
|
||||
</h1>
|
||||
</a>
|
||||
<div className="flex gap-3 text-sm sm:text-base">
|
||||
{auth.user !== null ? (
|
||||
<a href="#" onClick={() => auth.logout()}>
|
||||
|
||||
@@ -3,6 +3,7 @@ type InputType = {
|
||||
forLabel: string;
|
||||
type: "password" | "email" | "text";
|
||||
dark?: boolean;
|
||||
defaultValue?: string;
|
||||
onChange?: (v: string) => void;
|
||||
};
|
||||
|
||||
@@ -10,6 +11,7 @@ export default function Input({
|
||||
label,
|
||||
forLabel,
|
||||
type,
|
||||
defaultValue,
|
||||
dark = true,
|
||||
onChange,
|
||||
}: InputType) {
|
||||
@@ -23,6 +25,7 @@ export default function Input({
|
||||
onChange={onChange ? (e) => onChange(e.target.value) : undefined}
|
||||
type={type}
|
||||
required
|
||||
defaultValue={defaultValue}
|
||||
name={forLabel}
|
||||
className={`${dark ? "bg-black text-white" : "bg-white text-black"} rounded-lg border-white block`}
|
||||
/>
|
||||
|
||||
@@ -30,8 +30,6 @@ export default function Editor() {
|
||||
}, []);
|
||||
|
||||
async function createPost() {
|
||||
console.log(values);
|
||||
|
||||
if (!values?.title || !values.content || !values.description) {
|
||||
setError("Missing required value");
|
||||
return;
|
||||
@@ -66,7 +64,13 @@ export default function Editor() {
|
||||
|
||||
return (
|
||||
<Layout isProtected={true}>
|
||||
<h1 className="text-2xl font-bold">
|
||||
<p
|
||||
className="text-sm opacity-50 hover:underline hover:cursor-pointer"
|
||||
onClick={() => history.back()}
|
||||
>
|
||||
<- Back
|
||||
</p>
|
||||
<h1 className="text-2xl font-bold mb-4">
|
||||
{editingPost ? "Edit" : "Create"} Post
|
||||
</h1>
|
||||
|
||||
@@ -76,6 +80,7 @@ export default function Editor() {
|
||||
label="Title"
|
||||
type="text"
|
||||
dark={false}
|
||||
defaultValue={editingPost?.title}
|
||||
onChange={(v) =>
|
||||
setValues((prevState) => {
|
||||
return {
|
||||
@@ -88,6 +93,7 @@ export default function Editor() {
|
||||
<Input
|
||||
forLabel="description"
|
||||
label="Description"
|
||||
defaultValue={editingPost?.description}
|
||||
type="text"
|
||||
dark={false}
|
||||
onChange={(v) =>
|
||||
@@ -131,7 +137,7 @@ export default function Editor() {
|
||||
/>
|
||||
) : (
|
||||
<div className="prose prose-invert">
|
||||
<Markdown>{values.content}</Markdown>
|
||||
<Markdown>{values.content || editingPost?.content}</Markdown>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -142,6 +148,7 @@ export default function Editor() {
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
<p className="text-red-300 font-semibold">{error}</p>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import Layout from "../components/layout";
|
||||
import PostRow from "../components/postRow";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../providers/AuthProvider";
|
||||
import type { Post } from "../utils/types";
|
||||
|
||||
export default function Home() {
|
||||
const [posts, setPosts] = useState<Post[] | null>(null);
|
||||
const [loaded, setLoaded] = useState<boolean>(false);
|
||||
const auth = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/posts", {
|
||||
@@ -51,7 +55,17 @@ export default function Home() {
|
||||
</div>
|
||||
<hr />
|
||||
<div className="mt-2">
|
||||
<h1 className="font-semibold">Posts</h1>
|
||||
<div className="flex justify-between">
|
||||
<h1 className="font-semibold">Posts</h1>
|
||||
{auth.user && (
|
||||
<p
|
||||
className="text-sm opacity-50 hover:cursor-pointer hover:underline"
|
||||
onClick={() => navigate("/editor")}
|
||||
>
|
||||
Create
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<PostList />
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import Layout from "../components/layout";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useParams, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../providers/AuthProvider";
|
||||
import type { Post } from "../utils/types";
|
||||
import Markdown from "react-markdown";
|
||||
|
||||
export default function Post() {
|
||||
const [post, setPost] = useState<Post | null>(null);
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
const auth = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
if (params.slug) {
|
||||
@@ -32,6 +35,13 @@ export default function Post() {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="my-2">
|
||||
<a
|
||||
href="#"
|
||||
onClick={() => navigate("/")}
|
||||
className="text-sm opacity-50 hover:underline"
|
||||
>
|
||||
<- Home
|
||||
</a>
|
||||
<h1 className="text-2xl font-bold">{post.title}</h1>
|
||||
<p className="text-sm opacity-50">{post.description}</p>
|
||||
|
||||
@@ -46,6 +56,14 @@ export default function Post() {
|
||||
{post.updatedAt !== post.createdAt &&
|
||||
"- updated on " + new Date(post.updatedAt).toLocaleString()}
|
||||
</p>
|
||||
{auth.user && (
|
||||
<p
|
||||
className="text-sm opacity-50 underline hover:cursor-pointer"
|
||||
onClick={() => navigate(`/editor/${post.slug}`)}
|
||||
>
|
||||
Edit
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user