Skip to content

Commit

Permalink
Add auth & app/auth loading state; ssr fix
Browse files Browse the repository at this point in the history
  • Loading branch information
braddf committed May 28, 2024
1 parent 5346b1b commit f9a54bb
Show file tree
Hide file tree
Showing 17 changed files with 446 additions and 177 deletions.
3 changes: 2 additions & 1 deletion apps/nowcasting-app/components/map/deltaMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import mapboxgl, { Expression } from "mapbox-gl";
import { FailedStateMap, LoadStateMap, Map, MeasuringUnit } from "./";
import { ActiveUnit, SelectedData } from "./types";
import { DELTA_BUCKET, VIEWS } from "../../constant";
import ButtonGroup from "../../components/button-group";
import gspShapeData from "../../data/gsp_regions_20220314.json";
import useGlobalState from "../helpers/globalState";
import { formatISODateString, formatISODateStringHuman } from "../helpers/utils";
Expand All @@ -28,7 +27,9 @@ import DeltaColorGuideBar from "./delta-color-guide-bar";
import { safelyUpdateMapData } from "../helpers/mapUtils";
import { generateGeoJsonForecastData } from "../helpers/data";
import { components } from "../../types/quartz-api";
import dynamic from "next/dynamic";
const yellow = theme.extend.colors["ocf-yellow"].DEFAULT;
const ButtonGroup = dynamic(() => import("../../components/button-group"), { ssr: false });

const getRoundedPv = (pv: number, round: boolean = true) => {
if (!round) return Math.round(pv);
Expand Down
4 changes: 3 additions & 1 deletion apps/nowcasting-app/components/map/pvLatestMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import mapboxgl, { Expression } from "mapbox-gl";
import { FailedStateMap, LoadStateMap, Map, MeasuringUnit } from "./";
import { ActiveUnit, SelectedData } from "./types";
import { MAX_POWER_GENERATED, VIEWS } from "../../constant";
import ButtonGroup from "../../components/button-group";
import gspShapeData from "../../data/gsp_regions_20220314.json";
import useGlobalState from "../helpers/globalState";
import { formatISODateString, formatISODateStringHuman } from "../helpers/utils";
Expand All @@ -17,8 +16,11 @@ import { FeatureCollection } from "geojson";
import { safelyUpdateMapData } from "../helpers/mapUtils";
import { components } from "../../types/quartz-api";
import { generateGeoJsonForecastData } from "../helpers/data";
import dynamic from "next/dynamic";
const yellow = theme.extend.colors["ocf-yellow"].DEFAULT;

const ButtonGroup = dynamic(() => import("../../components/button-group"), { ssr: false });

type PvLatestMapProps = {
className?: string;
combinedData: CombinedData;
Expand Down
3 changes: 2 additions & 1 deletion apps/nowcasting-app/components/map/sitesMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
MAX_POWER_GENERATED,
VIEWS
} from "../../constant";
import ButtonGroup from "../../components/button-group";
import gspShapeData from "../../data/gsp_regions_20220314.json";
import dnoShapeData from "../../data/dno_regions_lat_long_converted.json";
import useGlobalState from "../helpers/globalState";
Expand All @@ -26,8 +25,10 @@ import { Feature, FeatureCollection } from "geojson";
import Slider from "./sitesMapFeatures/sitesZoomSlider";
import SitesLegend from "./sitesMapFeatures/sitesLegend";
import { safelyUpdateMapData } from "../helpers/mapUtils";
import dynamic from "next/dynamic";

const yellow = theme.extend.colors["ocf-yellow"].DEFAULT;
const ButtonGroup = dynamic(() => import("../../components/button-group"), { ssr: false });

const getRoundedPv = (pv: number, round: boolean = true) => {
if (!round) return Math.round(pv);
Expand Down
7 changes: 7 additions & 0 deletions apps/quartz-app/app/api/auth/[auth0]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { handleAuth, handleLogout } from "@auth0/nextjs-auth0";

export const GET = handleAuth({
logout: handleLogout({
returnTo: "/logout",
}),
});
10 changes: 10 additions & 0 deletions apps/quartz-app/app/api/token/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { NextResponse } from "next/server";
import { getAccessToken, withApiAuthRequired } from "@auth0/nextjs-auth0";

const GET = withApiAuthRequired(async function GET(req) {
const res = new NextResponse();
const { accessToken } = await getAccessToken(req, res);
return NextResponse.json({ accessToken }, res);
});

export { GET };
6 changes: 0 additions & 6 deletions apps/quartz-app/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}

@layer utilities {
Expand Down
15 changes: 7 additions & 8 deletions apps/quartz-app/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "../src/components/layout/Header";
import Providers from "@/app/providers";
import { ReactNode } from "react";
import { UserProvider } from "@auth0/nextjs-auth0/client";
import LayoutWrapper from "@/src/components/layout/LayoutWrapper";

const inter = Inter({ subsets: ["latin"] });

Expand All @@ -19,12 +19,11 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>
<Providers>
<Header />
{children}
</Providers>
</body>
<UserProvider>
<body className={inter.className}>
<LayoutWrapper>{children}</LayoutWrapper>
</body>
</UserProvider>
</html>
);
}
93 changes: 93 additions & 0 deletions apps/quartz-app/app/logout/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"use client";

