mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 19:01:19 +00:00
Removed local storage and using next-auth with session for login and authentication
This commit is contained in:
parent
658cfe31a9
commit
d1eaae6fa1
10
package-lock.json
generated
10
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"next": "14.2.5",
|
||||
"next-auth": "^4.24.7",
|
||||
"next-remove-imports": "^1.0.12",
|
||||
"nodemailer": "^6.9.14",
|
||||
"nostr-tools": "^2.7.1",
|
||||
"primeicons": "^7.0.0",
|
||||
"primereact": "^10.7.0",
|
||||
@ -8595,6 +8596,15 @@
|
||||
"integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "6.9.14",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz",
|
||||
"integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
|
@ -22,6 +22,7 @@
|
||||
"next": "14.2.5",
|
||||
"next-auth": "^4.24.7",
|
||||
"next-remove-imports": "^1.0.12",
|
||||
"nodemailer": "^6.9.14",
|
||||
"nostr-tools": "^2.7.1",
|
||||
"primeicons": "^7.0.0",
|
||||
"primereact": "^10.7.0",
|
||||
|
@ -5,7 +5,7 @@ import ZapDisplay from '@/components/zaps/ZapDisplay';
|
||||
import { getSatAmountFromInvoice } from '@/utils/lightning';
|
||||
import { Tag } from 'primereact/tag';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import Image from 'next/image';
|
||||
import dynamic from 'next/dynamic';
|
||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||
@ -33,13 +33,19 @@ export default function CourseDetails({ processedEvent }) {
|
||||
const [bitcoinConnect, setBitcoinConnect] = useState(false);
|
||||
const [nAddress, setNAddress] = useState(null);
|
||||
const [zapAmount, setZapAmount] = useState(0);
|
||||
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const [user, setUser] = useState(null);
|
||||
const { zaps, zapsLoading, zapsError } = useZapsSubscription({ event: processedEvent });
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const { data: session, status } = useSession();
|
||||
const router = useRouter();
|
||||
const ndk = useNDKContext();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const handleZapEvent = async () => {
|
||||
if (!processedEvent) return;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { InputText } from "primereact/inputtext";
|
||||
import { InputNumber } from "primereact/inputnumber";
|
||||
@ -7,7 +7,7 @@ import { Button } from "primereact/button";
|
||||
import { Dropdown } from "primereact/dropdown";
|
||||
import { ProgressSpinner } from "primereact/progressspinner";
|
||||
import { v4 as uuidv4, v4 } from 'uuid';
|
||||
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { useRouter } from "next/router";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
@ -32,11 +32,18 @@ const CourseForm = () => {
|
||||
const { resources, resourcesLoading, resourcesError } = useResourcesQuery();
|
||||
const { workshops, workshopsLoading, workshopsError } = useWorkshopsQuery();
|
||||
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
||||
const [user, setUser] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const ndk = useNDKContext();
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
/**
|
||||
* Course Creation Flow:
|
||||
* 1. Generate a new course ID
|
||||
|
@ -5,7 +5,7 @@ import { InputNumber } from "primereact/inputnumber";
|
||||
import { InputSwitch } from "primereact/inputswitch";
|
||||
import { Button } from "primereact/button";
|
||||
import { useRouter } from "next/router";;
|
||||
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import dynamic from 'next/dynamic';
|
||||
const MDEditor = dynamic(
|
||||
@ -24,11 +24,18 @@ const ResourceForm = ({ draft = null }) => {
|
||||
const [coverImage, setCoverImage] = useState(draft?.image || '');
|
||||
const [topics, setTopics] = useState(draft?.topics || ['']);
|
||||
const [content, setContent] = useState(draft?.content || '');
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const { showToast } = useToast();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const handleContentChange = useCallback((value) => {
|
||||
setContent(value || '');
|
||||
}, []);
|
||||
|
@ -6,7 +6,7 @@ import { InputNumber } from 'primereact/inputnumber';
|
||||
import { InputSwitch } from 'primereact/inputswitch';
|
||||
import { Button } from 'primereact/button';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import 'primeicons/primeicons.css';
|
||||
|
||||
const WorkshopForm = ({ draft = null }) => {
|
||||
@ -19,9 +19,16 @@ const WorkshopForm = ({ draft = null }) => {
|
||||
const [topics, setTopics] = useState(draft?.topics || ['']);
|
||||
|
||||
const router = useRouter();
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const { showToast } = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (draft) {
|
||||
setTitle(draft.title);
|
||||
|
@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
@ -6,22 +5,31 @@ import { useImageProxy } from '@/hooks/useImageProxy';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Menu } from 'primereact/menu';
|
||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||
import {useLocalStorageWithEffect} from '@/hooks/useLocalStorage';
|
||||
import {useSession, signOut} from 'next-auth/react';
|
||||
import 'primereact/resources/primereact.min.css';
|
||||
import 'primeicons/primeicons.css';
|
||||
import styles from '../navbar.module.css';
|
||||
|
||||
const UserAvatar = () => {
|
||||
const router = useRouter();
|
||||
const [user, setUser] = useLocalStorageWithEffect('user', {});
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [user, setUser] = useState(null);
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const windowWidth = useWindowWidth();
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
console.log(session);
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const menu = useRef(null);
|
||||
|
||||
const handleLogout = () => {
|
||||
window.localStorage.removeItem('user');
|
||||
signOut();
|
||||
router.push('/').then(() => window.location.reload());
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ import React, { useState, useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { Button } from "primereact/button";
|
||||
import MenuTab from "@/components/menutab/MenuTab";
|
||||
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
|
||||
import { useCoursesQuery } from "@/hooks/nostrQueries/content/useCoursesQuery";
|
||||
import { useResourcesQuery } from "@/hooks/nostrQueries/content/useResourcesQuery";
|
||||
import { useWorkshopsQuery } from "@/hooks/nostrQueries/content/useWorkshopsQuery";
|
||||
import { useDraftsQuery } from "@/hooks/apiQueries/useDraftsQuery";
|
||||
import { useContentIdsQuery } from "@/hooks/apiQueries/useContentIdsQuery";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import ContentList from "@/components/content/lists/ContentList";
|
||||
import { parseEvent } from "@/utils/nostr";
|
||||
@ -21,7 +21,8 @@ const UserContent = () => {
|
||||
const [content, setContent] = useState([]);
|
||||
const [publishedContent, setPublishedContent] = useState([]);
|
||||
|
||||
const [user] = useLocalStorageWithEffect("user", {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
const ndk = useNDKContext();
|
||||
@ -31,6 +32,12 @@ const UserContent = () => {
|
||||
const { drafts, draftsLoading, draftsError } = useDraftsQuery();
|
||||
const { contentIds, contentIdsLoading, contentIdsError, refetchContentIds } = useContentIdsQuery();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsClient(true);
|
||||
}, []);
|
||||
|
@ -18,7 +18,7 @@ const ZapDisplay = ({ zapAmount, event, zapsLoading }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className="text-xs cursor-pointer flex items-center relative shadow-md cursor-pointer hover:opacity-80" onClick={(e) => op.current.toggle(e)}>
|
||||
<span className="text-xs cursor-pointer flex items-center relative hover:opacity-80" onClick={(e) => op.current.toggle(e)}>
|
||||
<i className="pi pi-bolt text-yellow-300"></i>
|
||||
<span className="relative flex items-center min-w-[20px] min-h-[20px]">
|
||||
{zapsLoading || zapAmount === null || extraLoading ? (
|
||||
|
@ -1,11 +1,18 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import axios from 'axios';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import { useSession } from 'next-auth/react';
|
||||
|
||||
export function useDraftsQuery() {
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsClient(true);
|
||||
|
@ -1,46 +0,0 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
// This version of the hook initializes state without immediately attempting to read from localStorage
|
||||
function useLocalStorage(key, initialValue) {
|
||||
const [storedValue, setStoredValue] = useState(initialValue);
|
||||
|
||||
// Function to update localStorage and state
|
||||
const setValue = value => {
|
||||
try {
|
||||
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
||||
setStoredValue(valueToStore); // Update state
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore)); // Update localStorage
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
return [storedValue, setValue];
|
||||
}
|
||||
|
||||
// Custom hook to handle fetching and setting data from localStorage
|
||||
export function useLocalStorageWithEffect(key, initialValue) {
|
||||
const [storedValue, setStoredValue] = useLocalStorage(key, initialValue);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const item = window.localStorage.getItem(key);
|
||||
// Only update if the item exists to prevent overwriting the initial value with null
|
||||
if (item !== null) {
|
||||
setStoredValue(JSON.parse(item));
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}, [key]); // Dependencies array ensures this runs once on mount
|
||||
|
||||
return [storedValue, setStoredValue];
|
||||
}
|
||||
|
||||
export default useLocalStorage;
|
@ -2,6 +2,7 @@ import { PrimeReactProvider } from 'primereact/api';
|
||||
import { useEffect } from 'react';
|
||||
import Navbar from '@/components/navbar/Navbar';
|
||||
import { ToastProvider } from '@/hooks/useToast';
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
import Layout from '@/components/Layout';
|
||||
import '@/styles/globals.css'
|
||||
import 'primereact/resources/themes/lara-dark-indigo/theme.css';
|
||||
@ -17,12 +18,13 @@ import {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
export default function MyApp({
|
||||
Component, pageProps: { ...pageProps }
|
||||
Component, pageProps: { session, ...pageProps }
|
||||
}) {
|
||||
return (
|
||||
<PrimeReactProvider>
|
||||
<NDKProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<SessionProvider session={session}>
|
||||
<NDKProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ToastProvider>
|
||||
<Layout>
|
||||
<div className="flex flex-col min-h-screen">
|
||||
@ -39,6 +41,7 @@ export default function MyApp({
|
||||
</ToastProvider>
|
||||
</QueryClientProvider>
|
||||
</NDKProvider>
|
||||
</SessionProvider>
|
||||
</PrimeReactProvider>
|
||||
);
|
||||
}
|
86
src/pages/api/auth/[...nextauth].js
Normal file
86
src/pages/api/auth/[...nextauth].js
Normal file
@ -0,0 +1,86 @@
|
||||
import NextAuth from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
import NDK from "@nostr-dev-kit/ndk";
|
||||
import axios from "axios";
|
||||
import { findKind0Fields } from "@/utils/nostr";
|
||||
|
||||
const relayUrls = [
|
||||
"wss://nos.lol/",
|
||||
"wss://relay.damus.io/",
|
||||
"wss://relay.snort.social/",
|
||||
"wss://relay.nostr.band/",
|
||||
"wss://nostr.mutinywallet.com/",
|
||||
"wss://relay.mutinywallet.com/",
|
||||
"wss://relay.primal.net/"
|
||||
];
|
||||
|
||||
const BASE_URL = process.env.BASE_URL;
|
||||
|
||||
// Initialize NDK
|
||||
const ndk = new NDK({
|
||||
explicitRelayUrls: relayUrls,
|
||||
});
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
CredentialsProvider({
|
||||
id: "nostr",
|
||||
name: "Nostr",
|
||||
credentials: {
|
||||
pubkey: { label: "Public Key", type: "text" },
|
||||
},
|
||||
authorize: async (credentials) => {
|
||||
if (credentials?.pubkey) {
|
||||
await ndk.connect();
|
||||
|
||||
const user = ndk.getUser({ pubkey: credentials.pubkey });
|
||||
|
||||
try {
|
||||
const profile = await user.fetchProfile();
|
||||
|
||||
// Check if user exists, create if not
|
||||
const response = await axios.get(`${BASE_URL}/api/users/${credentials.pubkey}`);
|
||||
if (response.status === 200 && response.data) {
|
||||
return response.data;
|
||||
} else if (response.status === 204) {
|
||||
// Create user
|
||||
if (profile) {
|
||||
const fields = await findKind0Fields(profile);
|
||||
const payload = { pubkey: credentials.pubkey, ...fields };
|
||||
|
||||
const createUserResponse = await axios.post(`${BASE_URL}/api/users`, payload);
|
||||
return createUserResponse.data;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Nostr login error:", error);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token, user }) {
|
||||
if (user) {
|
||||
token.user = user; // Add user to token
|
||||
}
|
||||
return token;
|
||||
},
|
||||
async session({ session, token }) {
|
||||
session.user = token.user; // Add user to session
|
||||
return session;
|
||||
},
|
||||
async redirect({ url, baseUrl }) {
|
||||
return url.split("/signin");
|
||||
},
|
||||
},
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
session: { jwt: true },
|
||||
jwt: {
|
||||
signingKey: process.env.JWT_SECRET,
|
||||
},
|
||||
pages: {
|
||||
signIn: "/auth/signin",
|
||||
},
|
||||
});
|
75
src/pages/auth/signin.js
Normal file
75
src/pages/auth/signin.js
Normal file
@ -0,0 +1,75 @@
|
||||
import { signIn, useSession } from "next-auth/react"
|
||||
import { useState, useEffect } from "react"
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { Button } from 'primereact/button';
|
||||
import NDK, { NDKEvent, NDKNip07Signer } from "@nostr-dev-kit/ndk";
|
||||
|
||||
export default function SignIn() {
|
||||
const [email, setEmail] = useState("")
|
||||
const [nostrPubkey, setNostrPubkey] = useState("")
|
||||
const [nostrPrivkey, setNostrPrivkey] = useState("")
|
||||
|
||||
const { data: session, status } = useSession(); // Get the current session's data and status
|
||||
|
||||
// const ndk = useNDKContext()
|
||||
|
||||
useEffect(() => {
|
||||
console.log("session", session)
|
||||
}, [session])
|
||||
|
||||
const handleEmailSignIn = (e) => {
|
||||
e.preventDefault()
|
||||
signIn("email", { email })
|
||||
}
|
||||
|
||||
const handleNostrSignIn = async (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
const nip07signer = new NDKNip07Signer();
|
||||
const ndk = new NDK({ signer: nip07signer });
|
||||
|
||||
await ndk.connect()
|
||||
|
||||
try {
|
||||
const user = await nip07signer.user()
|
||||
|
||||
console.log("user in signin", user)
|
||||
const pubkey = user?._pubkey
|
||||
signIn("nostr", { pubkey })
|
||||
} catch (error) {
|
||||
console.error("Error signing Nostr event:", error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAnonymousSignIn = (e) => {
|
||||
e.preventDefault()
|
||||
signIn("anonymous")
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-fit mx-auto mt-24 flex flex-col justify-center">
|
||||
<h1 className="text-center mb-8">Sign In</h1>
|
||||
<Button
|
||||
label={"login with nostr"}
|
||||
icon="pi pi-user"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={handleNostrSignIn}
|
||||
/>
|
||||
<Button
|
||||
label={"login anonymously"}
|
||||
icon="pi pi-user"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={handleAnonymousSignIn}
|
||||
/>
|
||||
<Button
|
||||
label={"login with email"}
|
||||
icon="pi pi-envelope"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={handleEmailSignIn}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -6,7 +6,7 @@ import { getSatAmountFromInvoice } from '@/utils/lightning';
|
||||
import ZapDisplay from '@/components/zaps/ZapDisplay';
|
||||
import { Tag } from 'primereact/tag';
|
||||
import { nip19, nip04 } from 'nostr-tools';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import Image from 'next/image';
|
||||
import dynamic from 'next/dynamic';
|
||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||
@ -40,12 +40,19 @@ export default function Details() {
|
||||
const [decryptedContent, setDecryptedContent] = useState(null);
|
||||
|
||||
const ndk = useNDKContext();
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const { zaps, zapsLoading, zapsError } = useZapsSubscription({ event: processedEvent });
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (processedEvent.price) {
|
||||
setPaidResource(true);
|
||||
|
@ -4,7 +4,7 @@ import { useRouter } from 'next/router';
|
||||
import { hexToNpub } from '@/utils/nostr';
|
||||
import { nip19, nip04 } from 'nostr-tools';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
||||
import { Button } from 'primereact/button';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
@ -44,12 +44,19 @@ function validateEvent(event) {
|
||||
export default function Draft() {
|
||||
const [draft, setDraft] = useState(null);
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const { width, height } = useResponsiveImageDimensions();
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
const ndk = useNDKContext();
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
useEffect(() => {
|
||||
if (router.isReady) {
|
||||
const { slug } = router.query;
|
||||
@ -117,7 +124,6 @@ export default function Draft() {
|
||||
try {
|
||||
price = resource.tags.find(tag => tag[0] === 'price')[1];
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
price = 0;
|
||||
}
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
import React from "react";
|
||||
import { Button } from 'primereact/button';
|
||||
import { useLogin } from "@/hooks/useLogin";
|
||||
|
||||
const Login = () => {
|
||||
const { nostrLogin, anonymousLogin } = useLogin();
|
||||
return (
|
||||
<div className="w-fit mx-auto mt-24 flex flex-col justify-center">
|
||||
<h1 className="text-center mb-8">Login</h1>
|
||||
<Button
|
||||
label={"login with nostr"}
|
||||
icon="pi pi-user"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={nostrLogin}
|
||||
/>
|
||||
<Button
|
||||
label={"login anonymously"}
|
||||
icon="pi pi-user"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={anonymousLogin}
|
||||
/>
|
||||
<Button
|
||||
label={"login with email"}
|
||||
icon="pi pi-envelope"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
rounded
|
||||
onClick={anonymousLogin}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Login;
|
@ -1,21 +1,26 @@
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import React, { useRef, useState, useEffect, use } from "react";
|
||||
import { Button } from "primereact/button";
|
||||
import { DataTable } from "primereact/datatable";
|
||||
import { Menu } from "primereact/menu";
|
||||
import { Column } from "primereact/column";
|
||||
import { useImageProxy } from "@/hooks/useImageProxy";
|
||||
import { useRouter } from "next/router";
|
||||
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
|
||||
import { useSession } from 'next-auth/react';
|
||||
import UserContent from "@/components/profile/UserContent";
|
||||
import Image from "next/image";
|
||||
import BitcoinConnectButton from "@/components/profile/BitcoinConnect";
|
||||
|
||||
const Profile = () => {
|
||||
const [user] = useLocalStorageWithEffect("user", {});
|
||||
const { data: session, status } = useSession();
|
||||
const [user, setUser] = useState(null);
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const menu = useRef(null);
|
||||
|
||||
console.log('user:', user);
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
setUser(session.user);
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const purchases = [];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user