Skip to content

Commit

Permalink
add auth and dashboard space
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-parag committed Dec 9, 2020
1 parent d2f3260 commit 4e28ca2
Show file tree
Hide file tree
Showing 18 changed files with 902 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
config.js
.env
.env.local
secrets.json

# Logs
logs
Expand Down
12 changes: 11 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ module.exports = {
STORAGE_BUCKET: process.env.STORAGE_BUCKET,
MESSAGING_SENDER_ID: process.env.MESSAGING_SENDER_ID,
APP_ID: process.env.APP_ID,
TEST_VAR: process.env.TEST_VAR
TEST_VAR: process.env.TEST_VAR,
SERVICE_TYPE: process.env.SERVICE_TYPE,
SERVICE_PROJECT_ID: process.env.SERVICE_PROJECT_ID,
SERVICE_PRIVATE_KEY_ID: process.env.SERVICE_PRIVATE_KEY_ID,
SERVICE_PRIVATE_KEY: process.env.SERVICE_PRIVATE_KEY,
SERVICE_CLIENT_EMAIL: process.env.SERVICE_CLIENT_EMAIL,
SERVICE_CLIENT_ID: process.env.SERVICE_CLIENT_ID,
SERVICE_AUTH_URI: process.env.SERVICE_AUTH_URI,
SERVICE_TOKEN_URI: process.env.SERVICE_TOKEN_URI,
SERVICE_AUTH_PROVIDER_X509_CERT_URL: process.env.SERVICE_AUTH_PROVIDER_X509_CERT_URL,
SERVICE_CLIENT_X509_CERT_URL: process.env.SERVICE_CLIENT_X509_CERT_URL
},
};
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"eslint-plugin-react-hooks": "^2.2.0",
"extract-css-chunks-webpack-plugin": "^4.6.0",
"file-loader": "^4.2.0",
"firebase": "^8.1.1",
"firebase": "^8.1.2",
"friendly-errors-webpack-plugin": "^1.7.0",
"hard-source-webpack-plugin": "^0.13.1",
"html-webpack-plugin": "^3.2.0",
Expand Down Expand Up @@ -58,9 +58,12 @@
"@hot-loader/react-dom": "^16.10.2",
"autoprefixer": "^10.0.2",
"core-js": "^3.3.4",
"dotenv": "^8.2.0",
"firebase-admin": "^9.4.1",
"framer-motion": "^2.9.4",
"modern-normalize": "^0.5.0",
"next": "^10.0.3",
"nookies": "^2.5.0",
"postcss": "^8.1.10",
"react": "^16.11.0",
"react-color": "^2.19.3",
Expand Down
29 changes: 29 additions & 0 deletions src/components/Auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useEffect, useState, useContext, createContext } from 'react'
import nookies from "nookies"
import {firebaseClient} from '../../data/firebase'
import firebase from "firebase/app"
import "firebase/auth"

const AuthContext = createContext({})

export const AuthProvider = ({children}) => {
firebaseClient()
const [user, setUser] = useState(null)

useEffect(() => {
return firebase.auth().onIdTokenChanged(async (user) => {
if(!user) {
setUser(null)
nookies.set(undefined, "token", '', {})
return
}
const token = await user.getIdToken()
setUser(user)
nookies.set(undefined, "token", token, {})
})
}, [])

return (<AuthContext.Provider value={{user}}>{children}</AuthContext.Provider>)
}

