mirror of
https://github.com/fergalmoran/radio-otherway.git
synced 2025-12-22 09:50:29 +00:00
Fixed up profile page (WIP)
This commit is contained in:
13
.hintrc
Normal file
13
.hintrc
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": [
|
||||
"development"
|
||||
],
|
||||
"hints": {
|
||||
"axe/parsing": [
|
||||
"default",
|
||||
{
|
||||
"duplicate-id-aria": "off"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1068
.working/layout.html
Normal file
1068
.working/layout.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"turbo": "NODE_OPTIONS='-r next-logger' next dev --turbo",
|
||||
"dev": "NODE_OPTIONS='-r next-logger' node ./server.js",
|
||||
"debug": "node ./server.js",
|
||||
"dev-nossl": "next dev",
|
||||
@@ -28,7 +29,7 @@
|
||||
"firebase": "^9.17.1",
|
||||
"firebase-functions": "^4.2.1",
|
||||
"fireschema": "^4.0.4",
|
||||
"next": "13.2.0",
|
||||
"next": "^13.2.1",
|
||||
"next-logger": "^3.0.1",
|
||||
"next-seo": "^5.15.0",
|
||||
"pino": "^8.11.0",
|
||||
|
||||
21
src/app/error.tsx
Normal file
21
src/app/error.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
"use client";
|
||||
import logger from "@/lib/util/logging";
|
||||
import React from "react";
|
||||
|
||||
const ErrorPage = ({ error, reset }: { error: Error; reset: () => void }) => {
|
||||
React.useEffect(() => {
|
||||
// Log the error to an error reporting service
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
}, [error]);
|
||||
return (
|
||||
<div>
|
||||
<div>An error occurred: {error.message}</div>
|
||||
<button className="btn-danger btn" onClick={() => reset()}>
|
||||
Retry?
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorPage;
|
||||
@@ -2,12 +2,16 @@
|
||||
import React from "react";
|
||||
import { themeChange } from "theme-change";
|
||||
import "./globals.css";
|
||||
import { Inter } from "@next/font/google";
|
||||
import { Raleway } from "@next/font/google";
|
||||
import { NavBar } from "@/components/layout";
|
||||
import { AuthUserProvider } from "@/lib/auth/authUserContext";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
const font = Raleway({
|
||||
weight: ["400", "700"],
|
||||
subsets: ["latin"],
|
||||
variable: "--font-raleway",
|
||||
});
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
@@ -20,13 +24,15 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en">
|
||||
<head />
|
||||
<body>
|
||||
<body className={`${font.className}`}>
|
||||
<Toaster />
|
||||
<AuthUserProvider>
|
||||
<div className="w-full min-h-screen m-auto bg-base-100 text-base-content">
|
||||
<div className="flex flex-col min-h-screen p-5 mx-auto max-w-7xl">
|
||||
<Toaster />
|
||||
<div className="flex flex-col min-h-screen bg-base-100">
|
||||
<div className="sticky top-0 z-30 flex justify-center flex-none w-full h-16 transition-all duration-100 bg-opacity-90 text-primary-content backdrop-blur">
|
||||
<NavBar />
|
||||
<main className="flex-1">{children}</main>
|
||||
</div>
|
||||
<div className="-mt-[4rem] grow place-items-center items-end bg-gradient-to-br from-primary to-secondary pt-20 text-primary-content ">
|
||||
<main className="text-base-content">{children}</main>
|
||||
</div>
|
||||
</div>
|
||||
</AuthUserProvider>
|
||||
|
||||
@@ -1,68 +1,18 @@
|
||||
import RemindMeButton from "@/components/widgets/RemindMeButton";
|
||||
import { getMonthName, getTime } from "@/lib/util/dateUtils";
|
||||
import logger from "@/lib/util/logging";
|
||||
import { Show } from "@/models";
|
||||
import React from "react";
|
||||
import HomePageComponent from "@/components/pages/home/HomePageComponent";
|
||||
|
||||
const getData = async (): Promise<Show[]> => {
|
||||
const getData = async () => {
|
||||
// const res = await fetch(
|
||||
// `${process.env.NEXT_PUBLIC_API_URL}/api/shows/upcoming`
|
||||
// );
|
||||
const res = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_API_URL}/api/shows/upcoming`
|
||||
"https://otherway.dev.fergl.ie:3000/api/shows/upcoming"
|
||||
);
|
||||
logger.debug("getDate", res);
|
||||
const data = await res.json();
|
||||
return data.map((r: string) => Show.fromJson(r));
|
||||
return await res.json();
|
||||
};
|
||||
|
||||
const Home = async () => {
|
||||
const results = await getData();
|
||||
logger.debug("results", results);
|
||||
return results.length === 0 ? (
|
||||
<div className="min-h-screen hero bg-base-200">
|
||||
<div className="text-center hero-content">
|
||||
<div className="max-w-md">
|
||||
<h1 className="text-5xl font-bold">No upcoming shows found</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="container flex justify-center h-screen py-20 mx-auto">
|
||||
<div className="flex flex-col w-6/12 h-full pl-4">
|
||||
<div className="px-5 py-2 text-sm font-bold text-gray-500 bg-white border-b border-gray-300 shadow">
|
||||
Tracking events
|
||||
</div>
|
||||
<div
|
||||
className="w-full h-full overflow-auto bg-white shadow"
|
||||
id="journal-scroll"
|
||||
>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
{results &&
|
||||
results.map((show: Show) => (
|
||||
<tr
|
||||
key={show.id}
|
||||
className="relative py-1 transform scale-100 border-b-2 border-blue-100 cursor-default text-md"
|
||||
>
|
||||
<td className="pl-5 pr-3 whitespace-no-wrap">
|
||||
<div className="text-gray-400">
|
||||
{`${new Date(show.date).getDay()} ${getMonthName(show.date)}`}
|
||||
</div>
|
||||
<div>{getTime(show.date)}</div>
|
||||
</td>
|
||||
<td className="px-2 py-4 space-y-2 whitespace-no-wrap">
|
||||
<div className="font-medium leading-5 text-gray-500">
|
||||
{show.creator}
|
||||
</div>
|
||||
<div className="leading-5 text-gray-900">{show.title}</div>
|
||||
</td>
|
||||
<td className="px-2 py-4">
|
||||
<RemindMeButton showId={show.id} />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <HomePageComponent shows={results} />;
|
||||
};
|
||||
export default Home;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ProfilePageComponent } from "@/components/pages";
|
||||
import { ProfilePageComponent } from "@/components/pages/profile";
|
||||
|
||||
const ProfilePage = () => {
|
||||
return <ProfilePageComponent />;
|
||||
|
||||
@@ -9,6 +9,7 @@ const LoginPage = () => {
|
||||
useFirebaseAuth();
|
||||
const router = useRouter();
|
||||
const [error, setError] = React.useState("");
|
||||
const [forgot, setForgot] = React.useState(false);
|
||||
const [email, setEmail] = React.useState("");
|
||||
const [password, setPassword] = React.useState("");
|
||||
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { BiLogInCircle } from "react-icons/bi";
|
||||
import Link from "next/link";
|
||||
import useFirebaseAuth from "@/lib/auth/useFirebaseAuth";
|
||||
import { useAuthUserContext } from "@/lib/auth/authUserContext";
|
||||
import Image from "next/image";
|
||||
import { LogIn, LogOut, PlusSquare, Menu, User } from "react-feather";
|
||||
import dynamic from "next/dynamic";
|
||||
import Signup from "@/app/(auth)/signup/page";
|
||||
|
||||
const ThemeToggle = dynamic(
|
||||
() => import("@/components/widgets/ui/theme/ThemeToggle"),
|
||||
{
|
||||
ssr: false
|
||||
ssr: false,
|
||||
}
|
||||
);
|
||||
const Navbar = () => {
|
||||
@@ -22,18 +19,24 @@ const Navbar = () => {
|
||||
<Link
|
||||
href="/profile"
|
||||
id="profile"
|
||||
className="font-normal normal-case font-body btn-primary btn-sm btn"
|
||||
className="gap-1 normal-case btn-ghost btn"
|
||||
>
|
||||
<User size={12} className="mr-2" />
|
||||
<User
|
||||
size={20}
|
||||
className="inline-block w-5 h-5 stroke-current md:h-6 md:w-6"
|
||||
/>
|
||||
Profile
|
||||
</Link>
|
||||
<button
|
||||
id="logout-btn"
|
||||
className="btn-ghost btn-sm btn"
|
||||
tabIndex={0}
|
||||
className="gap-1 normal-case btn-ghost btn"
|
||||
onClick={() => logOut()}
|
||||
>
|
||||
<LogOut size={12} className="mr-2" />
|
||||
Logout
|
||||
<LogOut
|
||||
size={20}
|
||||
className="inline-block w-5 h-5 stroke-current md:h-6 md:w-6"
|
||||
/>
|
||||
<span className="hidden md:inline">Logout</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
@@ -46,8 +49,15 @@ const Navbar = () => {
|
||||
<PlusSquare size={12} className="mr-2" />
|
||||
Register
|
||||
</Link>
|
||||
<Link href="/login" id="login" className="btn-ghost btn-sm btn">
|
||||
<LogIn size={12} className="mr-2" />
|
||||
<Link
|
||||
href="/login"
|
||||
id="login"
|
||||
className="gap-1 normal-case btn-ghost btn"
|
||||
>
|
||||
<LogIn
|
||||
size={20}
|
||||
className="inline-block w-5 h-5 stroke-current md:h-6 md:w-6"
|
||||
/>
|
||||
Login
|
||||
</Link>
|
||||
</React.Fragment>
|
||||
@@ -59,7 +69,7 @@ const Navbar = () => {
|
||||
<Image src="/logo.png" alt="Otherway" width={48} height={48} />
|
||||
</Link>
|
||||
<div className="flex-col hidden ml-auto text-sm text-center font-body md:flex md:flex-row md:space-x-10">
|
||||
{NavMenu}
|
||||
{!loading && NavMenu}
|
||||
</div>
|
||||
<ThemeToggle />
|
||||
|
||||
|
||||
35
src/components/pages/home/HomePageComponent.tsx
Normal file
35
src/components/pages/home/HomePageComponent.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import Loading from "@/app/loading";
|
||||
import { RemindMeButton } from "@/components/widgets";
|
||||
import { getMonthName, getTime } from "@/lib/util/dateUtils";
|
||||
import { Show } from "@/models";
|
||||
import React from "react";
|
||||
import NoShows from "./NoShows";
|
||||
import UpcomingShowsTable from "./UpcomingShowsTable";
|
||||
|
||||
interface IHomePageComponentProps {
|
||||
shows: Show[] | undefined;
|
||||
}
|
||||
const HomePageComponent = ({ shows }: IHomePageComponentProps) => {
|
||||
const _getLayout = () => {
|
||||
if (!shows) {
|
||||
return <Loading />;
|
||||
}
|
||||
if (shows.length === 0) {
|
||||
return <NoShows />;
|
||||
}
|
||||
return (
|
||||
<div className="h-full pt-4 overflow-hidden">
|
||||
<div className="justify-center flex-1 px-2 mx-2 md:flex md:justify-start">
|
||||
<span className="text-2xl font-bold">Upcoming events</span>
|
||||
</div>
|
||||
<div className="mt-1 divider" />
|
||||
<div className="flex justify-center mx-6 mt-4" id="journal-scroll">
|
||||
<UpcomingShowsTable shows={shows} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
return _getLayout();
|
||||
};
|
||||
|
||||
export default HomePageComponent;
|
||||
15
src/components/pages/home/NoShows.tsx
Normal file
15
src/components/pages/home/NoShows.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from "react";
|
||||
|
||||
const NoShows = () => {
|
||||
return (
|
||||
<div className="flex items-center justify-center flex-grow -mt-32">
|
||||
<div className="text-center ">
|
||||
<div className="max-w-md">
|
||||
<h1 className="text-5xl font-bold">No upcoming shows found</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NoShows;
|
||||
44
src/components/pages/home/UpcomingShowsTable.tsx
Normal file
44
src/components/pages/home/UpcomingShowsTable.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import { RemindMeButton } from "@/components/widgets";
|
||||
import { getMonthName, getTime } from "@/lib/util/dateUtils";
|
||||
import { Show } from "@/models";
|
||||
|
||||
interface IUpcomingShowsTableProps {
|
||||
shows: Show[];
|
||||
}
|
||||
const UpcomingShowsTable = ({ shows }: IUpcomingShowsTableProps) => {
|
||||
return (
|
||||
<table className="table w-full">
|
||||
{/* head */}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Who?</th>
|
||||
<th>When?</th>
|
||||
<th>What?</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{/* row 1 */}
|
||||
{shows &&
|
||||
shows.map((show: Show) => (
|
||||
<tr key={show.id}>
|
||||
<th>{show.creator}</th>
|
||||
<td className="pl-5 pr-3 whitespace-no-wrap">
|
||||
<div className="text-gray-400">
|
||||
{`${new Date(show.date).getDay()} ${getMonthName(show.date)}`}{" "}
|
||||
@ {getTime(show.date)}
|
||||
</div>
|
||||
</td>
|
||||
<td>{show.title}</td>
|
||||
<th>
|
||||
<RemindMeButton showId={show.id} />
|
||||
</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpcomingShowsTable;
|
||||
0
src/components/pages/home/index.ts
Normal file
0
src/components/pages/home/index.ts
Normal file
@@ -4,11 +4,9 @@ import { useRouter } from "next/navigation";
|
||||
import { User, Bell } from "react-feather";
|
||||
import classNames from "classnames";
|
||||
import { useAuthUserContext } from "@/lib/auth/authUserContext";
|
||||
import useFirebaseAuth from "@/lib/auth/useFirebaseAuth";
|
||||
import { ImageUpload, InputText } from "../widgets/inputs";
|
||||
import { HeadingSubComponent } from "../widgets/text";
|
||||
import ProfilePageComponentProfile from "./ProfilePageComponentProfile";
|
||||
import ProfilePageComponentNotifications from "./ProfilePageComponentNotifications";
|
||||
|
||||
const ProfilePageComponent = () => {
|
||||
const { profile, loading } = useAuthUserContext();
|
||||
const router = useRouter();
|
||||
@@ -42,8 +40,11 @@ const ProfilePageComponent = () => {
|
||||
return <div>Rerouting</div>;
|
||||
} else if (!loading && profile) {
|
||||
return (
|
||||
<div className="overflow-hidden rounded-lg shadow bg-base-100 text-base-content">
|
||||
<h1>{selectedItem}</h1>
|
||||
<div className="pt-4 overflow-hidden">
|
||||
<div className="justify-center flex-1 px-2 mx-2 md:flex md:justify-start">
|
||||
<span className="text-2xl font-bold">Your Profile</span>
|
||||
</div>
|
||||
<div className="mt-1 divider" />
|
||||
<div className="divide-y lg:grid lg:grid-cols-12 lg:divide-y-0 lg:divide-x">
|
||||
<aside className="py-6 lg:col-span-3">
|
||||
<nav className="space-y-1">
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from "react";
|
||||
import { HeadingSubComponent } from "@/components/widgets/text";
|
||||
import { InputText } from "@/components/widgets/inputs";
|
||||
import { PhoneNumberContextImpl } from "twilio/lib/rest/lookups/v2/phoneNumber";
|
||||
import { PhoneNumber } from "../widgets/notifications";
|
||||
import { PhoneNumber } from "@/components/widgets/notifications";
|
||||
|
||||
const ProfilePageComponentNotifications = () => {
|
||||
return (
|
||||
@@ -1,18 +1,47 @@
|
||||
"use client";
|
||||
import { InputText } from "@/components/widgets/inputs";
|
||||
import { HeadingSubComponent } from "@/components/widgets/text";
|
||||
import { useAuthUserContext } from "@/lib/auth/authUserContext";
|
||||
import db, { users } from "@/lib/db";
|
||||
import { debug } from "console";
|
||||
import { doc, setDoc } from "firebase/firestore";
|
||||
import React from "react";
|
||||
import { InputText } from "../widgets/inputs";
|
||||
import { HeadingSubComponent } from "../widgets/text";
|
||||
const ProfilePageComponentProfile = () => {
|
||||
const { loading, profile } = useAuthUserContext();
|
||||
const [sendReminders, setSendReminders] = React.useState(false);
|
||||
const [userName, setUserName] = React.useState("");
|
||||
const [email, setEmail] = React.useState("");
|
||||
const [password, setPassword] = React.useState("");
|
||||
const [about, setAbout] = React.useState("");
|
||||
const [displayName, setDisplayName] = React.useState("");
|
||||
const [url, setUrl] = React.useState("");
|
||||
const [image, setImage] = React.useState("");
|
||||
React.useEffect(() => {
|
||||
console.log("ProfilePageComponentProfile", "useEffect", profile);
|
||||
if (profile) {
|
||||
setEmail(profile.email as string);
|
||||
setDisplayName(profile.displayName as string);
|
||||
setAbout(profile.about as string);
|
||||
}
|
||||
}, [profile]);
|
||||
const _submitProfileForm = async ($event: React.SyntheticEvent) => {
|
||||
$event.preventDefault();
|
||||
const result = await setDoc(
|
||||
doc(users, profile?.id),
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
email,
|
||||
displayName,
|
||||
about: about || "",
|
||||
lastSeen: new Date(),
|
||||
}
|
||||
),
|
||||
{ merge: true }
|
||||
);
|
||||
console.log("ProfilePageComponentProfile", "_submitProfileForm", result);
|
||||
};
|
||||
return (
|
||||
<form className="space-y-8 divide-y ">
|
||||
<form className="space-y-8 divide-y" onSubmit={_submitProfileForm}>
|
||||
<div className="space-y-8 divide-y sm:space-y-5">
|
||||
<div>
|
||||
<div>
|
||||
@@ -22,20 +51,22 @@ const ProfilePageComponentProfile = () => {
|
||||
share.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 space-y-6 sm:mt-5 sm:space-y-5">
|
||||
<div className="space-x-3 sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:border-t sm:pt-5">
|
||||
<HeadingSubComponent
|
||||
title="Username"
|
||||
subHeading="The username that you would like to use to login to the site. This could be your email address"
|
||||
title="Display Name"
|
||||
subHeading="The name you would like others to see you as."
|
||||
/>
|
||||
<div className="mt-1 sm:col-span-2 sm:mt-0">
|
||||
<div className="flex max-w-lg rounded-md shadow-sm">
|
||||
<InputText
|
||||
id="username"
|
||||
labelTitle="Username"
|
||||
defaultValue={userName}
|
||||
updateFormValue={(v) => setUserName(v)}
|
||||
id="displayname"
|
||||
type="text"
|
||||
labelTitle="Display name"
|
||||
value={displayName}
|
||||
updateFormValue={(v) => {
|
||||
setDisplayName(v);
|
||||
}}
|
||||
showLabel={false}
|
||||
/>
|
||||
</div>
|
||||
@@ -52,7 +83,7 @@ const ProfilePageComponentProfile = () => {
|
||||
id="email"
|
||||
type="email"
|
||||
labelTitle="Email address"
|
||||
defaultValue={email}
|
||||
value={email}
|
||||
updateFormValue={(v) => setEmail(v)}
|
||||
showLabel={false}
|
||||
/>
|
||||
@@ -71,7 +102,7 @@ const ProfilePageComponentProfile = () => {
|
||||
id="about"
|
||||
type="textarea"
|
||||
labelTitle="About"
|
||||
defaultValue={about}
|
||||
value={about}
|
||||
updateFormValue={(v) => setAbout(v)}
|
||||
showLabel={false}
|
||||
/>
|
||||
@@ -6,7 +6,7 @@ interface IInputTextProps {
|
||||
labelStyle?: string;
|
||||
type?: string;
|
||||
containerStyle?: string;
|
||||
defaultValue: string;
|
||||
value: string;
|
||||
placeholder?: string;
|
||||
showLabel?: boolean;
|
||||
updateFormValue: (value: string) => void;
|
||||
@@ -17,15 +17,13 @@ const InputText = ({
|
||||
labelStyle,
|
||||
type,
|
||||
containerStyle,
|
||||
defaultValue,
|
||||
value,
|
||||
placeholder,
|
||||
updateFormValue,
|
||||
showLabel = true,
|
||||
}: IInputTextProps) => {
|
||||
const [value, setValue] = React.useState(defaultValue);
|
||||
|
||||
const updateInputValue = (val: string) => {
|
||||
setValue(val);
|
||||
updateFormValue(val);
|
||||
};
|
||||
const _getId = () => (type === "text" ? `inp_${id}` : `ta_${id}`);
|
||||
@@ -36,16 +34,18 @@ const InputText = ({
|
||||
name={_getId()}
|
||||
rows={3}
|
||||
className="w-full h-24 textarea-bordered textarea"
|
||||
defaultValue={defaultValue}
|
||||
placeholder={placeholder || ""}
|
||||
defaultValue={value}
|
||||
onChange={(e) => updateInputValue(e.target.value)}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
id={_getId()}
|
||||
type={type || "text"}
|
||||
value={value}
|
||||
placeholder={placeholder || ""}
|
||||
onChange={(e) => updateInputValue(e.target.value)}
|
||||
className="w-full input-bordered input"
|
||||
type={type || "text"}
|
||||
placeholder={placeholder || ""}
|
||||
value={value}
|
||||
onChange={(e) => updateInputValue(e.target.value)}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import {
|
||||
createUserWithEmailAndPassword,
|
||||
FacebookAuthProvider,
|
||||
getAuth,
|
||||
GoogleAuthProvider, linkWithPopup, OAuthProvider,
|
||||
GoogleAuthProvider,
|
||||
linkWithPopup,
|
||||
OAuthProvider,
|
||||
onAuthStateChanged,
|
||||
signInWithEmailAndPassword,
|
||||
signInWithPopup, signInWithRedirect,
|
||||
signInWithPopup,
|
||||
signOut,
|
||||
TwitterAuthProvider, UserCredential
|
||||
TwitterAuthProvider,
|
||||
UserCredential,
|
||||
} from "firebase/auth";
|
||||
import { app } from "./firebase";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Profile } from "@/models";
|
||||
import { FirebaseAuth } from "@firebase/auth-types";
|
||||
import firebase from "firebase/app";
|
||||
|
||||
import { users } from "../db";
|
||||
import { doc, setDoc } from "firebase/firestore";
|
||||
|
||||
export default function useFirebaseAuth() {
|
||||
const [profile, setProfile] = useState<Profile | undefined>();
|
||||
@@ -24,7 +26,7 @@ export default function useFirebaseAuth() {
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const getUserProfile = (): Profile | undefined => {
|
||||
const getUserProfile = useCallback(() => {
|
||||
if (auth.currentUser !== null) {
|
||||
// The user object has basic properties such as display name, email, etc.
|
||||
// Going forward we may look this up from the user table in firestore
|
||||
@@ -33,36 +35,43 @@ export default function useFirebaseAuth() {
|
||||
auth.currentUser.email,
|
||||
auth.currentUser.displayName,
|
||||
auth.currentUser.photoURL,
|
||||
auth.currentUser.emailVerified
|
||||
auth.currentUser.emailVerified,
|
||||
new Date()
|
||||
);
|
||||
setProfile(profile);
|
||||
setDoc(doc(users, auth.currentUser.uid), Object.assign({}, profile), {
|
||||
merge: true,
|
||||
});
|
||||
return profile;
|
||||
}
|
||||
};
|
||||
const authStateChanged = async (user: any) => {
|
||||
if (user) {
|
||||
}, [auth.currentUser]);
|
||||
const authStateChanged = useCallback(
|
||||
(user: any) => {
|
||||
if (user) {
|
||||
setLoading(true);
|
||||
const profile = getUserProfile();
|
||||
setProfile(profile);
|
||||
}
|
||||
setLoading(false);
|
||||
const profile = getUserProfile();
|
||||
setProfile(profile);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
[getUserProfile]
|
||||
);
|
||||
const clear = () => {
|
||||
setProfile(undefined);
|
||||
setLoading(true);
|
||||
};
|
||||
|
||||
const signIn = (email: string, password: string): Promise<> =>
|
||||
const signIn = (email: string, password: string) =>
|
||||
signInWithEmailAndPassword(auth, email, password);
|
||||
|
||||
const signUp = (email: string, password: string) =>
|
||||
createUserWithEmailAndPassword(auth, email, password);
|
||||
|
||||
const logOut = () =>
|
||||
signOut(auth).then(clear);
|
||||
const logOut = () => signOut(auth).then(clear);
|
||||
|
||||
const _processSignIn = async (provider: any): Promise<UserCredential | undefined> => {
|
||||
const _processSignIn = async (
|
||||
provider: any
|
||||
): Promise<UserCredential | undefined> => {
|
||||
try {
|
||||
const result = await signInWithPopup(auth, provider);
|
||||
return result;
|
||||
@@ -73,12 +82,20 @@ export default function useFirebaseAuth() {
|
||||
console.log("useFirebaseAuth", "_processSignIn_duplicateAccount", err);
|
||||
const auth = getAuth();
|
||||
if (auth?.currentUser) {
|
||||
linkWithPopup(auth.currentUser, provider).then((result) => {
|
||||
const credential = GoogleAuthProvider.credentialFromResult(result);
|
||||
return credential;
|
||||
}).catch((error) => {
|
||||
console.log("useFirebaseAuth", "_processSignIn", "Failure in _processSignIn", err);
|
||||
});
|
||||
linkWithPopup(auth.currentUser, provider)
|
||||
.then((result) => {
|
||||
const credential =
|
||||
GoogleAuthProvider.credentialFromResult(result);
|
||||
return credential;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(
|
||||
"useFirebaseAuth",
|
||||
"_processSignIn",
|
||||
"Failure in _processSignIn",
|
||||
err
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +131,7 @@ export default function useFirebaseAuth() {
|
||||
useEffect(() => {
|
||||
const unsubscribe = onAuthStateChanged(auth, authStateChanged);
|
||||
return unsubscribe;
|
||||
}, []);
|
||||
}, [auth, getUserProfile]);
|
||||
|
||||
return {
|
||||
profile,
|
||||
@@ -125,6 +142,6 @@ export default function useFirebaseAuth() {
|
||||
signInWithGoogle,
|
||||
signInWithTwitter,
|
||||
signInWithFacebook,
|
||||
getUserProfile
|
||||
getUserProfile,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const defaults = {
|
||||
defaultTheme: "fantasy",
|
||||
defaultTheme: "synthwave",
|
||||
defaultDarkTheme: "luxury",
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import serviceAccount from "serviceAccount.json";
|
||||
import { initializeApp } from "firebase/app";
|
||||
import {
|
||||
getFirestore,
|
||||
@@ -6,7 +5,9 @@ import {
|
||||
collection,
|
||||
DocumentData,
|
||||
WithFieldValue,
|
||||
QueryDocumentSnapshot, SnapshotOptions, Timestamp
|
||||
QueryDocumentSnapshot,
|
||||
SnapshotOptions,
|
||||
Timestamp,
|
||||
} from "firebase/firestore";
|
||||
|
||||
const firebaseConfig = {
|
||||
@@ -16,7 +17,7 @@ const firebaseConfig = {
|
||||
storageBucket: "radio-otherway.appspot.com",
|
||||
messagingSenderId: "47147490249",
|
||||
appId: "1:47147490249:web:a84515b3ce1c481826e618",
|
||||
measurementId: "G-12YB78EZM4"
|
||||
measurementId: "G-12YB78EZM4",
|
||||
};
|
||||
export const firebaseApp = initializeApp(firebaseConfig);
|
||||
const firestore = getFirestore();
|
||||
@@ -27,7 +28,9 @@ const showConverter = {
|
||||
toFirestore(show: WithFieldValue<Show>): DocumentData {
|
||||
return {
|
||||
...show,
|
||||
date: Timestamp.fromDate(<Date>show.date)
|
||||
date: show.date
|
||||
? Timestamp.fromDate(new Date(show.date as string))
|
||||
: new Date(),
|
||||
};
|
||||
},
|
||||
fromFirestore(
|
||||
@@ -35,20 +38,18 @@ const showConverter = {
|
||||
options: SnapshotOptions
|
||||
): Show {
|
||||
const data = snapshot.data(options)!;
|
||||
return new Show(
|
||||
snapshot.id,
|
||||
data.title,
|
||||
data.date.toDate(),
|
||||
data.creator);
|
||||
}
|
||||
return new Show(snapshot.id, data.title, data.date.toDate(), data.creator);
|
||||
},
|
||||
};
|
||||
|
||||
// Import all your model types
|
||||
import { Show, Reminder, RemindersProcessed } from "@/models";
|
||||
import { Show, Reminder, RemindersProcessed, Profile } from "@/models";
|
||||
// export all your collections
|
||||
|
||||
export const shows = createCollection<Show>("shows")
|
||||
.withConverter(showConverter);
|
||||
export const users = createCollection<Profile>("users");
|
||||
export const shows =
|
||||
createCollection<Show>("shows").withConverter(showConverter);
|
||||
export const reminders = createCollection<Reminder>("reminders");
|
||||
export const remindersProcessed = createCollection<RemindersProcessed>("reminders");
|
||||
export const remindersProcessed =
|
||||
createCollection<RemindersProcessed>("reminders");
|
||||
export default firestore;
|
||||
|
||||
@@ -4,12 +4,22 @@ export default class Profile {
|
||||
displayName: string | null;
|
||||
photoURL: string | null;
|
||||
emailVerified: boolean;
|
||||
|
||||
constructor(id: string, email: string | null, displayName: string | null, photoURL: string | null, emailVerified: boolean) {
|
||||
about?: String;
|
||||
lastSeen: Date;
|
||||
constructor(
|
||||
id: string,
|
||||
email: string | null,
|
||||
displayName: string | null,
|
||||
photoURL: string | null,
|
||||
emailVerified: boolean,
|
||||
lastSeen?: Date
|
||||
) {
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
this.displayName = displayName;
|
||||
this.photoURL = photoURL;
|
||||
this.emailVerified = emailVerified;
|
||||
|
||||
this.lastSeen = lastSeen || new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
}, { merge: true });
|
||||
}
|
||||
logger.debug("Stored show", res);
|
||||
res.status(200).json({ status: "OK" });
|
||||
res.status(200).json({ status: "OK", entries });
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
res.status(500).json({status: "Error"});
|
||||
|
||||
@@ -32,7 +32,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const reminder = r.data() as Reminder;
|
||||
for (let notification of reminder.notifications) {
|
||||
const targetDate = addSeconds(new Date(), notification.secondsBefore);
|
||||
const differenceInSeconds = dateDifferenceInSeconds(targetDate, show.date);
|
||||
const differenceInSeconds = dateDifferenceInSeconds(targetDate, new Date(show.date));
|
||||
if (differenceInSeconds >= 0) {
|
||||
//time to fire off a notification
|
||||
await sendSMS("353868065119", "New show starting in 1 hour");
|
||||
|
||||
@@ -11,7 +11,7 @@ module.exports = {
|
||||
// ],
|
||||
plugins: [require("daisyui")],
|
||||
daisyui: {
|
||||
themes: ["fantasy", "luxury"],
|
||||
// themes: ["fantasy", "luxury", "synthwave"],
|
||||
darkTheme: "luxury",
|
||||
},
|
||||
};
|
||||
|
||||
183
yarn.lock
183
yarn.lock
@@ -488,10 +488,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@next/env@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-13.2.0.tgz#1a597a885ce11860446c88e1098fd517dc0e84b1"
|
||||
integrity sha512-yv9oaRVa+AxFa27uQOVecS931NrE+GcQSqcL2HaRxL8NunStLtPiyNm/VixvdzfiWLabMz4dXvbXfwCNaECzcw==
|
||||
"@next/env@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-13.2.1.tgz#082d42cfc0c794e9185d7b4133d71440ba2e795d"
|
||||
integrity sha512-Hq+6QZ6kgmloCg8Kgrix+4F0HtvLqVK3FZAnlAoS0eonaDemHe1Km4kwjSWRE3JNpJNcKxFHF+jsZrYo0SxWoQ==
|
||||
|
||||
"@next/eslint-plugin-next@13.1.5":
|
||||
version "13.1.5"
|
||||
@@ -505,70 +505,70 @@
|
||||
resolved "https://registry.yarnpkg.com/@next/font/-/font-13.2.0.tgz#677b3fc67243bccbae94d7d1e96a494be98206c4"
|
||||
integrity sha512-pWoegIxqegV+9+gFmRCZao6xhA2m3kKS34lMXqShJ5ibRuyHkP/tfDE82LzYZmVQ3p51ZrkwTugNwy/ohiE2cA==
|
||||
|
||||
"@next/swc-android-arm-eabi@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.0.tgz#241d007fdb2f06f70ab21d5a333e08a29de9cd7f"
|
||||
integrity sha512-VMetUwBWtDBGzNiOkhiWTP+99ZYW5NVRpIGlUsldEtY8IQIqleaUgW9iamsO0kDSjhWNdCQCB+xu5HcCvmDTww==
|
||||
"@next/swc-android-arm-eabi@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.1.tgz#67f2580fbbe05ee006220688972c5e3a555fc741"
|
||||
integrity sha512-Yua7mUpEd1wzIT6Jjl3dpRizIfGp9NR4F2xeRuQv+ae+SDI1Em2WyM9m46UL+oeW5GpMiEHoaBagr47RScZFmQ==
|
||||
|
||||
"@next/swc-android-arm64@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.2.0.tgz#924e79197f094a12ac3409b6a416f84c2f74341d"
|
||||
integrity sha512-fAiP54Om3fSj5aKntxEvW5fWzyMUzLzjFrHuUt5jBnTRWM4QikhLy547OZDoxycyk4GoQVHmNMSA3hILsrV/dQ==
|
||||
"@next/swc-android-arm64@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.2.1.tgz#460a02b69eb23bb5f402266bcea9cadae59415c1"
|
||||
integrity sha512-Bifcr2f6VwInOdq1uH/9lp8fH7Nf7XGkIx4XceVd32LPJqG2c6FZU8ZRBvTdhxzXVpt5TPtuXhOP4Ij9UPqsVw==
|
||||
|
||||
"@next/swc-darwin-arm64@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.0.tgz#bfd3dfe90903b3bbf81f617f2b1d4f8b9e20e8aa"
|
||||
integrity sha512-F4zbvPnq3zCTqyyM6WN8ledazzJx3OrxIdc2ewnqnfk6tjBZ/aq1M27GhEfylGjZG1KvbtJCxUqi7dR/6R94bA==
|
||||
"@next/swc-darwin-arm64@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.1.tgz#8b8530ff417802027471aee2419f78a58a863ccb"
|
||||
integrity sha512-gvqm+fGMYxAkwBapH0Vvng5yrb6HTkIvZfY4oEdwwYrwuLdkjqnJygCMgpNqIFmAHSXgtlWxfYv1VC8sjN81Kw==
|
||||
|
||||
"@next/swc-darwin-x64@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.2.0.tgz#3d159bb2889f093d173546a6e5edd6260df7e156"
|
||||
integrity sha512-Y9+fB7TLAAnkCZQXWjwJg5bi1pT5NuNkI+HoKYp26U1J0SxW5vZWFGc31WFmmHIz3wA0zlaQfRa4mF7cpZL5yw==
|
||||
"@next/swc-darwin-x64@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.2.1.tgz#80aebb3329a1e4568a28de1ee177780b3d50330c"
|
||||
integrity sha512-HGqVqmaZWj6zomqOZUVbO5NhlABL0iIaxTmd0O5B0MoMa5zpDGoaHSG+fxgcWMXcGcxmUNchv1NfNOYiTKoHOg==
|
||||
|
||||
"@next/swc-freebsd-x64@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.2.0.tgz#33877ad933e1b3d7776dfb060f4e3b55f675523e"
|
||||
integrity sha512-b9bCLlfznbV6e6Vg9wKYZJs7Uz8z/Py9105MYq95a3JlHiI3e/fvBpm1c7fe5QlvWJlqyNav6Clyu1W+lDk+IQ==
|
||||
"@next/swc-freebsd-x64@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.2.1.tgz#250ea2ab7e1734f22d11c677c463fab9ac33a516"
|
||||
integrity sha512-N/a4JarAq+E+g+9K2ywJUmDIgU2xs2nA+BBldH0oq4zYJMRiUhL0iaN9G4e72VmGOJ61L/3W6VN8RIUOwTLoqQ==
|
||||
|
||||
"@next/swc-linux-arm-gnueabihf@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.2.0.tgz#31b81ff368e5337019f858c4a0d7ae7f80310728"
|
||||
integrity sha512-jY/2JjDVVyktzRtMclAIVLgOxk5Ut9NKu8kKMCPdKMf9/ila37UpRfIh2fOXtRhv8AK7Lq/iSI/v2vjopZxZgQ==
|
||||
"@next/swc-linux-arm-gnueabihf@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.2.1.tgz#fe6bb29ed348a5f8ecae3740df22a8d8130c474a"
|
||||
integrity sha512-WaFoerF/eRbhbE57TaIGJXbQAERADZ/RZ45u6qox9beb5xnWsyYgzX+WuN7Tkhyvga0/aMuVYFzS9CEay7D+bw==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.2.0.tgz#e46bd73d1ccc38be46009b88dc87df88d8c44fa1"
|
||||
integrity sha512-EKjWU3/lSBhOwPQRQLbySUnATnXygCjGd8ag3rP6d7kTIhfuPO4pY+DYW+wHOt5qB1ULNRmW0sXZ/ZKnQrVszw==
|
||||
"@next/swc-linux-arm64-gnu@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.2.1.tgz#4781b927fc5e421f3cea2b29e5d38e5e4837b198"
|
||||
integrity sha512-R+Jhc1/RJTnncE9fkePboHDNOCm1WJ8daanWbjKhfPySMyeniKYRwGn5SLYW3S8YlRS0QVdZaaszDSZWgUcsmA==
|
||||
|
||||
"@next/swc-linux-arm64-musl@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.2.0.tgz#54a4f0cc1431f3e4e24a5e017e473a5fc761b33b"
|
||||
integrity sha512-T5R9r23Docwo6PYZRzndeFB5WUN3+smMbyk25K50MAngCiSydr82/YfAetcp7Ov7Shp4a8xXP9DHDIsBas6wbQ==
|
||||
"@next/swc-linux-arm64-musl@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.2.1.tgz#c2ba0a121b0255ba62450916bc70e6d0e26cbc98"
|
||||
integrity sha512-oI1UfZPidGAVddlL2eOTmfsuKV9EaT1aktIzVIxIAgxzQSdwsV371gU3G55ggkurzfdlgF3GThFePDWF0d8dmw==
|
||||
|
||||
"@next/swc-linux-x64-gnu@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.0.tgz#1c17a6121846decac2d701a040649f8f764ac671"
|
||||
integrity sha512-FeXTc2KFvUSnTJmkpNMKoBHmNA1Ujr3QdfcKnVm/gXWqK+rfuEhAiRNOo+6mPcQ0noEge1j8Ai+W1LTbdDwPZQ==
|
||||
"@next/swc-linux-x64-gnu@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.1.tgz#573c220f8b087e5d131d1fba58d3e1a670b220ad"
|
||||
integrity sha512-PCygPwrQmS+7WUuAWWioWMZCzZm4PG91lfRxToLDg7yIm/3YfAw5N2EK2TaM9pzlWdvHQAqRMX/oLvv027xUiA==
|
||||
|
||||
"@next/swc-linux-x64-musl@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.0.tgz#a4f39cfeb19123196a2ebc2061e60897b29ffa3f"
|
||||
integrity sha512-7Y0XMUzWDWI94pxC0xWGMWrgTFKHu/myc+GTNVEwvLtI9WA0brKqZrL1tCQW/+t6J+5XqS7w+AHbViaF+muu1A==
|
||||
"@next/swc-linux-x64-musl@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.1.tgz#950b5bb920b322ca7b447efbd12a9c7a10c3a642"
|
||||
integrity sha512-sUAKxo7CFZYGHNxheGh9nIBElLYBM6md/liEGfOTwh/xna4/GTTcmkGWkF7PdnvaYNgcPIQgHIMYiAa6yBKAVw==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.2.0.tgz#d21ef0d0c2757cee9b1d723aafb9e02ca25852eb"
|
||||
integrity sha512-NM5h2gEMe8EtvOeRU3vRM83tq1xo6Qvhuz0xJem/176SAMxbqzAz4LLP3l9VyUI3SIzGyiztvF/1c0jqeq7UEA==
|
||||
"@next/swc-win32-arm64-msvc@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.2.1.tgz#dbff3c4f5a3812a7059dac05804148a0f98682db"
|
||||
integrity sha512-qDmyEjDBpl/vBXxuOOKKWmPQOcARcZIMach1s7kjzaien0SySut/PHRlj56sosa81Wt4hTGhfhZ1R7g1n7+B8w==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.2.0.tgz#529852721e3f00afb9385640cbac1a899342c6ba"
|
||||
integrity sha512-G7YEJZX9wkcUaBOvXQSCF9Wb2sqP8hhsmFXF6po7M3llw4b+2ut2DXLf+UMdthOdUK0u+Ijhy5F7SbW9HOn2ig==
|
||||
"@next/swc-win32-ia32-msvc@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.2.1.tgz#7d2c17be7b8d9963984f5c15cc2588127101f620"
|
||||
integrity sha512-2joqFQ81ZYPg6DcikIzQn3DgjKglNhPAozx6dL5sCNkr1CPMD0YIkJgT3CnYyMHQ04Qi3Npv0XX3MD6LJO8OCA==
|
||||
|
||||
"@next/swc-win32-x64-msvc@13.2.0":
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.0.tgz#49bc50b1865d20b29892a415fcbaab84217112a5"
|
||||
integrity sha512-QTAjSuPevnZnlHfC4600+4NvxRuPar6tWdYbPum9vnk3OIH1xu9YLK+2ArPGFd0bB2K8AoY2SIMbs1dhK0GjQQ==
|
||||
"@next/swc-win32-x64-msvc@13.2.1":
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.1.tgz#09713c6a925461f414e89422851326d1625bd4d2"
|
||||
integrity sha512-r3+0fSaIZT6N237iMzwUhfNwjhAFvXjqB+4iuW+wcpxW+LHm1g/IoxN8eSRcb8jPItC86JxjAxpke0QL97qd6g==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
@@ -770,7 +770,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
|
||||
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
|
||||
|
||||
"@types/node@*", "@types/node@18.14.1", "@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
||||
"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
||||
version "18.14.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.2.tgz#c076ed1d7b6095078ad3cf21dfeea951842778b1"
|
||||
integrity sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==
|
||||
|
||||
"@types/node@18.14.1":
|
||||
version "18.14.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.1.tgz#90dad8476f1e42797c49d6f8b69aaf9f876fc69f"
|
||||
integrity sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==
|
||||
@@ -1215,9 +1220,9 @@ camelcase-css@^2.0.1:
|
||||
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
|
||||
|
||||
caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449:
|
||||
version "1.0.30001457"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301"
|
||||
integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==
|
||||
version "1.0.30001458"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c"
|
||||
integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
@@ -1353,9 +1358,9 @@ cookie@0.5.0:
|
||||
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
|
||||
|
||||
core-js@^3.1.3:
|
||||
version "3.28.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.28.0.tgz#ed8b9e99c273879fdfff0edfc77ee709a5800e4a"
|
||||
integrity sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==
|
||||
version "3.29.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6"
|
||||
integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==
|
||||
|
||||
cors@^2.8.5:
|
||||
version "2.8.5"
|
||||
@@ -1404,9 +1409,9 @@ csstype@^3.0.2:
|
||||
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
||||
|
||||
daisyui@^2.49.0:
|
||||
version "2.51.0"
|
||||
resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-2.51.0.tgz#7ed95786a27a4ea044f14dc6b1423f98acb213bc"
|
||||
integrity sha512-HGM89+VzZ/KDsH4cK6OhizIscXOVzkEENynovL6bXPfJDOKZQz0V2CuTGEoQmN8FeuGxrZiz/He1P9p+E9Qr5A==
|
||||
version "2.51.1"
|
||||
resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-2.51.1.tgz#20fe01f3f3caa8628ebb30fcc1b99341183d1702"
|
||||
integrity sha512-rMtdB8Rh8Ghd3+FDlMe63Caw+IopKIf7tviJGEx8gkjj5H+RCvU1bEbjx6DHsMsu477Gv5aafrLIdoUL+iMRrw==
|
||||
dependencies:
|
||||
color "^4.2"
|
||||
css-selector-tokenizer "^0.8.0"
|
||||
@@ -2826,7 +2831,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
|
||||
|
||||
json5@^1.0.1:
|
||||
json5@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
|
||||
@@ -3086,30 +3091,30 @@ next-seo@^5.15.0:
|
||||
resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-5.15.0.tgz#b1a90508599774982909ea44803323c6fb7b50f4"
|
||||
integrity sha512-LGbcY91yDKGMb7YI+28n3g+RuChUkt6pXNpa8FkfKkEmNiJkeRDEXTnnjVtwT9FmMhG6NH8qwHTelGrlYm9rgg==
|
||||
|
||||
next@13.2.0:
|
||||
version "13.2.0"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-13.2.0.tgz#100b2d1dca120a3460c767ccdad80fc8e2463e31"
|
||||
integrity sha512-vhByvKHedsaMwNTwXKzK4IMmNp7XI7vN4etcGUoIpLrIuDfoYA3bS0ImS4X9F6lKzopG5aVp7a1CjuzF2NGkvA==
|
||||
next@^13.2.1:
|
||||
version "13.2.1"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-13.2.1.tgz#34d823f518632b36379863228ed9f861c335b9c0"
|
||||
integrity sha512-qhgJlDtG0xidNViJUPeQHLGJJoT4zDj/El7fP3D3OzpxJDUfxsm16cK4WTMyvSX1ciIfAq05u+0HqFAa+VJ+Hg==
|
||||
dependencies:
|
||||
"@next/env" "13.2.0"
|
||||
"@next/env" "13.2.1"
|
||||
"@swc/helpers" "0.4.14"
|
||||
caniuse-lite "^1.0.30001406"
|
||||
postcss "8.4.14"
|
||||
styled-jsx "5.1.1"
|
||||
optionalDependencies:
|
||||
"@next/swc-android-arm-eabi" "13.2.0"
|
||||
"@next/swc-android-arm64" "13.2.0"
|
||||
"@next/swc-darwin-arm64" "13.2.0"
|
||||
"@next/swc-darwin-x64" "13.2.0"
|
||||
"@next/swc-freebsd-x64" "13.2.0"
|
||||
"@next/swc-linux-arm-gnueabihf" "13.2.0"
|
||||
"@next/swc-linux-arm64-gnu" "13.2.0"
|
||||
"@next/swc-linux-arm64-musl" "13.2.0"
|
||||
"@next/swc-linux-x64-gnu" "13.2.0"
|
||||
"@next/swc-linux-x64-musl" "13.2.0"
|
||||
"@next/swc-win32-arm64-msvc" "13.2.0"
|
||||
"@next/swc-win32-ia32-msvc" "13.2.0"
|
||||
"@next/swc-win32-x64-msvc" "13.2.0"
|
||||
"@next/swc-android-arm-eabi" "13.2.1"
|
||||
"@next/swc-android-arm64" "13.2.1"
|
||||
"@next/swc-darwin-arm64" "13.2.1"
|
||||
"@next/swc-darwin-x64" "13.2.1"
|
||||
"@next/swc-freebsd-x64" "13.2.1"
|
||||
"@next/swc-linux-arm-gnueabihf" "13.2.1"
|
||||
"@next/swc-linux-arm64-gnu" "13.2.1"
|
||||
"@next/swc-linux-arm64-musl" "13.2.1"
|
||||
"@next/swc-linux-x64-gnu" "13.2.1"
|
||||
"@next/swc-linux-x64-musl" "13.2.1"
|
||||
"@next/swc-win32-arm64-msvc" "13.2.1"
|
||||
"@next/swc-win32-ia32-msvc" "13.2.1"
|
||||
"@next/swc-win32-x64-msvc" "13.2.1"
|
||||
|
||||
node-fetch@2.6.7:
|
||||
version "2.6.7"
|
||||
@@ -4241,12 +4246,12 @@ ts-morph@^10.0.2:
|
||||
code-block-writer "^10.1.1"
|
||||
|
||||
tsconfig-paths@^3.14.1:
|
||||
version "3.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
|
||||
integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
|
||||
version "3.14.2"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088"
|
||||
integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
|
||||
dependencies:
|
||||
"@types/json5" "^0.0.29"
|
||||
json5 "^1.0.1"
|
||||
json5 "^1.0.2"
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user