Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make news list layout #23

Merged
merged 5 commits into from Jul 29, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .babelrc
@@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
4 changes: 2 additions & 2 deletions .eslintrc
@@ -1,3 +1,3 @@
{
"extends": "next"
}
"extends": "next"
}
5 changes: 1 addition & 4 deletions components/Footer.tsx
Expand Up @@ -5,10 +5,7 @@ import Link from "next/link";
export default function Footer() {
return (
<Container>
<Link
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
passHref={true}
>
<Link href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app">
<StyledLink>
React
<Image
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -13,7 +13,7 @@
"next": "^11.0.1",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-hook-form": "^7.11.0",
"react-hook-form": "^7.12.0",
"styled-components": "^5.3.0"
},
"devDependencies": {
Expand Down
30 changes: 30 additions & 0 deletions pages/_document.js
@@ -0,0 +1,30 @@
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;

try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});

const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
121 changes: 121 additions & 0 deletions pages/admin/news/form.tsx
@@ -0,0 +1,121 @@
import React from "react";
import Head from "next/head";
import styled from "styled-components";
import Footer from "../../../components/Footer";
import "firebase/auth";
import { useForm, SubmitHandler } from "react-hook-form";

type FormValues = {

Choose a reason for hiding this comment

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

@duoctvd
Trong phần code tham khảo của react-hook-form có chọn ngôn ngữ JS và TS, em chọn vào TS (typescript) để xem và làm theo nha.
image

Copy link
Owner Author

@duoctvd duoctvd Jul 28, 2021

Choose a reason for hiding this comment

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

@bit-thuynt ah dạ! hôm nay em refer theo source đính kèm dưới video này https://gyazo.com/c4801108834acc463cc6f0bbfe955135 https://codesandbox.io/s/pensive-jepsen-lqyk7 , nên có 1 số chỗ nó chưa thật sự đúng TS
mai em sẽ compare lại và fix

Copy link
Owner Author

Choose a reason for hiding this comment

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

@duoctvd
Trong phần code tham khảo của react-hook-form có chọn ngôn ngữ JS và TS, em chọn vào TS (typescript) để xem và làm theo nha.
image

@bit-thuynt : DONE

title: string;
description: string;
photo: string;
};

export default function Form() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValues>();
const onSubmit: SubmitHandler<FormValues> = data => console.log(data);

return (
<>
<Head>
<Title>News Form</Title>
</Head>
<Heading>News Form</Heading>

<Container>
<FormGroup onSubmit={handleSubmit(onSubmit)}>
<Label htmlFor="title">Title</Label>
<Input
{...register("title", {
required: { value: true, message: "Title is required" },
})}
id="title"
placeholder="please input title"
/>
{errors.title && <PValidation>{errors.title.message}</PValidation>}

<Label htmlFor="description">Description</Label>
<Textarea
{...register("description", {
required: { value: true, message: "Desciption is required" },
})}
id="description"
/>
{errors.description && <PValidation>{errors.description.message}</PValidation>}

<Label htmlFor="photo">Photo</Label>
<Input
{...register("photo", {
required: { value: true, message: "Photo is required" },
})}
id="photo"
type="file"
/>
{errors.photo && <PValidation>{errors.photo.message}</PValidation>}

<Input type="submit" />
</FormGroup>
</Container>
<Footer />
</>
);
}

const Heading = styled.h1`
font-size: 2em;
text-align: center;
color: palevioletred;
`;

const Title = styled.title``;

const Container = styled.div`
text-align: center;
padding: 0 0.5rem;
align-items: center;
`;

const FormGroup = styled.form`
`;

const Input = styled.input`
display: block;
box-sizing: border-box;
width: 100%;
border-radius: 4px;
border: 1px solid black;
padding: 10px 15px;
margin-bottom: 10px;
font-size: 14px;
`;

const Label = styled.label`
line-height: 2;
text-align: left;
display: block;
margin-bottom: 13px;
margin-top: 20px;
color: black;
font-size: 20px;
font-weight: 200;
`;
const Textarea = styled.textarea`
display: block;
box-sizing: border-box;
width: 100%;
height: 100px;
border-radius: 4px;
border: 1px solid black;
padding: 10px 15px;
margin-bottom: 10px;
font-size: 14px;
`;