export const useAuth = () => useContext(AuthContext)
4 changes: 2 additions & 2 deletions src/components/Intro/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import Navigation from '../Navigation'
const Intro = () => {
return (
<>
<div className="flex justify-between items-center">
<div className="flex justify-between items-center mb-8">
<Link href="/">
<a><Logo/></a>
</Link>
</div>
<Navigation active={'Themes'}/>
<Navigation active={'Explore'}/>
<h1 className="mt-8">Pick a theme for Slack</h1>
<p className="font-bold mt-4">Having trouble keeping track of all of your Slack workspaces?</p>
<p className="mt-4">Choose and copy one of the themes in the list to personalize a Slack workspace.</p>
Expand Down
18 changes: 15 additions & 3 deletions src/components/Navigation/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react'
import Link from 'next/link'

const Navigation = ({active}) => {
const Navigation = ({active, signOut}) => {

const navItems = [
{ name: 'Themes', href: '/'},
{ name: 'Explore', href: '/'},
{ name: 'About', href: '/about'},
{ name: 'Submit a Theme', href: '/submit-theme'},
]

return(
<div className="flex mt-8">
<div className="flex items-center">
{
navItems.map((item, i) => (
<Link
Expand All @@ -25,6 +25,18 @@ const Navigation = ({active}) => {
</Link>
))
}
{
signOut ? (
<button
className="transition pb-0.5 ml-4 border-b-2 border-transparent focus:outline-none text-red-500 hover:text-red-700"
onClick={() => signOut()}
>
Sign Out
</button>
)
:
null
}
</div>
)
}
Expand Down
28 changes: 28 additions & 0 deletions src/components/ThemeAdmin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@ import React, { useState, useEffect } from 'react'
import { Search } from 'react-feather';
import Modal from '../Modal'
import ThemeUpdateItem from '../ThemeUpdateItem'
import Link from 'next/link'
import Logo from '../Logo'
import Navigation from '../Navigation'

export const ThemeHeader = ({loggedIn}) => {
return (
<div className="flex flex-wrap md:flex-row flex-col mx-4 md:mx-auto lg:mx-auto xl:mx-auto 2xl:mx-auto py-8 md:py-9 items-center justify-between">
<div className="inline-block mb-4 md:mb-0">
<Logo admin/>
</div>
{
loggedIn ? (
<Navigation signOut={loggedIn}/>
)
:
(
<div className="inline-flex">
<Link href="/">
<a className="button mx-2">
&larr; Back
</a>
</Link>
</div>
)
}
</div>
)
}

const ThemeAdmin = ({data}) => {

Expand Down
18 changes: 18 additions & 0 deletions src/data/admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const admin = require("firebase-admin")
const serviceAccount = require("../data/service")

export const verifyIdToken = (token) => {
if(!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(JSON.parse(JSON.stringify(serviceAccount))),
databaseURL: process.env.DATABASE_URL,
})
}

return admin
.auth()
.verifyIdToken(token)
.catch((error) => {
throw error
})
}
7 changes: 7 additions & 0 deletions src/data/firebase.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import firebase from "firebase";
import "firebase/auth"

const firebaseConfig = {
apiKey: process.env.API_KEY,
Expand All @@ -10,4 +11,10 @@ const firebaseConfig = {
appId: process.env.APP_ID
};

export function firebaseClient() {
if(!firebase.apps.length) {
firebase.initializeApp(firebaseConfig)
}
}

export default !firebase.apps.length ? firebase.initializeApp(firebaseConfig) : firebase.app();
12 changes: 12 additions & 0 deletions src/data/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
type: process.env.SERVICE_TYPE,
project_id: process.env.SERVICE_PROJECT_ID,
private_key_id: process.env.SERVICE_PRIVATE_KEY_ID,
private_key: process.env.SERVICE_PRIVATE_KEY,
client_email: process.env.SERVICE_CLIENT_EMAIL,
client_id: process.env.SERVICE_CLIENT_ID,
auth_uri: process.env.SERVICE_AUTH_URI,
token_uri: process.env.SERVICE_TOKEN_URI,
auth_provider_x509_cert_url: process.env.SERVICE_AUTH_PROVIDER_X509_CERT_URL,
client_x509_cert_url: process.env.SERVICE_CLIENT_X509_CERT_URL
}
7 changes: 6 additions & 1 deletion src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import '../styles/tailwind.css';
import '../styles/tailwind.css'
import '../styles/index.css'
import '../styles/tailwind-utils.css'
import {AuthProvider} from '../components/Auth'

export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
return (
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
);
}
12 changes: 7 additions & 5 deletions src/pages/about.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ export default function About() {
<Layout>
<div className="flex flex-col lg:flex-row mx-4 md:mx-auto lg:mx-auto xl:mx-auto 2xl:mx-auto py-8 md:py-9">
<div className="w-full md:w-2/3 xl:w-1/2 mx-auto lg:px-8">
<Link href="/">
<a>
<Logo/>
</a>
</Link>
<div className="flex justify-between items-center mb-8">
<Link href="/">
<a>
<Logo/>
</a>
</Link>
</div>
<Navigation active={'About'}/>
<h1 className="mb-4 mt-8">About</h1>
<p>
Expand Down
97 changes: 97 additions & 0 deletions src/pages/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { useState } from "react"
import nookies from "nookies"
import {verifyIdToken} from "../data/admin"
import {firebaseClient} from "../data/firebase"
import firebase from "firebase/app"
import Layout from '../components/Layout'
import { ThemeHeader } from '../components/ThemeAdmin'
import { motion } from 'framer-motion'
import { Loader } from 'react-feather'

function Dashboard({session}) {
firebaseClient()
const [activeTab, setActiveTab] = useState('themes')

const signOut = async () => {
await firebase.auth().signOut()
window.location.href = '/login'
}

if(session) {
return (
<Layout>
<ThemeHeader loggedIn={signOut} />
<div className="border-b border-gray-300 flex w-full justify-center">
<div className="w-full md:w-1/2 mx-auto text-center">
<h1>Themes</h1>
<p className="text-xl mt-4">Edit/Add themes in the database</p>
<div className="flex border-b mt-8">
<button
className={`transition w-full focus:outline-none text-center hover:bg-gray-100 p-3 ${activeTab === 'themes' ? 'font-bold border-b-2 border-current' : 'border-b border-transparent text-gray-600 hover:border-current'}`}
onClick={() => setActiveTab('themes')}
>
Themes
</button>
<button
className={`transition w-full focus:outline-none text-center hover:bg-gray-100 p-3 ${activeTab === 'submitted' ? 'font-bold border-b-2 border-current' : 'border-b border-transparent text-gray-600 hover:border-current focus:border-current'}`}
onClick={() => setActiveTab('submitted')}
>
Submitted
</button>
</div>
</div>
</div>
<div className="py-8 px-4 md:px-0">
{
activeTab === 'themes' ? (
<div className="bg-pink-100 text-pink-900 p-8 rounded-md block text-center w-full">
THEMES TODO
</div>
)
:
null
}
{
activeTab === 'submitted' ? (
<div className="bg-yellow-100 text-yellow-900 p-8 rounded-md block text-center w-full">
SUBMITTED TODO
</div>
)
:
null
}
</div>
</Layout>
)
} else {
return (
<div className="rounded-md text-center bg-gray-100 p-8 mt-4">
<motion.div
animate={{ rotate: 360 }}
transition={{ ease: "linear", duration: 1, loop: Infinity }}
className="inline-block p-3 mb-4 bg-gray-200 text-gray-800 rounded-full"
>
<Loader/>
</motion.div>
<h4>Loading...</h4>
</div>
)
}
}

export async function getServerSideProps(context) {
try {
const cookies = nookies.get(context)
const token = await verifyIdToken(cookies.token)
const {uid, email} = token
return {
props: { session: `Your email is ${email} and your UID is ${uid}`}
}
} catch (err) {
context.res.writeHead(302, {location: "/login"})
context.res.end()
return {props: []}
}
}

export default Dashboard
1 change: 0 additions & 1 deletion src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export default function Home() {
const updateQuery = (string) => {
setQuery(string)
setQueryAmount(27)
console.log(process.env.TEST_VAR)
}

const updateQueryAmount = () => {
Expand Down
Loading

0 comments on commit 4e28ca2

Please sign in to comment.