import { useRouter } from "next/navigation";
import { ChevronRightIcon } from "@heroicons/react/solid";
import { SupportIcon, ViewListIcon } from "@heroicons/react/outline";

const MyPage = () => {
const router = useRouter();
const links = [
// {
// title: "Documentation",
// description: "Learn how to integrate our tools with your app",
// icon: BookOpenIcon,
// url: "https://openclimatefix.notion.site/Quartz-Solar-Documentation-0d718915650e4f098470d695aa3494bf",
// },
{
title: "API Reference",
description: "A complete API reference for our library",
icon: ViewListIcon,
url:
process.env.NEXT_PUBLIC_API_URL + "docs" ||
"https://api.quartz.energy/docs",
},
{
title: "Support",
description: "Get help with any problems you encounter",
icon: SupportIcon,
url: "mailto:[email protected]?subject=Quartz%20Energy%20Support%20Request",
},
];
return (
<div className="container flex-1 flex flex-col gap-6 py-24 items-center">
<div className="flex-1 flex flex-col gap-6 justify-center text-center md:text-left items-center">
<h1 className="text-4xl text-white">See you next time.</h1>
<h2 className="text-xl text-white px-3">
You have been successfully logged out.
</h2>
<button
className="bg-ocf-yellow py-2 px-3 rounded-md"
onClick={() => router.push("/api/auth/login")}
>
Log back in &rarr;
</button>
</div>
<div className="max-w-3xl w-full flex flex-1 flex-col gap-6 justify-center items-center">
<div className="mt-16">
<h2 className="text-sm font-semibold tracking-wide text-gray-300 uppercase">
More from Quartz
</h2>
<ul
role="list"
className="mt-4 border-t border-b border-gray-200 divide-y divide-gray-200"
>
{links.map((link, linkIdx) => (
<li
key={`LogoutLink${linkIdx}`}
className="relative flex items-start py-6 space-x-4"
>
<div className="flex-shrink-0">
<span className="flex items-center justify-center w-12 h-12 rounded-lg">
<link.icon
className="w-6 h-6 text-gray-300"
aria-hidden="true"
/>
</span>
</div>
<div className="flex-1 min-w-0">
<h3 className="text-base font-medium text-gray-100">
<span className="rounded-sm focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-gray-500">
<a href={link.url} className="focus:outline-none">
<span className="absolute inset-0" aria-hidden="true" />
{link.title}
</a>
</span>
</h3>
<p className="text-base text-gray-400">{link.description}</p>
</div>
<div className="self-center flex-shrink-0">
<ChevronRightIcon
className="w-5 h-5 text-gray-400"
aria-hidden="true"
/>
</div>
</li>
))}
</ul>
</div>
</div>
</div>
);
};