const PValidation = styled.p`
color: red;
text-align: left;
`;
161 changes: 161 additions & 0 deletions pages/admin/news/list.tsx
@@ -0,0 +1,161 @@
import React from "react";
import Head from "next/head";
import styled from "styled-components";
import Footer from "../../../components/Footer";
import "firebase/auth";
import Image from "next/image";

export default function List() {
return (
<>
<Head>
<Title>News List</Title>
</Head>
<Heading>News List</Heading>

<Container>
<TotalCount>
<B>Total: 20 news</B>
</TotalCount>
<StyledTable>
<THead>
<TR>
<TH>Photo</TH>
<TH>Title</TH>
<TH>Descrption</TH>
<TH>Edit</TH>
<TH>Delete</TH>
</TR>
</THead>
<TBody>
<TR>
<TD>
<Image
src="/images/photo1.jpg"
alt="Picture of the product"
width={80}
height={80}
/>
</TD>
<TD>News 1</TD>
<TD>News 1 description</TD>
<TD>
{" "}
<Button>Edit</Button>
</TD>
<TD>
{" "}
<Button>Delete</Button>
</TD>
</TR>

<TR>
<TD>
<Image
src="/images/photo1.jpg"
alt="Picture of the product"
width={80}
height={80}
/>
</TD>
<TD>News 2</TD>
<TD>News 2 description</TD>
<TD>
{" "}
<Button>Edit</Button>
</TD>
<TD>
{" "}
<Button>Delete</Button>
</TD>
</TR>
</TBody>
</StyledTable>
<Pagination>
<PaginationStep>&laquo;</PaginationStep>
<PaginationStep>1</PaginationStep>
<PaginationStep>2</PaginationStep>
<PaginationStep>3</PaginationStep>
<PaginationStep>4</PaginationStep>
<PaginationStep>&raquo;</PaginationStep>
</Pagination>
</Container>
<Footer />
</>
);
}

const Heading = styled.h1`
font-size: 2em;
text-align: center;
color: palevioletred;
`;

const Title = styled.title``;

const Container = styled.div`
text-align: center;
padding: 0 0.5rem;
align-items: center;
`;

const TotalCount = styled.p`
text-align: left;
color: red;
`;
const StyledTable = styled.table`
// custom css goes here
width: 100%;
border: 1px solid black;
border-collapse: collapse;
`;

const THead = styled.thead`
// custom css goes here
`;

const TFoot = styled.tfoot`
// custom css goes here
`;

const TBody = styled.tbody`
// custom css goes here
`;

const TR = styled.tr`
// custom css goes here
`;

const TH = styled.th`
// custom css goes here
border: 1px solid black;
border-collapse: collapse;
`;

export const TD = styled.td`
// custom css goes here
border: 1px solid black;
border-collapse: collapse;
`;

const Pagination = styled.div`
display: inline-block;
`;

const PaginationStep = styled.a`
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
`;

const Button = styled.button`
background: white;
color: palevioletred;
font-size: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;

const B = styled.b``;
17 changes: 6 additions & 11 deletions pages/admin/top.tsx
Expand Up @@ -6,7 +6,7 @@ import { firebase } from "../../firebase";
import "firebase/auth";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect } from 'react';
import { useEffect } from "react";
import Image from "next/image";

export default function Top() {
Expand All @@ -23,19 +23,16 @@ export default function Top() {
console.log("User is signed in");
user_name = user.displayName;
photo = user.photoURL;
}
}
useEffect(() => {
// If auth is null and we are no longer loading
if(user == null)
{
router.push('/');
if (user == null) {
router.push("/");
}

}, [user, router]);

if(user == null)
{
return <p>Redirecting to top...</p>
if (user == null) {
return <p>Redirecting to top...</p>;
}

// [END auth_current_user]
Expand All @@ -52,11 +49,9 @@ export default function Top() {
<br />
<Image src={`${photo}`} alt={`${user_name}`} width={200} height={200} />
<br />

<Link href={`/`} passHref>
<Button>Home</Button>
</Link>

<br />
<Link href={`/logout`} passHref>
<Button>Log out!</Button>
Expand Down