-
Notifications
You must be signed in to change notification settings - Fork 3
Editor mode #56
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
Editor mode #56
Changes from 49 commits
bee43e4
d066a4f
678c67c
774f106
b424d2f
deffb4c
1a17ac8
7b5f56f
7d3148c
9955712
20e3520
e29a1e1
6137239
ab448ba
18672bf
a19b21d
6475744
a5e63d1
08d4a62
b1a39f9
e72cf4c
2033da2
81cbccb
1618fca
5848e5e
b276f84
43ac166
2793040
e48bef9
628f9ba
cbc0c8d
331d260
0d00cee
d1566c7
f742ac1
76166c5
28615b0
19e98f8
5bb938f
2ee9b31
1b01b4e
f65560a
4649e63
fda802a
4580d44
55f2712
60ce23d
f0b10b5
e020a28
69fbaf9
b6f0958
122b503
4977a57
942726b
52b6637
1da996c
e370af1
3903690
732869a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { setAdmin } from "redux/slices/admin"; | ||
| import { useAppDispatch } from "redux/typesHooks"; | ||
|
|
||
| import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect"; | ||
|
|
||
| interface Props { | ||
| children: JSX.Element; | ||
| } | ||
|
|
||
| const getAdmin = (): boolean | undefined => { | ||
| return localStorage.admin === "true"; | ||
| }; | ||
|
|
||
| const getInitialAdmin = (): boolean => getAdmin() || false; | ||
|
|
||
| const AdminProvider = ({ children }: Props) => { | ||
| const dispatch = useAppDispatch(); | ||
|
|
||
| useIsomorphicLayoutEffect(() => { | ||
| const admin = getInitialAdmin(); | ||
|
|
||
| dispatch(setAdmin(admin)); | ||
| }, [dispatch]); | ||
|
|
||
| return children; | ||
| }; | ||
|
|
||
| export default AdminProvider; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,30 +1,84 @@ | ||||||
| import config from "config"; | ||||||
| import { useEffect, useState } from "react"; | ||||||
| import { useDispatch } from "react-redux"; | ||||||
| import { setAdmin } from "redux/slices/admin"; | ||||||
| import { useAppSelector } from "redux/typesHooks"; | ||||||
|
|
||||||
| const Intro = () => ( | ||||||
| <section className="intro-section"> | ||||||
| <div className="container"> | ||||||
| <div className="intro-content"> | ||||||
| <div className="intro-avatar"> | ||||||
| <div className="image"> | ||||||
| <img | ||||||
| src="/images/author-avatar.jpg" | ||||||
| alt="author-avatar" | ||||||
| width={90} | ||||||
| height={90} | ||||||
| /> | ||||||
| const Intro = () => { | ||||||
| const dispatch = useDispatch(); | ||||||
| const admin = useAppSelector((state) => state.admin); | ||||||
|
|
||||||
| const [isFirstRender, setIsFirstRender] = useState(true); | ||||||
|
|
||||||
| const handleClick = () => { | ||||||
| if (admin === true) { | ||||||
| dispatch(setAdmin(false)); | ||||||
| } else { | ||||||
| dispatch(setAdmin(true)); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| useEffect(() => { | ||||||
| const imageWrapper = document.querySelector("div.image-avatar"); | ||||||
| const editIcon = document.querySelector("img.editor-icon"); | ||||||
|
|
||||||
| if (admin) { | ||||||
| imageWrapper?.setAttribute("admin", ""); | ||||||
| editIcon?.setAttribute("admin", ""); | ||||||
| setIsFirstRender(false); | ||||||
| } | ||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a break line down below, for the consistency |
||||||
| if (!admin && isFirstRender === false) { | ||||||
|
||||||
| if (!admin && isFirstRender === false) { | |
| if (!admin && !isFirstRender) { |
Use the same syntax for both of them
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do MUI in here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#82 - refactor of MUI component. I think it will be easier for you to check this refactor if it will be like another PR.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,4 @@ | ||
| import { | ||
| isPostADraft, | ||
| isPostInTheFuture, | ||
| } from "helpers/checkOfDraftOrFuturePost"; | ||
| import isUpcomingPost from "helpers/isUpcomingPost"; | ||
| import { PostDocumentWithoutContent } from "interfaces"; | ||
| import Image from "next/image"; | ||
| import Link from "next/link"; | ||
|
|
@@ -28,11 +25,8 @@ const LatestPosts = ({ latestPosts }: Props) => { | |
| height="102" | ||
| sizes="100vw" | ||
| style={{ | ||
| filter: | ||
| isPostADraft(post) || isPostInTheFuture(post) | ||
| ? "grayscale(50%)" | ||
| : "none", | ||
|
|
||
| filter: isUpcomingPost(post) ? "grayscale(50%)" : "none", | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love this utility function |
||
|
|
||
| objectFit: "cover", | ||
| }} | ||
| /> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ import { | |
| isPostADraft, | ||
| isPostInTheFuture, | ||
| } from "helpers/checkOfDraftOrFuturePost"; | ||
| import isUpcomingPost from "helpers/isUpcomingPost"; | ||
| import { PostDocumentWithoutContent } from "interfaces"; | ||
| import Image from "next/image"; | ||
| import Link from "next/link"; | ||
|
|
@@ -57,9 +58,7 @@ const PostCard = ({ post }: Props) => { | |
|
|
||
| <div | ||
| className={`posts-list-block ${ | ||
| isPostADraft(post) || isPostInTheFuture(post) | ||
| ? "posts-list-block-draft-or-future" | ||
| : "" | ||
| isUpcomingPost(post) ? "upcoming-posts-list-block" : "" | ||
|
||
| }`} | ||
| > | ||
| <div className="content"> | ||
|
|
@@ -75,10 +74,7 @@ const PostCard = ({ post }: Props) => { | |
| height="378" | ||
| sizes="100vw" | ||
| style={{ | ||
| filter: | ||
| isPostADraft(post) || isPostInTheFuture(post) | ||
| ? "grayscale(50%)" | ||
| : "none", | ||
| filter: isUpcomingPost(post) ? "grayscale(50%)" : "none", | ||
|
|
||
| objectFit: "cover", | ||
| }} | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,10 +5,12 @@ import { useAppDispatch, useAppSelector } from "redux/typesHooks"; | |||||
|
|
||||||
| interface Props { | ||||||
| uniqueTags: string[]; | ||||||
| countOfPostsInTags: number[]; | ||||||
| } | ||||||
|
|
||||||
| const Tags = ({ uniqueTags }: Props) => { | ||||||
| const Tags = ({ uniqueTags, countOfPostsInTags }: Props) => { | ||||||
| const selectedTags = useAppSelector((state) => state.selectedTags); | ||||||
| const admin = useAppSelector((state) => state.admin); | ||||||
|
|
||||||
| const dispatch = useAppDispatch(); | ||||||
|
|
||||||
|
|
@@ -27,7 +29,7 @@ const Tags = ({ uniqueTags }: Props) => { | |||||
| > | ||||||
| ALL | ||||||
| </li> | ||||||
| {uniqueTags.map((uniqueTag) => ( | ||||||
| {uniqueTags.map((uniqueTag, index) => ( | ||||||
| <li | ||||||
| key={uniqueTag} | ||||||
| className={selectedTags.includes(uniqueTag) ? "active" : ""} | ||||||
|
|
@@ -44,6 +46,7 @@ const Tags = ({ uniqueTags }: Props) => { | |||||
| }} | ||||||
| > | ||||||
| {uniqueTag} | ||||||
| {admin && ` [${countOfPostsInTags[index]}]`} | ||||||
|
||||||
| {admin && ` [${countOfPostsInTags[index]}]`} | |
| {admin && `[${countOfPostsInTags[index]}]`} |
Extra space?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It look more readable with this space, removed this space
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,37 @@ | ||||||
| import { Box, Divider, Typography } from "@mui/material"; | ||||||
| import { PostDocumentWithoutContent } from "interfaces"; | ||||||
|
|
||||||
| import PostCard from "./PostCard"; | ||||||
|
|
||||||
| interface Props { | ||||||
| posts: PostDocumentWithoutContent[]; | ||||||
| } | ||||||
|
|
||||||
| const UpcomingPosts = ({ posts }: Props) => ( | ||||||
| <Box sx={{ mb: 17.5 }}> | ||||||
| <Box> | ||||||
| <Typography | ||||||
| sx={(theme) => ({ | ||||||
| color: theme.palette.mode === "light" ? "#3a3a3a" : "#fff", | ||||||
|
||||||
| color: theme.palette.mode === "light" ? "#3a3a3a" : "#fff", | |
| color: theme.palette.mode === "light" ? "#3a3a3a" : "white", |
white is easier to read, so even non programmers can understand your code
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { PostDocumentWithoutContent } from "interfaces"; | ||
|
|
||
| import { isPostADraft, isPostInTheFuture } from "./checkOfDraftOrFuturePost"; | ||
|
|
||
| export default function isUpcomingPost(post: PostDocumentWithoutContent) { | ||
| return isPostADraft(post) || isPostInTheFuture(post); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ import matter from "gray-matter"; | |
| import { PostDocument, PostDocumentWithoutContent } from "interfaces"; | ||
| import { join } from "path"; | ||
|
|
||
| import { isPostADraft, isPostInTheFuture } from "./checkOfDraftOrFuturePost"; | ||
| import isUpcomingPost from "./isUpcomingPost"; | ||
|
|
||
| const documentsDirectory = join(process.cwd(), "content/posts"); | ||
|
|
||
|
|
@@ -31,7 +31,7 @@ export function getAllPostDocuments(): PostDocumentWithoutContent[] { | |
| return true; | ||
| } | ||
|
|
||
| if (isPostADraft(post) || isPostInTheFuture(post)) { | ||
| if (isUpcomingPost(post)) { | ||
| return false; | ||
| } | ||
|
|
||
|
|
@@ -45,3 +45,17 @@ export function getAllPostDocuments(): PostDocumentWithoutContent[] { | |
|
|
||
| return JSONSerialize(docs); | ||
| } | ||
|
|
||
| export function getUpcomingPosts(): PostDocumentWithoutContent[] { | ||
| const slugs = fs.readdirSync(documentsDirectory); | ||
| const docs = slugs | ||
| .map((slug) => getPostDocumentBySlug(slug)) | ||
| .filter((post: PostDocument) => isUpcomingPost(post)) | ||
| .sort((post1, post2) => (post1.date > post2.date ? -1 : 1)) | ||
| .map((post) => { | ||
| const { content, ...postWithoutContent } = post; | ||
| return postWithoutContent; | ||
| }); | ||
|
|
||
| return JSONSerialize(docs); | ||
| } | ||
|
Comment on lines
+48
to
+61
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tina CMS is fetching posts somewhat differently, so it might cause some merge conflicts I might merge Tina first, and only then you're going to update this utility method |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { getUpcomingPosts } from "helpers/markdownDocumentsReader"; | ||
| import type { NextApiRequest, NextApiResponse } from "next"; | ||
|
|
||
| export default function handler(req: NextApiRequest, res: NextApiResponse) { | ||
| const posts = getUpcomingPosts(); | ||
|
|
||
| res.status(200).json(posts); | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tina GraphQL query might look a bit differently, so just heads up
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, waiting for merge of Tina and after will be fixing that |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a same thing