Skip to content

Commit

Permalink
Merge pull request #1 from giselle2323/FUEL-002
Browse files Browse the repository at this point in the history
Suggest Resource Feature
  • Loading branch information
jhumeey committed Oct 28, 2021
2 parents 77e6ea5 + f5f131b commit 5331bda
Show file tree
Hide file tree
Showing 16 changed files with 382 additions and 26 deletions.
14 changes: 5 additions & 9 deletions components/cards/ResourceCard.tsx
@@ -1,10 +1,8 @@
import { GetStaticProps } from "next";
import Link from "next/link";
import { ItemProps } from "./types";

const ResourceCard = ({ item }: ItemProps) => {
return (
<li className="card m-2 cursor-pointer text-white flex flex-col border border-black-brand-02 bg-opacity-15 rounded-lg transform hover:-translate-y-1 transition-all duration-200">
<li className="font-mono card cursor-pointer text-gray-brand-02 flex flex-col border border-black-brand-06 bg-black-brand-08 rounded-lg transform hover:-translate-y-1 transition-all duration-200">
<div className="p-3 flex flex-col flex-1">
<div className="flex flex-wrap justify-between">
<div className="w-full flex items-center">
Expand All @@ -15,21 +13,19 @@ const ResourceCard = ({ item }: ItemProps) => {
) : (
<div className="bg-black-brand-03 rounded-full h-12 w-12 p-2 mx-2 text-green-brand-01 flex items-center justify-center">{`${item.name[0]}${item.name[1]}`.toUpperCase()}</div>
)}
<h2 className="text-lg break-all mx-1">{item.name}</h2>
<h2 className="text-lg break-all mx-1 text-white">{item.name}</h2>
</div>
</div>
<div className="flex flex-col flex-1 px-2 my-2">
{" "}
<p className="font-normal text-white text-base text-opacity-50 flex-1">
<p className="font-normal text-base text-opacity-50 flex-1">
{item.description}
</p>
</div>
</div>
<div className="px-4 py-2 flex flex-col items-end">
<div className="">
<h2 className="text-sm text-white bg-black-brand-02 rounded-full px-7 py-2">
{item.tag}
</h2>
<div>
<span className="text-sm flex items-center font-medium text-gray-brand-02 resource-card-tag capitalize"> {item.tag}</span>
</div>
</div>
</li>
Expand Down
8 changes: 6 additions & 2 deletions components/layout/index.tsx
Expand Up @@ -3,12 +3,15 @@ import DashMobileNavbar from "../navbar/DashMobileNavbar";
import Sidebar from "../navbar/Sidebar";
import Image from "next/image";
import DashTopBar from "../navbar/DashTopBar";
import ResourceModal from "../modals/SuggestResourceModal";
import codeIcon from "../../public/images/code-icon.png";
// import cssIcon from "../../public/images/css3.png";
// import magnifier from "../../public/images/magnifier.png";
import laptop from "../../public/images/laptop.png";
import { url } from "inspector";
const Layout = ({ children }: any) => {
const [toggleNav, setToogleNavBar] = React.useState(false);
const [showModal, setShowModal] = React.useState(false);

const toggleNavBar = () => {
setToogleNavBar(!toggleNav);
Expand All @@ -18,8 +21,8 @@ const Layout = ({ children }: any) => {
<DashMobileNavbar toggleNavBar={toggleNavBar} />
<Sidebar toggleState={toggleNav} toggleNavBar={toggleNavBar} />
<div className="flex flex-col flex-1 px-4 py-4 overflow-hidden lg:py-8 lg:px-6 xl:px-8">
<DashTopBar/>
<div className="border border-black-brand-05 h-60 rounded flex flex-col items-center justify-center my-4 relative">
<DashTopBar setShowModal={setShowModal} />
<div className="border border-black-brand-06 bg-black-brand-08 h-60 rounded flex flex-col items-center justify-center my-4 relative">
<div className="absolute w-20 h-20 bottom-0 right-5 animate-pulse">
<Image src={codeIcon} alt="code-icon" />
</div>
Expand All @@ -37,6 +40,7 @@ const Layout = ({ children }: any) => {
Place.
</h1>
</div>
<ResourceModal showModal={showModal} setShowModal={setShowModal} />
<div className="flex-1 py-4 lg:py-10">{children}</div>
</div>
</main>
Expand Down
141 changes: 141 additions & 0 deletions components/modals/SuggestResourceModal.tsx
@@ -0,0 +1,141 @@
import * as React from "react";
import { supabase } from "../../utils/supabase";
import { ToggleModalProps } from "../navbar/types";
import { Formik, Field, Form, ErrorMessage, FormikHelpers } from "formik";
import * as Yup from 'yup';
import { FormValues } from "./interface";
import { toast } from "react-toastify";
import { ResourceSchema } from "../../utils/yupValidation";



export default function ResourceModal(props: ToggleModalProps) {
const initialValues: FormValues = { name: "", link: "", tag: "" };

const submitResource = async (values: FormValues) => {
const { error } = await supabase
.from("suggested_resources")
.insert([values]);
if (error) {
console.log(error)
toast.error("oops! an error occured, kindly try again");
}
toast.success("yay 💃, resource has been successfully submitted");
};
return (
<>
{props.showModal ? (
<>
<div className="justify-center bg-black-brand-smoke items-center flex overflow-x-hidden overflow-y-auto fixed inset-0 z-50 outline-none focus:outline-none">
<div className="relative w-96 my-6 mx-auto max-w-5xl">
<div className="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-black-brand-08 outline-none focus:outline-none">
<div className="flex items-center justify-between p-5 my-3">
<h3 className="text-xl self-center font-medium text-white">
Suggest a Resource
</h3>
<button
className="p-1 ml-auto border-0 text-white float-right text-3xl leading-none font-normal outline-none focus:outline-none"
onClick={() => props.setShowModal(false)}
>
x
</button>
</div>
<Formik
initialValues={initialValues}
validationSchema={ResourceSchema}
onSubmit={async (values: FormValues, { setSubmitting }:FormikHelpers<FormValues>) => {
await submitResource(values);
setSubmitting(false);
props.setShowModal(false);
}}
>
{({ isSubmitting, errors, touched }) => (
<Form className="p-5">
<div className="mb-6">
<label
htmlFor="name"
className="block text-white mb-4 text-base font-normal"
>
Resource Name
</label>
<Field
id="name"
name="name"
className="form-input mt-1 block w-full bg-black-brand-01 text-white rounded-lg p-2 "
placeholder="w3 schools"
/>
{errors.name && touched.name ? (
<div className="text-red-700">{errors.name}</div>
) : null
}
</div>
<div className="mb-6">
<label
htmlFor="link"
className="block mb-4 text-white text-base font-normal"
>
Resource Link
</label>

<Field
id="link"
name="link"
className="form-input mt-1 block w-full bg-black-brand-01 text-white rounded-lg p-2 "
placeholder="https://www.smilebox.com"
/>
{errors.link && touched.link ? (
<div className="text-red-700">{errors.link}</div>
) : null
}
</div>
<div className="mb-6">
<label
htmlFor="tag"
className="block mb-4 text-base text-white font-normal"
>
Category
</label>

<Field
id="tag"
name="tag"
as="select"
className="form-select mt-1 block w-full border-0 rounded-lg bg-black-brand-01 text-white"
>
<option value="">Choose a category</option>
<option value="fonts">Fonts</option>
<option value="javascript">Javascript</option>
<option value="css">CSS</option>
<option value="pictures">Pictures</option>
<option value="docs">Docs</option>
<option value="playground">Playground</option>
</Field>
{errors.tag && touched.tag ? (
<div className="text-red-700">{errors.tag}</div>
) : null
}
</div>

<div className="mb-6 text-center">
<button
type="submit"
disabled={isSubmitting}
className="text-black-brand-01 bg-green-brand-01 font-normal uppercase text-base px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none my-3 ease-linear transition-all duration-150"
>
{isSubmitting
? "Submitting Resource"
: "Submit Resource"}
</button>
</div>
</Form>
)}
</Formik>
</div>
</div>
</div>
<div className="opacity-25 fixed inset-0 z-40 bg-black"></div>
</>
) : null}
</>
);
}
5 changes: 5 additions & 0 deletions components/modals/interface.ts
@@ -0,0 +1,5 @@
export interface FormValues {
name: string;
link: string;
tag: string;
}
6 changes: 4 additions & 2 deletions components/navbar/DashTopBar.tsx
@@ -1,6 +1,7 @@
import * as React from "react";
import { ToggleModalProps } from "./types";

export default function DashTopBar() {
export default function DashTopBar(props: ToggleModalProps) {
return (
<div className="flex justify-between w-full mx-auto max-w-screen-2xl">
<div className="hidden md:block">
Expand All @@ -22,10 +23,11 @@ export default function DashTopBar() {
</svg>
<input
type="text"
className="w-full h-10 pr-4 text-sm font-semibold text-white placeholder-white bg-black-brand-01 border border-black-brand-05 rounded-lg pl-9 placeholder-opacity-70 focus:outline-none focus:ring-2 focus:ring-green-brand-01 focus:ring-opacity-60"
className="w-full h-10 pr-4 text-sm font-semibold text-white placeholder-white bg-black-brand-08 border border-black-brand-06 rounded-lg pl-9 placeholder-opacity-70 focus:outline-none focus:ring-2 focus:ring-green-brand-01 focus:ring-opacity-60"
placeholder="Enter your search term..."
/>
</div>
<button onClick={() => props.setShowModal(true)} className="inline-flex bg-black-brand-08 border border-black-brand-06 text-green-brand-01 py-1 px-6 focus:outline-none rounded-lg text-lg hover:animate-bounce hover:text-white">Suggest a resource</button>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion components/navbar/Sidebar.tsx
Expand Up @@ -11,7 +11,7 @@ const Sidebar = (props: ToggleProps) => {
id="menu"
className={`sticky top-0 z-10 flex-col ${
props.toggleState ? "" : "hidden"
} h-screen px-4 py-4 bg-white dark:bg-black-brand-01 shadow-inner w-full lg:w-60 xl:w-64 2xl:w-80 lg:px-6 xl:px-8 lg:py-6 lg:flex overflow-scroll border-r border-black-brand-02`}
} h-screen px-4 py-4 bg-black-brand-08 shadow-inner w-full lg:w-60 xl:w-64 2xl:w-80 lg:px-6 xl:px-8 lg:py-6 lg:flex overflow-scroll border-r border-black-brand-06`}
>
<div className="flex-1 py-4">
<a href="#" className="hidden md:block">
Expand Down
5 changes: 5 additions & 0 deletions components/navbar/types.ts
Expand Up @@ -7,4 +7,9 @@ export type Menu = {
export type ToggleProps = {
toggleNavBar?(): any,
toggleState?: boolean
}

export type ToggleModalProps = {
setShowModal(value: boolean): any
showModal?: boolean
}
6 changes: 5 additions & 1 deletion package.json
Expand Up @@ -11,12 +11,16 @@
"dependencies": {
"@heroicons/react": "^1.0.4",
"@supabase/supabase-js": "^1.24.0",
"@tailwindcss/forms": "^0.3.4",
"formik": "^2.2.9",
"import": "^0.0.6",
"next": "latest",
"next-themes": "^0.0.15",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-query": "^3.26.0"
"react-query": "^3.26.0",
"react-toastify": "^8.0.3",
"yup": "^0.32.11"
},
"devDependencies": {
"@types/node": "^12.12.21",
Expand Down
21 changes: 16 additions & 5 deletions pages/_app.tsx
Expand Up @@ -4,9 +4,10 @@ import type { NextPage } from 'next'
import Head from 'next/head';
import { QueryClientProvider, QueryClient } from "react-query";
import { Hydrate } from "react-query/hydration";
import { ThemeProvider } from "next-themes";
// import '../styles/globals.css';
import "../styles/index.css";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import '../styles/globals.css';
// import "../styles/index.css";

type NextPageWithLayout = NextPage & {
getLayout?: (page: React.ReactElement) => React.ReactNode
Expand All @@ -23,12 +24,22 @@ export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return getLayout(
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<ThemeProvider attribute="class">
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</Head>
<Component {...pageProps} />
</ThemeProvider>
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="dark"
/>
</Hydrate>
</QueryClientProvider>

Expand Down
2 changes: 1 addition & 1 deletion pages/resources/[category].tsx
Expand Up @@ -20,7 +20,7 @@ export default function DashboardWithFilter() {
<ul
role="list"
className={
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 overflow-y-auto"
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 overflow-y-auto py-4"
}
>
{data && data.data && data.data.map(item => (
Expand Down
2 changes: 1 addition & 1 deletion pages/resources/index.tsx
Expand Up @@ -13,7 +13,7 @@ export default function Dashboard() {
<ul
role="list"
className={
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 overflow-y-auto"
"grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 overflow-y-auto py-4"
}
>
{data && data.data && data.data.map(item => (
Expand Down
1 change: 1 addition & 0 deletions public/images/gradient.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions styles/globals.css
Expand Up @@ -10,8 +10,21 @@ html {
.side-links li::before {
content: "\2022";
color: #3fd080;
/* backgound: #8b949e; */
font-weight: bold;
display: inline-block;
width: 1.5em;
margin-left: -1em;
}

.resource-card-tag::before {
border: 2px solid #3fd080;
content: "";
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
background: transparent;
margin-right: 4px;
}

0 comments on commit 5331bda

Please sign in to comment.