-
Notifications
You must be signed in to change notification settings - Fork 2
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
Feature - Resources admin dashboard #106
Open
tfredh
wants to merge
21
commits into
main
Choose a base branch
from
feature_resources-admin-dashboard
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
4511b00
misc
tfredh 3c207ef
n
tfredh 0b0bfa0
freeze immutable arr
tfredh 63c66e8
wwwwwwwwwwwwwwwwwwwwwwww
tfredh 7da2db9
give posts id for react child
tfredh 53754da
pr fixes and notes
tfredh ae8db27
pr fixes and notes
tfredh c51effa
initial frontend
tfredh 9678a37
initial frontend
tfredh 4b0fb96
fix prettier check
tfredh 9075658
add context for state & start main admin dashboard
tfredh 67e4418
add context for state & start main admin dashboard
tfredh 2d9b804
add time framework
tfredh 06f62e2
deliver metadata on log in
tfredh f95db61
ui additions
tfredh 1c21e6e
misc & publish blog to repo api endpoint
tfredh 2c9fc08
autosave projects
tfredh 4b9e214
remove useless dev. html
tfredh 429b6fa
corner cases & templating for future features
tfredh ff29514
initial setup for Admin Dashboard to create new opportunities like blogs
tfredh 0671066
update markdown editor placeholder
tfredh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{ | ||
"presets": ["next/babel"], | ||
"plugins": [["styled-components", { "ssr": true }]] | ||
"presets": ["next/babel"], | ||
"plugins": [["styled-components", { "ssr": true }]] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"printWidth": 85, | ||
"semi": true, | ||
"tabWidth": 2 | ||
"tabWidth": 2, | ||
"singleQuote": false | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import styled from "styled-components"; | ||
|
||
export default styled.hr` | ||
display: block; | ||
height: 1px; | ||
border: 0; | ||
border-top: 1px solid black; | ||
margin: 1em 0; | ||
padding: 0; | ||
margin: 3rem 0; | ||
width: 100%; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { useCallback, useState } from "react"; | ||
import "easymde/dist/easymde.min.css"; | ||
|
||
export default function MDEditor({ initialValue, mdeRecordSetter }) { | ||
const [mde, setMde] = useState(null); | ||
|
||
const injectEditor = useCallback( | ||
async (element) => { | ||
if (element == null) return; | ||
|
||
// create and add editor | ||
element.innerHTML = ""; | ||
const editor = document.createElement("textarea"); | ||
element.append(editor); | ||
|
||
// dynamic import to to support SSR | ||
const EasyMDE = (await import("easymde")).default; | ||
const easyMDE = new EasyMDE({ | ||
element: editor, | ||
showIcons: [ | ||
"strikethrough", | ||
"code", | ||
"table", | ||
"horizontal-rule", | ||
"undo", | ||
"redo", | ||
], | ||
initialValue, | ||
placeholder: "Start typing...", | ||
}); | ||
|
||
setMde(easyMDE); | ||
mdeRecordSetter(easyMDE); | ||
}, | ||
[initialValue, mdeRecordSetter] | ||
); | ||
|
||
return ( | ||
<div> | ||
<p>Remember you can preview with the toolbar fourth column</p> | ||
<div ref={injectEditor} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import styled from "styled-components"; | ||
import { Button } from "../Button"; | ||
import { Input } from "../Input"; | ||
import { latestTimeAgo } from "../../utils/methods/time"; | ||
|
||
export default function BlogTemplateRow({ blog }) { | ||
return ( | ||
<BlogTemplateRowWrapper> | ||
<BlogInformationContainer> | ||
<Input disabled type="checkbox" /> | ||
|
||
<ResourceProjectTitle href={`/resources/admin/project/blog/${blog.id}`}> | ||
{blog.name} | ||
</ResourceProjectTitle> | ||
<ModifiedTimeStamp> | ||
Last opened {latestTimeAgo(blog.lastSaved)} ago | ||
</ModifiedTimeStamp> | ||
</BlogInformationContainer> | ||
|
||
<BlogControlContainer> | ||
<Button onClick={() => alert("Coming soon")}>Copy</Button> | ||
<Button onClick={() => alert("Coming soon")}>Archive</Button> | ||
<Button onClick={() => alert("Coming soon")}>Trash</Button> | ||
</BlogControlContainer> | ||
</BlogTemplateRowWrapper> | ||
); | ||
} | ||
|
||
const BlogTemplateRowWrapper = styled.section` | ||
display: flex; | ||
justify-content: space-between; | ||
|
||
min-height: 2vh; | ||
background-color: whitesmoke; | ||
margin-bottom: 0.1rem; | ||
padding: 0.3rem; | ||
color: black; | ||
border-left: 1px solid white; | ||
border-right: 1px solid white; | ||
overflow-x: auto; | ||
|
||
&:last-child { | ||
margin-bottom: 0; | ||
} | ||
`; | ||
|
||
const BlogInformationContainer = styled.section` | ||
display: flex; | ||
align-items: center; | ||
|
||
* { | ||
margin-right: 1.2rem; | ||
|
||
&:last-child { | ||
margin-right: 0; | ||
} | ||
} | ||
`; | ||
|
||
export const ModifiedTimeStamp = styled.div` | ||
font-size: 1.1rem; | ||
`; | ||
|
||
const BlogControlContainer = styled.section` | ||
display: flex; | ||
align-items: center; | ||
|
||
* { | ||
margin-right: 0.2rem; | ||
|
||
&:last-child { | ||
margin-right: 0; | ||
} | ||
} | ||
`; | ||
|
||
const ResourceProjectTitle = styled.a` | ||
font-size: 1.2rem; | ||
margin-right: 4rem; | ||
font-weight: bold; | ||
color: #3e70bb; | ||
|
||
&:hover { | ||
cursor: pointer; | ||
text-decoration: underline; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export default function JobOpportunityRow() { | ||
return ( | ||
<div> | ||
<div>JobOpportunityRow</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import axios from "axios"; | ||
import { createContext, useContext, useEffect, useState } from "react"; | ||
|
||
const Context = createContext(); | ||
|
||
export function AdminProvider({ children }) { | ||
const [adminUser, setAdminUser] = useState(null); | ||
|
||
// attempt to log user in right after page load | ||
useEffect(() => { | ||
async function f() { | ||
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. a little weird naming? if this is temporary probably fine |
||
const res = await axios.get("/api/admin/instant-log-in"); | ||
// eslint-disable-next-line no-console | ||
console.log(res.data); | ||
|
||
if (res.data.loggedIn) { | ||
const { user } = res.data; | ||
|
||
setAdminUser(user); | ||
} | ||
} | ||
f(); | ||
}, []); | ||
|
||
return ( | ||
<Context.Provider value={{ adminUser, setAdminUser }}> | ||
{children} | ||
</Context.Provider> | ||
); | ||
} | ||
|
||
export function useAdmin() { | ||
return useContext(Context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { createContext, useContext, useEffect } from "react"; | ||
import { LOCAL_STORAGE_KEYS } from "../utils/constants"; | ||
import { simpleUUID } from "../utils/methods/general"; | ||
import useLocalStorage from "../utils/hooks/useLocalStorage"; | ||
|
||
const Context = createContext(); | ||
|
||
const defaultBlogProjects = Array.from({ length: 6 }, (_v, i) => { | ||
return { | ||
id: simpleUUID(7), | ||
name: `blog-project-${i + 1}`, | ||
lastSaved: Date.now(), | ||
|
||
// blog contents | ||
title: "", | ||
date: "", | ||
releaseBatch: "", | ||
authors: [], | ||
tags: [], | ||
body: "", | ||
}; | ||
}); | ||
const defaultJobProjects = Array.from({ length: 3 }, (v, i) => { | ||
return { | ||
id: simpleUUID(7), | ||
name: `job-opportunity-project-${i + 1}`, | ||
lastSaved: Date.now(), | ||
}; | ||
}); | ||
|
||
export function ResourcesAdminProvider({ children }) { | ||
/** | ||
* @TODO : remove entirely, only store important project info | ||
* (title, last modified) here. | ||
* then on each route, store each blog/resource independently | ||
* in LS | ||
* This so there isnt 1 huge LS value | ||
*/ | ||
const [blogTemplates, setBlogTemplates] = useLocalStorage( | ||
LOCAL_STORAGE_KEYS.AdminBlogProjects, | ||
defaultBlogProjects | ||
); | ||
const [jobOpportunityTemplates, setJobOpportunityTemplates] = useLocalStorage( | ||
LOCAL_STORAGE_KEYS.AdminJobOppProject, | ||
defaultJobProjects | ||
); | ||
|
||
return ( | ||
<Context.Provider | ||
value={{ | ||
blogTemplates, | ||
setBlogTemplates, | ||
jobOpportunityTemplates, | ||
setJobOpportunityTemplates, | ||
}} | ||
> | ||
{children} | ||
</Context.Provider> | ||
); | ||
} | ||
|
||
export function useResourcesAdmin() { | ||
return useContext(Context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// eslint-disable-next-line no-undef | ||
require("dotenv").config(); | ||
|
||
// eslint-disable-next-line no-undef | ||
const { JWT_SECRET_KEY, GITHUB_KEY, REPO_OWNER, MAIN_REPO } = process.env; | ||
|
||
const ENVS = { | ||
JWT_SECRET_KEY, | ||
GITHUB_KEY, | ||
}; | ||
// console.log(ENVS); | ||
|
||
for (const [k, val] of Object.entries(ENVS)) { | ||
if (val == null) throw new Error(`undef. env var: ${k}, val: ${val}`); | ||
} | ||
|
||
ENVS["REPO_OWNER"] = REPO_OWNER; | ||
ENVS["MAIN_REPO"] = MAIN_REPO; | ||
|
||
for (const [k, val] of Object.entries(ENVS)) { | ||
// eslint-disable-next-line no-console | ||
if (val == null) console.warn(`undef. env var: ${k}, val: ${val}`); | ||
} | ||
|
||
export { ENVS }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Octokit } from "octokit"; | ||
import { ENVS } from "./envs"; | ||
|
||
// console.log(ENVS.GITHUB_FGPAT); | ||
export default new Octokit({ | ||
auth: ENVS.GITHUB_KEY, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { verify } from "jsonwebtoken"; | ||
import { ENVS } from "../lib/envs"; | ||
import { COOKIE_KEYS } from "../utils/constants"; | ||
|
||
export function validateToken(req, res) { | ||
const { [COOKIE_KEYS.AccessToken]: accessToken } = req.cookies; | ||
|
||
if (accessToken != null) { | ||
try { | ||
// eslint-disable-next-line no-undef | ||
const decodedToken = verify(accessToken, ENVS.JWT_SECRET_KEY); | ||
|
||
req.user = decodedToken.user; | ||
} catch (err) { | ||
// console.log("thee", err); | ||
// console.log("err done"); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I'm guessing this doesn't work with just the
Input
? I think if you want aref
as a prop you can make it on the original element and pass it as optional?