Skip to content

Commit

Permalink
Merge pull request #98 from sqrl-planner/develop
Browse files Browse the repository at this point in the history
Bump version
  • Loading branch information
eamonma authored Jul 11, 2022
2 parents 1bdeca6 + b46cebd commit 8016ca1
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 78 deletions.
11 changes: 9 additions & 2 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Badge,
useToast,
} from "@chakra-ui/react"
import Head from "next/head"
import { EditIcon, Icon, InfoIcon, SettingsIcon } from "@chakra-ui/icons"
import { FaShareSquare } from "react-icons/fa"
import { useAppContext } from "../src/SqrlContext"
Expand Down Expand Up @@ -83,11 +84,11 @@ const Header = ({ setSidebarOpen }: { setSidebarOpen: any }) => {

const router = useRouter()

const { allowedToEdit, updateName } = useTimetable({
const { allowedToEdit } = useTimetable({
id: (router.query.id as string) || "",
})

const { name } = useSections()
const { name, updateName } = useSections()

const keydownListener = useCallback(
(e: KeyboardEvent) => {
Expand Down Expand Up @@ -162,6 +163,12 @@ const Header = ({ setSidebarOpen }: { setSidebarOpen: any }) => {

return (
<HeaderComponent bg={useColorModeValue("gray.75", "gray.700")}>
<Head>
<title>Sqrl Planner | {name}</title>
<meta property="og:url" content={`${sharePrefix}${id}`} />
<meta property="og:type" content="website" />
<meta property="og:title" content={`Sqrl Planner | ${name}`} />
</Head>
<AboutModal isOpen={isAboutOpen} onClose={onCloseAbout} />
<ShareModal isOpen={isShareOpen} onClose={onCloseShare} />
<Flex flex="1" alignItems="center" pl="11rem">
Expand Down
100 changes: 69 additions & 31 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ import { useTranslation } from "next-i18next"
import AboutModal from "../components/AboutModal"
import Layout from "../components/Layout"
import { FaMoon, FaSun } from "react-icons/fa"
import { IconType } from "react-icons"
import { theme } from "./_app"

/**
* Darkens a color by a percentage
* @param hexColor A hex color with a hashtag, like #ABCDEF
* @param percentage A positive real number
* Values from 0-1 make the color darker
* A value of 1 keeps the color the same
* Values greater than 1 make the color brighter, up to FFFFFF
*/
function changeColor(hexColor: string, percentage: number): string {
const changeChannel = (twoDigitHex: string): string => {
const base10Number = Math.floor(parseInt(twoDigitHex, 16) * percentage)
const constrained = Math.min(Math.max(0, base10Number), 255) // Put in [0, 255] range
const stringRep = constrained.toString(16)
return stringRep.length === 1 ? "0" + stringRep : stringRep
}

const red = changeChannel(hexColor.slice(1, 3))
const green = changeChannel(hexColor.slice(3, 5))
const blue = changeChannel(hexColor.slice(5, 7))

return "#" + red + green + blue
}

const Dashboard = () => {
const router = useRouter()
Expand Down Expand Up @@ -167,6 +192,29 @@ const Dashboard = () => {

const { t } = useTranslation("index")

// Differences in the UI between light and dark mode
// Mostly for icons/hover
interface ModeConfig {
tLabel: string
icon: IconType
iconId: string
hoverFactor: number
}
const modeConfig: ModeConfig = {
light: {
tLabel: "light-mode",
icon: FaSun,
iconId: "sun-icon",
hoverFactor: 0.9,
},
dark: {
tLabel: "dark-mode",
icon: FaMoon,
iconId: "moon-icon",
hoverFactor: 1.1,
},
}[colorMode]

return (
<React.Fragment>
<AboutModal isOpen={isAboutOpen} onClose={onCloseAbout} />
Expand Down Expand Up @@ -286,9 +334,16 @@ const Dashboard = () => {
px={8}
minH="2xs"
fontWeight="medium"
transition="background 75ms linear"
position="relative"
opacity={!!pageLoading ? "0.5" : "1"}
cursor={!!pageLoading ? "not-allowed" : "pointer"}
_hover={{
background: changeColor(
theme.colors.blue[600],
modeConfig.hoverFactor
), // blue[700] doesn't work here
}}
onClick={() => {
if (pageLoading) return
setPageLoading(id)
Expand Down Expand Up @@ -382,37 +437,20 @@ const Dashboard = () => {
<Tab onClick={onOpenAbout}>{t("common:about")}</Tab>
<Tab onClick={toggleColorMode}>
<AnimatePresence exitBeforeEnter>
{colorMode === "light" ? (
<React.Fragment>
<motion.div
key="moon-icon"
initial={{
opacity: 0,
y: -15,
rotate: -45,
}}
animate={{ opacity: 1, y: 0, rotate: 0 }}
>
<Icon as={FaMoon} mr={2} />
</motion.div>{" "}
{t("dark-mode")}
</React.Fragment>
) : (
<React.Fragment>
<motion.div
key="sun-icon"
initial={{
opacity: 0,
y: -15,
rotate: -45,
}}
animate={{ opacity: 1, y: 0, rotate: 0 }}
>
<Icon as={FaSun} mr={2} />
</motion.div>{" "}
{t("light-mode")}
</React.Fragment>
)}
<React.Fragment>
<motion.div
key={modeConfig.iconId}
initial={{
opacity: 0,
y: -15,
rotate: -45,
}}
animate={{ opacity: 1, y: 0, rotate: 0 }}
>
<Icon as={modeConfig.icon} mr={2} />
</motion.div>{" "}
{t(modeConfig.tLabel)}
</React.Fragment>
</AnimatePresence>
</Tab>
</TabList>
Expand Down
21 changes: 4 additions & 17 deletions pages/timetable/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ApolloClient, InMemoryCache } from "@apollo/client"
import type { NextPage } from "next"
import { serverSideTranslations } from "next-i18next/serverSideTranslations"
import Head from "next/head"
import React, { useEffect, useState } from "react"
import React from "react"
import Layout from "../../components/Layout"
import { GET_TIMETABLE_BY_ID } from "../../operations/queries/getTimetableById"
import { apolloClientParams } from "../../src/apollo-client"
Expand All @@ -12,26 +11,14 @@ import { AppContextProvider } from "../../src/SqrlContext"
import { SectionsProvider } from "../../src/useSections"

export const TimetableView: NextPage = (props: any) => {
const [sharePrefix, setSharePrefix] = useState("")

useEffect(() => {
setSharePrefix(
`${window.location.protocol}//${window.location.host}/timetable/`
)
}, [])

return (
<React.Fragment>
<Head>
<title>Sqrl Planner | {props.name}</title>
<meta property="og:url" content={`${sharePrefix}${props.id}`} />
<meta property="og:type" content="website" />
<meta property="og:title" content={`Sqrl Planner | ${props.name}`} />
</Head>
<PreferencesProvider>
<AppContextProvider>
<SectionsProvider initialSections={props.sections}>
<Layout><Sqrl /></Layout>
<Layout>
<Sqrl />
</Layout>
</SectionsProvider>
</AppContextProvider>
</PreferencesProvider>
Expand Down
32 changes: 31 additions & 1 deletion src/useSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { createContext, useContext, useEffect, useState } from "react"
import { REMOVE_COURSE_TIMETABLE } from "../operations/mutations/removeCourseTimetable"
import { SET_SECTIONS_TIMETABLE } from "../operations/mutations/setSectionsTimetable"
import { GET_TIMETABLE_BY_ID } from "../operations/queries/getTimetableById"
import { SET_TIMETABLE_NAME } from "../operations/mutations/setTimetableName"

import useTimetable from "./useTimetable"
import {
constructSectionsFromMeetings,
Expand All @@ -24,6 +26,7 @@ const SectionsContext = createContext<
| {
sections: { [key: string]: Array<string> }
name: string
updateName: Function
setSections: Function
removeCourse: Function
}
Expand Down Expand Up @@ -71,7 +74,7 @@ export const SectionsProvider = ({
}, [data, id])

const [setSectionsTimetable] = useMutation(SET_SECTIONS_TIMETABLE)

const [setTimetableName] = useMutation(SET_TIMETABLE_NAME)
const [removeCourse] = useMutation(REMOVE_COURSE_TIMETABLE)

const removeTimetableCourse = ({ courseId }: RemoveTimetableCourseProps) => {
Expand Down Expand Up @@ -115,11 +118,38 @@ export const SectionsProvider = ({
})
}

const updateName = (name: string, cb?: Function) => {
if (!key) return
if (!id) return

// Set the name in the client (contexts)
setName(name)

// Set the new name in LS (persistence)
setTimetableName({
variables: { id, key, name },
onCompleted: (data) => {
const prevLsTimetablesJSON = localStorage.getItem("timetables")
let prevLsTimetables: { [key: string]: { key: string; name: string } } =
{}
if (prevLsTimetablesJSON)
prevLsTimetables = JSON.parse(prevLsTimetablesJSON)

prevLsTimetables[id].name = data.setTimetableName.timetable.name

localStorage.setItem("timetables", JSON.stringify(prevLsTimetables))

if (cb) cb()
},
})
}

return (
<SectionsContext.Provider
value={{
sections,
name,
updateName,
setSections: setTimetableSections,
removeCourse: removeTimetableCourse,
}}
Expand Down
28 changes: 1 addition & 27 deletions src/useTimetable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useMutation } from "@apollo/client"
import { useToast } from "@chakra-ui/react"
import { useEffect, useState } from "react"
import { SET_TIMETABLE_NAME } from "../operations/mutations/setTimetableName"

type Props = {
id?: string
Expand Down Expand Up @@ -46,31 +44,7 @@ const useTimetable = ({ id }: Props) => {
}
}, [allowedToEdit])

const [setTimetableName] = useMutation(SET_TIMETABLE_NAME)

const updateName = (name: string, cb?: Function) => {
if (!key) return
if (!id) return

setTimetableName({
variables: { id, key, name },
onCompleted: (data) => {
const prevLsTimetablesJSON = localStorage.getItem("timetables")
let prevLsTimetables: { [key: string]: { key: string; name: string } } =
{}
if (prevLsTimetablesJSON)
prevLsTimetables = JSON.parse(prevLsTimetablesJSON)

prevLsTimetables[id].name = data.setTimetableName.timetable.name

localStorage.setItem("timetables", JSON.stringify(prevLsTimetables))

if (cb) cb()
},
})
}

return { allowedToEdit, updateName, key }
return { allowedToEdit, key }
}

export default useTimetable

0 comments on commit 8016ca1

Please sign in to comment.