export default MyPage;
143 changes: 21 additions & 122 deletions apps/quartz-app/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,130 +1,29 @@
"use client";
import Image from "next/image";
import Sidebar from "../src/components/Sidebar";
import Charts from "../src/components/charts/Charts";
import {
dehydrate,
HydrationBoundary,
QueryClient,
} from "@tanstack/react-query";
import { GET_REGIONS, getRegionsQuery } from "@/src/data/queries";
import {
useGetForecastedGenerationForRegionQuery,
useGetGenerationForRegionQuery,
useGetRegionsQuery,
} from "@/src/hooks/queries";
import { CombinedData } from "@/src/types/data";
import { useEffect, useMemo } from "react";
import useGlobalState from "@/src/components/helpers/globalState";

export default function Home() {
const [combinedData, setCombinedData] = useGlobalState("combinedData");

const queryClient = new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
refetchInterval: 60 * 1000,
import { withPageAuthRequired } from "@auth0/nextjs-auth0";
import { Main } from "@/src/components/Main";

export default withPageAuthRequired(
async function Home() {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
refetchInterval: 60 * 1000,
},
},
}, //
});

queryClient.prefetchQuery({
queryKey: [GET_REGIONS, "solar"],
queryFn: () => getRegionsQuery("solar"),
});

const { data: solarRegionsData, error: solarRegionsError } =
useGetRegionsQuery("solar");
console.log("page solarRegionsData", solarRegionsData);

const { data: windRegionsData, error: windRegionsError } =
useGetRegionsQuery("wind");
console.log("page windRegionsData", windRegionsData);

const { data: solarGenerationData, error: solarGenerationError } =
useGetGenerationForRegionQuery(
"solar",
solarRegionsData?.regions[0] || "",
!!solarRegionsData?.regions[0]
);
const { data: windGenerationData, error: windGenerationError } =
useGetGenerationForRegionQuery(
"wind",
windRegionsData?.regions[0] || "",
!!windRegionsData?.regions[0]
);

// Get forecast data
const { data: solarForecastData, error: solarForecastError } =
useGetForecastedGenerationForRegionQuery(
"solar",
solarRegionsData?.regions[0] || "",
!!solarRegionsData?.regions[0]
);
const { data: windForecastData, error: windForecastError } =
useGetForecastedGenerationForRegionQuery(
"wind",
windRegionsData?.regions[0] || "",
!!windRegionsData?.regions[0]
);
});

const latestCombinedData: CombinedData = useMemo(() => {
return {
solarGenerationData,
windGenerationData,
solarForecastData,
windForecastData,
};
}, [
solarGenerationData,
windGenerationData,
solarForecastData,
windForecastData,
]);

useEffect(() => {
console.log("combinedData updated", latestCombinedData);
setCombinedData(latestCombinedData);
}, [latestCombinedData]);

if (
solarRegionsError ||
windRegionsError ||
solarGenerationError ||
windGenerationError ||
solarForecastError ||
windForecastError
) {
console.log(
"error",
solarRegionsError,
windRegionsError,
solarGenerationError,
windGenerationError,
solarForecastError,
windForecastError
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Main />
</HydrationBoundary>
);
return <div>Error</div>;
}

console.log("page solarGenerationData", solarGenerationData);
console.log("page windGenerationData", windGenerationData);

return (
<HydrationBoundary state={dehydrate(queryClient)}>
<main className="flex min-h-screen bg-ocf-gray-900 flex-row items-stretch justify-between pt-16">
<Sidebar
title={"Rajasthan"}
solarForecastData={solarForecastData}
windForecastData={windForecastData}
solarGenerationData={solarGenerationData}
windGenerationData={windGenerationData}
/>
<Charts combinedData={combinedData} />
</main>
</HydrationBoundary>
);
}
},
{ returnTo: "/" }
);
1 change: 1 addition & 0 deletions apps/quartz-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@auth0/nextjs-auth0": "3.2.0",
"@babel/eslint-parser": "^7.18.9",
"@tanstack/react-query": "^5.20.2",
"eslint-config-prettier": "^8.5.0",
Expand Down
Loading

0 comments on commit f9a54bb

Please sign in to comment.