generated from scaffold-eth/scaffold-eth-2
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* edit form submit buttons width * add reduxToolkit, react-redux, next redux wrapper packages * add dash-wind components converted to typescript * change all Next <Image /> back to HTML <img /> * edit store.ts to follow next-redux-wrapper docs * add next-redux-wrapper provider to _app.tsx * move to store.ts * swap out react-redux imports for next-react-redux imports * move FormSteps type to its own ts file * add login/register/forgot-password/welcome pages and edit link routing * small edits * add deps to useEffect deps array * add page layout for dashboard with header and side nav * add 404 fallback page * backup original dapp onboarding flow - probably delete later * remove some commented code * routing and icon edit * edit routes, comment out some sidebar routs, rename 404 page so it will work * edit route * add all dashboard pages * add all missing deps to useEffect deps arrays * add more deps to deps arrays * es-lint ignore img elements
- Loading branch information
1 parent
ba73c57
commit 8cca1fd
Showing
119 changed files
with
4,983 additions
and
20 deletions.
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
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,43 @@ | ||
import axios, { AxiosError, AxiosResponse } from "axios"; | ||
|
||
const checkAuth = () => { | ||
/* Getting token value stored in localstorage, if token is not present we will open login page | ||
for all internal dashboard routes */ | ||
const TOKEN = localStorage.getItem("token"); | ||
const PUBLIC_ROUTES = ["login", "forgot-password", "register", "documentation"]; | ||
|
||
const isPublicPage = PUBLIC_ROUTES.some(r => window.location.href.includes(r)); | ||
|
||
if (!TOKEN && !isPublicPage) { | ||
window.location.href = "/login"; | ||
return; | ||
} else { | ||
axios.defaults.headers.common["Authorization"] = `Bearer ${TOKEN}`; | ||
|
||
axios.interceptors.request.use( | ||
function (config) { | ||
// UPDATE: Add this code to show global loading indicator | ||
document.body.classList.add("loading-indicator"); | ||
return config; | ||
}, | ||
function (error: AxiosError) { | ||
return Promise.reject(error); | ||
}, | ||
); | ||
|
||
axios.interceptors.response.use( | ||
function (response: AxiosResponse) { | ||
// UPDATE: Add this code to hide global loading indicator | ||
document.body.classList.remove("loading-indicator"); | ||
return response; | ||
}, | ||
function (error: AxiosError) { | ||
document.body.classList.remove("loading-indicator"); | ||
return Promise.reject(error); | ||
}, | ||
); | ||
return TOKEN; | ||
} | ||
}; | ||
|
||
export default checkAuth; |
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,20 @@ | ||
import axios from "axios"; | ||
|
||
const initializeApp = () => { | ||
// Setting base URL for all API request via axios | ||
axios.defaults.baseURL = process.env.REACT_APP_BASE_URL; | ||
|
||
if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") { | ||
// dev code | ||
} else { | ||
// Prod build code | ||
|
||
// Removing console.log from prod | ||
// console.log = () => {}; | ||
console.log = () => null; | ||
|
||
// init analytics here | ||
} | ||
}; | ||
|
||
export default initializeApp; |
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,62 @@ | ||
import headerSlice from "../features/common/headerSlice"; | ||
import modalSlice from "../features/common/modalSlice"; | ||
import rightDrawerSlice from "../features/common/rightDrawerSlice"; | ||
import leadsSlice from "../features/leads/leadSlice"; | ||
import { Reducer, ThunkAction, configureStore } from "@reduxjs/toolkit"; | ||
import { createWrapper } from "next-redux-wrapper"; | ||
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; | ||
import { Action } from "redux"; | ||
|
||
interface CombinedReducer { | ||
header: Reducer<{ | ||
pageTitle: string; | ||
noOfNotifications: number; | ||
newNotificationMessage: string; | ||
newNotificationStatus: number; | ||
}>; | ||
rightDrawer: Reducer<{ | ||
header: string; | ||
isOpen: boolean; | ||
bodyType: string; | ||
extraObject: Record<string, any>; | ||
}>; | ||
modal: Reducer<{ | ||
title: string; | ||
isOpen: boolean; | ||
bodyType: string; | ||
size: string; | ||
extraObject: Record<string, any>; | ||
}>; | ||
lead: Reducer<{ | ||
isLoading: boolean; | ||
leads: never[]; | ||
}>; | ||
} | ||
|
||
const combinedReducer: CombinedReducer = { | ||
header: headerSlice, | ||
rightDrawer: rightDrawerSlice, | ||
modal: modalSlice, | ||
lead: leadsSlice, | ||
}; | ||
|
||
// export default configureStore({ | ||
// reducer: combinedReducer, | ||
// }); | ||
const store = configureStore({ | ||
reducer: combinedReducer, | ||
}); | ||
|
||
// const makeStore = context => store; | ||
const makeStore = () => store; | ||
|
||
export type MyStore = ReturnType<typeof makeStore>; | ||
export type MyState = ReturnType<MyStore["getState"]>; | ||
export type MyDispatch = MyStore["dispatch"]; | ||
// export type MyDispatch = typeof store.dispatch; | ||
export type MyThunk<ReturnType = void> = ThunkAction<ReturnType, MyState, unknown, Action>; | ||
|
||
export const useMyDispatch = () => useDispatch<MyDispatch>(); | ||
export const useMySelector: TypedUseSelectorHook<MyState> = useSelector; | ||
|
||
export const wrapper = createWrapper<MyStore>(makeStore); |
178 changes: 178 additions & 0 deletions
178
packages/nextjs/components/dash-wind/components/CalendarView/index.tsx
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,178 @@ | ||
import { useEffect, useState } from "react"; | ||
import { CalendarDetails, CalendarEvents } from "../../types/CalendarTypes"; | ||
import { getTheme } from "./util"; | ||
import moment from "moment"; | ||
import ChevronLeftIcon from "@heroicons/react/24/solid/ChevronLeftIcon"; | ||
import ChevronRightIcon from "@heroicons/react/24/solid/ChevronRightIcon"; | ||
|
||
interface props { | ||
calendarEvents: CalendarEvents; | ||
addNewEvent: (date: moment.Moment) => void; | ||
openDayDetail: (detail: CalendarDetails) => void; | ||
} | ||
|
||
const CalendarView: React.FC<props> = ({ calendarEvents, addNewEvent, openDayDetail }) => { | ||
const today = moment().startOf("day"); | ||
const weekdays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]; | ||
const colStartClasses = [ | ||
"", | ||
"col-start-2", | ||
"col-start-3", | ||
"col-start-4", | ||
"col-start-5", | ||
"col-start-6", | ||
"col-start-7", | ||
]; | ||
|
||
const [firstDayOfMonth, setFirstDayOfMonth] = useState<moment.Moment>(moment().startOf("month")); | ||
const [events, setEvents] = useState<[] | CalendarEvents>([]); | ||
const [, setCurrMonth] = useState<string>(() => moment(today).format("MMM-yyyy")); | ||
|
||
useEffect(() => { | ||
setEvents(calendarEvents); | ||
}, [calendarEvents]); | ||
|
||
const allDaysInMonth = () => { | ||
const start: moment.Moment = moment(firstDayOfMonth).startOf("week"); | ||
const end: moment.Moment = moment(moment(firstDayOfMonth).endOf("month")).endOf("week"); | ||
const days: moment.Moment[] = []; | ||
let day: moment.Moment = start; | ||
while (day <= end) { | ||
days.push(day); | ||
day = day.clone().add(1, "d"); | ||
} | ||
return days; | ||
}; | ||
|
||
const getEventsForCurrentDate = (date: moment.Moment): CalendarEvents => { | ||
let filteredEvents = events.filter(e => { | ||
if ("startTime" in e) { | ||
return moment(date).isSame(moment(e.startTime), "day"); | ||
} | ||
return false; | ||
}); | ||
if (filteredEvents.length > 2) { | ||
const originalLength = filteredEvents.length; | ||
filteredEvents = filteredEvents.slice(0, 2); | ||
filteredEvents.push({ title: `${originalLength - 2} more`, theme: "MORE" }); | ||
} | ||
return filteredEvents; | ||
}; | ||
|
||
const openAllEventsDetail = (date: moment.Moment, theme: string) => { | ||
if (theme != "MORE") return 1; | ||
const filteredEvents = events | ||
.filter(e => { | ||
if ("startTime" in e) { | ||
return moment(date).isSame(moment(e.startTime), "day"); | ||
} | ||
return false; | ||
}) | ||
.map(e => { | ||
return { title: e.title, theme: e.theme }; | ||
}); | ||
openDayDetail({ filteredEvents, title: moment(date).format("D MMM YYYY") }); | ||
}; | ||
|
||
const isToday = (date: moment.Moment) => { | ||
return moment(date).isSame(moment(), "day"); | ||
}; | ||
|
||
const isDifferentMonth = (date: moment.Moment) => { | ||
return moment(date).month() != moment(firstDayOfMonth).month(); | ||
}; | ||
|
||
// const getPrevMonth = (event) => { | ||
const getPrevMonth = () => { | ||
const firstDayOfPrevMonth = moment(firstDayOfMonth).add(-1, "M").startOf("month"); | ||
setFirstDayOfMonth(firstDayOfPrevMonth); | ||
setCurrMonth(moment(firstDayOfPrevMonth).format("MMM-yyyy")); | ||
}; | ||
|
||
// const getCurrentMonth = (event) => { | ||
const getCurrentMonth = () => { | ||
const firstDayOfCurrMonth = moment().startOf("month"); | ||
setFirstDayOfMonth(firstDayOfCurrMonth); | ||
setCurrMonth(moment(firstDayOfCurrMonth).format("MMM-yyyy")); | ||
}; | ||
|
||
// const getNextMonth = (event: any) => { | ||
const getNextMonth = () => { | ||
const firstDayOfNextMonth = moment(firstDayOfMonth).add(1, "M").startOf("month"); | ||
setFirstDayOfMonth(firstDayOfNextMonth); | ||
setCurrMonth(moment(firstDayOfNextMonth).format("MMM-yyyy")); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="w-full bg-base-100 p-4 rounded-lg"> | ||
<div className="flex items-center justify-between"> | ||
<div className="flex justify-normal gap-2 sm:gap-4"> | ||
<p className="font-semibold text-xl w-48"> | ||
{moment(firstDayOfMonth).format("MMMM yyyy").toString()} | ||
<span className="text-xs ml-2 ">Beta</span> | ||
</p> | ||
|
||
<button className="btn btn-square btn-sm btn-ghost" onClick={getPrevMonth}> | ||
<ChevronLeftIcon className="w-5 h-5" /> | ||
</button> | ||
<button className="btn btn-sm btn-ghost normal-case" onClick={getCurrentMonth}> | ||
Current Month | ||
</button> | ||
<button className="btn btn-square btn-sm btn-ghost" onClick={getNextMonth}> | ||
<ChevronRightIcon className="w-5 h-5" /> | ||
</button> | ||
</div> | ||
<div> | ||
<button className="btn btn-sm btn-ghost btn-outline normal-case" onClick={() => addNewEvent}> | ||
Add New Event | ||
</button> | ||
</div> | ||
</div> | ||
<div className="my-4 divider" /> | ||
<div className="grid grid-cols-7 gap-6 sm:gap-12 place-items-center"> | ||
{weekdays.map((day, key) => { | ||
return ( | ||
<div className="text-xs capitalize" key={key}> | ||
{day} | ||
</div> | ||
); | ||
})} | ||
</div> | ||
|
||
<div className="grid grid-cols-7 mt-1 place-items-center"> | ||
{allDaysInMonth().map((day, idx) => { | ||
return ( | ||
<div key={idx} className={colStartClasses[moment(day).day()] + " border border-solid w-full h-28 "}> | ||
<p | ||
// className={`inline-block flex items-center justify-center h-8 w-8 rounded-full mx-1 mt-1 text-sm cursor-pointer hover:bg-base-300 ${ | ||
className={`flex items-center justify-center h-8 w-8 rounded-full mx-1 mt-1 text-sm cursor-pointer hover:bg-base-300 ${ | ||
isToday(day) && " bg-blue-100 dark:bg-blue-400 dark:hover:bg-base-300 dark:text-white" | ||
} ${isDifferentMonth(day) && " text-slate-400 dark:text-slate-600"}`} | ||
onClick={() => addNewEvent(day)} | ||
> | ||
{" "} | ||
{moment(day).format("D")} | ||
</p> | ||
{getEventsForCurrentDate(day).map((e, k) => { | ||
return ( | ||
<p | ||
key={k} | ||
onClick={() => openAllEventsDetail(day, e.theme)} | ||
className={`text-xs px-2 mt-1 truncate ${getTheme(e.theme) || ""}`} | ||
// className={`text-xs px-2 mt-1 truncate ${THEME_BG[e.theme] || ""}`} | ||
> | ||
{e.title} | ||
</p> | ||
); | ||
})} | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default CalendarView; |
29 changes: 29 additions & 0 deletions
29
packages/nextjs/components/dash-wind/components/CalendarView/util.ts
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,29 @@ | ||
// import moment from "moment"; | ||
// const moment = require("moment"); | ||
|
||
export function getTheme(theme: string) { | ||
const THEME_BG = CALENDAR_EVENT_STYLE; | ||
switch (theme) { | ||
case "BLUE": | ||
return THEME_BG.BLUE; | ||
case "GREEN": | ||
return THEME_BG.GREEN; | ||
case "PURPLE": | ||
return THEME_BG.PURPLE; | ||
case "ORANGE": | ||
return THEME_BG.ORANGE; | ||
case "PINK": | ||
return THEME_BG.PINK; | ||
case "MORE": | ||
return THEME_BG.MORE; | ||
} | ||
} | ||
|
||
export const CALENDAR_EVENT_STYLE = Object.freeze({ | ||
BLUE: "bg-blue-200 dark:bg-blue-600 dark:text-blue-100", | ||
GREEN: "bg-green-200 dark:bg-green-600 dark:text-green-100", | ||
PURPLE: "bg-purple-200 dark:bg-purple-600 dark:text-purple-100", | ||
ORANGE: "bg-orange-200 dark:bg-orange-600 dark:text-orange-100", | ||
PINK: "bg-pink-200 dark:bg-pink-600 dark:text-pink-100", | ||
MORE: "hover:underline cursor-pointer font-medium ", | ||
}); |
30 changes: 30 additions & 0 deletions
30
packages/nextjs/components/dash-wind/components/Cards/TitleCard.tsx
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,30 @@ | ||
import { ReactNode } from "react"; | ||
import Subtitle from "../Typography/Subtitle"; | ||
|
||
interface props { | ||
title: string; | ||
children: ReactNode; | ||
topMargin?: string; | ||
TopSideButtons?: JSX.Element; | ||
} | ||
|
||
function TitleCard({ title, children, topMargin, TopSideButtons }: props) { | ||
return ( | ||
<div className={"card w-full p-6 bg-base-100 shadow-xl " + (topMargin || "mt-6")}> | ||
{/* Title for Card */} | ||
<Subtitle styleClass={TopSideButtons ? "inline-block" : ""}> | ||
{title} | ||
|
||
{/* Top side button, show only if present */} | ||
{TopSideButtons && <div className="inline-block float-right">{TopSideButtons}</div>} | ||
</Subtitle> | ||
|
||
<div className="divider mt-2"></div> | ||
|
||
{/** Card Body */} | ||
<div className="h-full w-full pb-6 bg-base-100">{children}</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default TitleCard; |
Oops, something went wrong.