mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 10:51:20 +00:00
Fix bitcoin connect init bug, fix resource fetching and publishing flows in useNostr, added delete for drafts
This commit is contained in:
parent
a9a443fed1
commit
ff0a0facaf
@ -9,21 +9,24 @@ const Button = dynamic(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let initialized = false;
|
||||||
|
|
||||||
|
export async function initializeBitcoinConnect() {
|
||||||
|
if (!initialized) {
|
||||||
|
const { init } = await import('@getalby/bitcoin-connect-react');
|
||||||
|
init({
|
||||||
|
appName: "PlebDevs",
|
||||||
|
filters: ["nwc"],
|
||||||
|
showBalance: false
|
||||||
|
});
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const BitcoinConnectButton = () => {
|
const BitcoinConnectButton = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializeBitcoinConnect = async () => {
|
|
||||||
// Initialize Bitcoin Connect
|
|
||||||
const { init } = await import('@getalby/bitcoin-connect-react');
|
|
||||||
init({
|
|
||||||
appName: "PlebDevs",
|
|
||||||
filters: ["nwc"],
|
|
||||||
showBalance: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
initializeBitcoinConnect();
|
initializeBitcoinConnect();
|
||||||
}, []); // Empty dependency array to run only once on component mount
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onConnect={(provider) => {
|
<Button onConnect={(provider) => {
|
||||||
@ -32,4 +35,4 @@ const BitcoinConnectButton = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BitcoinConnectButton;
|
export default BitcoinConnectButton;
|
@ -3,6 +3,8 @@ import axios from 'axios';
|
|||||||
import { nip57, nip19 } from 'nostr-tools';
|
import { nip57, nip19 } from 'nostr-tools';
|
||||||
import { NostrContext } from '@/context/NostrContext';
|
import { NostrContext } from '@/context/NostrContext';
|
||||||
import { lnurlEncode } from '@/utils/lnurl';
|
import { lnurlEncode } from '@/utils/lnurl';
|
||||||
|
import { parseEvent } from '@/utils/nostr';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
const defaultRelays = [
|
const defaultRelays = [
|
||||||
"wss://nos.lol/",
|
"wss://nos.lol/",
|
||||||
@ -228,29 +230,29 @@ export function useNostr() {
|
|||||||
|
|
||||||
const fetchKind0 = useCallback(
|
const fetchKind0 = useCallback(
|
||||||
async (publicKey) => {
|
async (publicKey) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
resolve(null); // Resolve with null if no event is received within the timeout
|
resolve(null); // Resolve with null if no event is received within the timeout
|
||||||
}, 10000); // 10 seconds timeout
|
}, 10000); // 10 seconds timeout
|
||||||
|
|
||||||
subscribe(
|
subscribe(
|
||||||
[{ authors: [publicKey], kinds: [0] }],
|
[{ authors: [publicKey], kinds: [0] }],
|
||||||
{
|
{
|
||||||
onevent: (event) => {
|
onevent: (event) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
resolve(JSON.parse(event.content));
|
resolve(JSON.parse(event.content));
|
||||||
},
|
},
|
||||||
onerror: (error) => {
|
onerror: (error) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
console.error('Error fetching kind 0:', error);
|
console.error('Error fetching kind 0:', error);
|
||||||
resolve(null);
|
resolve(null);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[subscribe]
|
[subscribe]
|
||||||
);
|
);
|
||||||
|
|
||||||
const zapEvent = useCallback(
|
const zapEvent = useCallback(
|
||||||
async (event, amount, comment) => {
|
async (event, amount, comment) => {
|
||||||
@ -340,37 +342,36 @@ export function useNostr() {
|
|||||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||||
const hasRequiredTags = (tags) => {
|
const hasRequiredTags = (tags) => {
|
||||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
// Check if 'resource' tag exists
|
|
||||||
const hasResource = tags.some(([tag, value]) => tag === "t" && value === "resource");
|
const hasResource = tags.some(([tag, value]) => tag === "t" && value === "resource");
|
||||||
// Return true if both tags exist
|
|
||||||
return hasPlebDevs && hasResource;
|
return hasPlebDevs && hasResource;
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let resources = [];
|
let resources = [];
|
||||||
|
|
||||||
const subscription = subscribe(
|
const subscription = subscribe(
|
||||||
filter,
|
filter,
|
||||||
{
|
{
|
||||||
onevent: (event) => {
|
onevent: (event) => {
|
||||||
if (hasRequiredTags(event.tags)) {
|
if (hasRequiredTags(event.tags)) {
|
||||||
|
console.log('event:', event);
|
||||||
resources.push(event);
|
resources.push(event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror: (error) => {
|
onerror: (error) => {
|
||||||
console.error('Error fetching resources:', error);
|
console.error('Error fetching resources:', error);
|
||||||
subscription?.close();
|
// Don't resolve here, just log the error
|
||||||
resolve(resources);
|
|
||||||
},
|
},
|
||||||
onclose: () => {
|
onclose: () => {
|
||||||
resolve(resources);
|
// Don't resolve here either
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
2000 // Adjust the timeout value as needed
|
2000 // Adjust the timeout value as needed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set a timeout to resolve the promise after collecting events
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
subscription?.close();
|
subscription?.close();
|
||||||
|
console.log('Resolving with resources:', resources);
|
||||||
resolve(resources);
|
resolve(resources);
|
||||||
}, 2000); // Adjust the timeout value as needed
|
}, 2000); // Adjust the timeout value as needed
|
||||||
});
|
});
|
||||||
@ -378,32 +379,33 @@ export function useNostr() {
|
|||||||
|
|
||||||
const fetchWorkshops = useCallback(async () => {
|
const fetchWorkshops = useCallback(async () => {
|
||||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||||
|
console.log('filter:', filter);
|
||||||
const hasRequiredTags = (tags) => {
|
const hasRequiredTags = (tags) => {
|
||||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
|
|
||||||
const hasWorkshop = tags.some(([tag, value]) => tag === "t" && value === "workshop");
|
const hasWorkshop = tags.some(([tag, value]) => tag === "t" && value === "workshop");
|
||||||
|
|
||||||
return hasPlebDevs && hasWorkshop;
|
return hasPlebDevs && hasWorkshop;
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let workshops = [];
|
let workshops = [];
|
||||||
|
|
||||||
const subscription = subscribe(
|
const subscription = subscribe(
|
||||||
filter,
|
filter,
|
||||||
{
|
{
|
||||||
onevent: (event) => {
|
onevent: (event) => {
|
||||||
|
console.log('Received workshop event:', event);
|
||||||
if (hasRequiredTags(event.tags)) {
|
if (hasRequiredTags(event.tags)) {
|
||||||
|
console.log('Workshop event passed tag check, adding to workshops');
|
||||||
workshops.push(event);
|
workshops.push(event);
|
||||||
|
} else {
|
||||||
|
console.log('Workshop event did not pass tag check');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror: (error) => {
|
onerror: (error) => {
|
||||||
console.error('Error fetching workshops:', error);
|
console.error('Error fetching workshops:', error);
|
||||||
subscription?.close();
|
// Don't resolve here, just log the error
|
||||||
resolve(workshops);
|
|
||||||
},
|
},
|
||||||
onclose: () => {
|
onclose: () => {
|
||||||
resolve(workshops);
|
// Don't resolve here either
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
2000 // Adjust the timeout value as needed
|
2000 // Adjust the timeout value as needed
|
||||||
@ -411,6 +413,7 @@ export function useNostr() {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
subscription?.close();
|
subscription?.close();
|
||||||
|
console.log('Resolving with workshops:', workshops);
|
||||||
resolve(workshops);
|
resolve(workshops);
|
||||||
}, 2000); // Adjust the timeout value as needed
|
}, 2000); // Adjust the timeout value as needed
|
||||||
});
|
});
|
||||||
@ -420,30 +423,30 @@ export function useNostr() {
|
|||||||
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
||||||
const hasRequiredTags = (tags) => {
|
const hasRequiredTags = (tags) => {
|
||||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||||
|
|
||||||
const hasCourse = tags.some(([tag, value]) => tag === "t" && value === "course");
|
const hasCourse = tags.some(([tag, value]) => tag === "t" && value === "course");
|
||||||
|
|
||||||
return hasPlebDevs && hasCourse;
|
return hasPlebDevs && hasCourse;
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let courses = [];
|
let courses = [];
|
||||||
|
|
||||||
const subscription = subscribe(
|
const subscription = subscribe(
|
||||||
filter,
|
filter,
|
||||||
{
|
{
|
||||||
onevent: (event) => {
|
onevent: (event) => {
|
||||||
|
console.log('Received course event:', event);
|
||||||
if (hasRequiredTags(event.tags)) {
|
if (hasRequiredTags(event.tags)) {
|
||||||
|
console.log('Course event passed tag check, adding to courses');
|
||||||
courses.push(event);
|
courses.push(event);
|
||||||
|
} else {
|
||||||
|
console.log('Course event did not pass tag check');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror: (error) => {
|
onerror: (error) => {
|
||||||
console.error('Error fetching courses:', error);
|
console.error('Error fetching courses:', error);
|
||||||
subscription?.close();
|
// Don't resolve here, just log the error
|
||||||
resolve(courses);
|
|
||||||
},
|
},
|
||||||
onclose: () => {
|
onclose: () => {
|
||||||
resolve(courses);
|
// Don't resolve here either
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
2000 // Adjust the timeout value as needed
|
2000 // Adjust the timeout value as needed
|
||||||
@ -451,6 +454,7 @@ export function useNostr() {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
subscription?.close();
|
subscription?.close();
|
||||||
|
console.log('Resolving with courses:', courses);
|
||||||
resolve(courses);
|
resolve(courses);
|
||||||
}, 2000); // Adjust the timeout value as needed
|
}, 2000); // Adjust the timeout value as needed
|
||||||
});
|
});
|
||||||
@ -458,92 +462,87 @@ export function useNostr() {
|
|||||||
|
|
||||||
const publishResource = useCallback(
|
const publishResource = useCallback(
|
||||||
async (resourceEvent) => {
|
async (resourceEvent) => {
|
||||||
const published = await publish(resourceEvent);
|
const published = await publish(resourceEvent);
|
||||||
|
|
||||||
if (published) {
|
|
||||||
const { id, kind, pubkey, content, title, summary, image, published_at, d, topics } = parseEvent(resourceEvent);
|
|
||||||
|
|
||||||
const user = window.localStorage.getItem('user');
|
if (published) {
|
||||||
const userId = JSON.parse(user).id;
|
const { id, kind, pubkey, content, title, summary, image, published_at, d, topics } = parseEvent(resourceEvent);
|
||||||
|
|
||||||
const payload = {
|
const user = window.localStorage.getItem('user');
|
||||||
|
const userId = JSON.parse(user).id;
|
||||||
};
|
|
||||||
|
const payload = {
|
||||||
if (payload && payload.user) {
|
id: uuidv4(),
|
||||||
try {
|
user: {
|
||||||
const response = await axios.post('/api/resources', payload);
|
connect: { id: userId } // This is the correct way to connect to an existing user
|
||||||
|
},
|
||||||
if (response.status === 201) {
|
noteId: id
|
||||||
try {
|
};
|
||||||
const deleteResponse = await axios.delete(`/api/drafts/${resourceEvent.id}`);
|
|
||||||
|
if (payload && payload.user) {
|
||||||
if (deleteResponse.status === 204) {
|
try {
|
||||||
return true;
|
const response = await axios.post('/api/resources', payload);
|
||||||
|
|
||||||
|
if (response.status === 201) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating resource:', error);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting draft:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating resource:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
[publish]
|
[publish]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const publishCourse = useCallback(
|
const publishCourse = useCallback(
|
||||||
async (courseEvent) => {
|
async (courseEvent) => {
|
||||||
const published = await publish(courseEvent);
|
const published = await publish(courseEvent);
|
||||||
|
|
||||||
if (published) {
|
if (published) {
|
||||||
const user = window.localStorage.getItem('user');
|
const user = window.localStorage.getItem('user');
|
||||||
const pubkey = JSON.parse(user).pubkey;
|
const pubkey = JSON.parse(user).pubkey;
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
title: courseEvent.title,
|
title: courseEvent.title,
|
||||||
summary: courseEvent.summary,
|
summary: courseEvent.summary,
|
||||||
type: 'course',
|
type: 'course',
|
||||||
content: courseEvent.content,
|
content: courseEvent.content,
|
||||||
image: courseEvent.image,
|
image: courseEvent.image,
|
||||||
user: pubkey,
|
user: pubkey,
|
||||||
topics: [...courseEvent.topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'course']
|
topics: [...courseEvent.topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'course']
|
||||||
};
|
};
|
||||||
|
|
||||||
if (payload && payload.user) {
|
if (payload && payload.user) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('/api/courses', payload);
|
const response = await axios.post('/api/courses', payload);
|
||||||
|
|
||||||
if (response.status === 201) {
|
if (response.status === 201) {
|
||||||
try {
|
try {
|
||||||
const deleteResponse = await axios.delete(`/api/drafts/${courseEvent.id}`);
|
const deleteResponse = await axios.delete(`/api/drafts/${courseEvent.id}`);
|
||||||
|
|
||||||
if (deleteResponse.status === 204) {
|
if (deleteResponse.status === 204) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting draft:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating course:', error);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting draft:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating course:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
[publish]
|
[publish]
|
||||||
);
|
);
|
||||||
|
|
||||||
return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchKind0, fetchResources, fetchWorkshops, fetchCourses, zapEvent, fetchZapsForEvents, publishResource, publishCourse };
|
return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchKind0, fetchResources, fetchWorkshops, fetchCourses, zapEvent, fetchZapsForEvents, publishResource, publishCourse };
|
||||||
}
|
}
|
@ -72,10 +72,42 @@ export default function Details() {
|
|||||||
const { unsignedEvent, type } = await buildEvent(draft);
|
const { unsignedEvent, type } = await buildEvent(draft);
|
||||||
|
|
||||||
if (unsignedEvent) {
|
if (unsignedEvent) {
|
||||||
await publishEvent(unsignedEvent, type);
|
const published = await publishEvent(unsignedEvent, type);
|
||||||
|
// if successful, delete the draft, redirect to profile
|
||||||
|
if (published) {
|
||||||
|
axios.delete(`/api/drafts/${draft.id}`)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 204) {
|
||||||
|
showToast('success', 'Success', 'Draft deleted successfully.');
|
||||||
|
router.push(`/profile`);
|
||||||
|
} else {
|
||||||
|
showToast('error', 'Error', 'Failed to delete draft.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showToast('error', 'Error', 'Failed to broadcast resource. Please try again.');
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
showToast('error', 'Error', 'Failed to broadcast resource. Please try again.');
|
}
|
||||||
|
|
||||||
|
const handleDelete = async () => {
|
||||||
|
if (draft) {
|
||||||
|
await axios.delete(`/api/drafts/${draft.id}`)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 204) {
|
||||||
|
showToast('success', 'Success', 'Draft deleted successfully.');
|
||||||
|
router.push(`/profile`);
|
||||||
|
} else {
|
||||||
|
showToast('error', 'Error', 'Failed to delete draft.');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,28 +159,31 @@ export default function Details() {
|
|||||||
published = await publishCourse(signedEvent);
|
published = await publishCourse(signedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('published:', published);
|
||||||
|
|
||||||
if (published) {
|
if (published) {
|
||||||
// check if the event is published
|
// check if the event is published
|
||||||
const publishedEvent = await fetchSingleEvent(signedEvent.id);
|
const publishedEvent = await fetchSingleEvent(signedEvent.id);
|
||||||
|
|
||||||
console.log('publishedEvent:', publishedEvent);
|
console.log('publishedEvent:', publishedEvent);
|
||||||
|
|
||||||
if (publishedEvent) {
|
if (publishedEvent) {
|
||||||
// show success message
|
// show success message
|
||||||
showToast('success', 'Success', `${type} published successfully.`);
|
showToast('success', 'Success', `${type} published successfully.`);
|
||||||
// delete the draft
|
// delete the draft
|
||||||
|
console.log('draft:', draft);
|
||||||
await axios.delete(`/api/drafts/${draft.id}`)
|
await axios.delete(`/api/drafts/${draft.id}`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.status === 204) {
|
if (res.status === 204) {
|
||||||
showToast('success', 'Success', 'Draft deleted successfully.');
|
showToast('success', 'Success', 'Draft deleted successfully.');
|
||||||
router.push(`/profile`);
|
router.push(`/profile`);
|
||||||
} else {
|
} else {
|
||||||
showToast('error', 'Error', 'Failed to delete draft.');
|
showToast('error', 'Error', 'Failed to delete draft.');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +198,7 @@ export default function Details() {
|
|||||||
case 'resource':
|
case 'resource':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
||||||
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY ,process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
||||||
}
|
}
|
||||||
event = {
|
event = {
|
||||||
kind: draft?.price ? 30402 : 30023, // Determine kind based on if price is present
|
kind: draft?.price ? 30402 : 30023, // Determine kind based on if price is present
|
||||||
@ -185,7 +220,7 @@ export default function Details() {
|
|||||||
case 'workshop':
|
case 'workshop':
|
||||||
if (draft?.price) {
|
if (draft?.price) {
|
||||||
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
// encrypt the content with NEXT_PUBLIC_APP_PRIV_KEY to NEXT_PUBLIC_APP_PUBLIC_KEY
|
||||||
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY ,process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
encryptedContent = await nip04.encrypt(process.env.NEXT_PUBLIC_APP_PRIV_KEY, process.env.NEXT_PUBLIC_APP_PUBLIC_KEY, draft.content);
|
||||||
}
|
}
|
||||||
event = {
|
event = {
|
||||||
kind: draft?.price ? 30402 : 30023,
|
kind: draft?.price ? 30402 : 30023,
|
||||||
@ -254,12 +289,12 @@ export default function Details() {
|
|||||||
/>
|
/>
|
||||||
{user && user?.pubkey && (
|
{user && user?.pubkey && (
|
||||||
<p className='text-lg'>
|
<p className='text-lg'>
|
||||||
Created by{' '}
|
Created by{' '}
|
||||||
<a href={`https://nostr.com/${hexToNpub(user?.pubkey)}`} rel='noreferrer noopener' target='_blank' className='text-blue-500 hover:underline'>
|
<a href={`https://nostr.com/${hexToNpub(user?.pubkey)}`} rel='noreferrer noopener' target='_blank' className='text-blue-500 hover:underline'>
|
||||||
{user?.username || user?.pubkey.slice(0, 10)}{'... '}
|
{user?.username || user?.pubkey.slice(0, 10)}{'... '}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col max-tab:mt-12 max-mob:mt-12'>
|
<div className='flex flex-col max-tab:mt-12 max-mob:mt-12'>
|
||||||
@ -281,9 +316,10 @@ export default function Details() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='w-[75vw] mx-auto flex flex-row justify-end mt-12'>
|
<div className='w-[75vw] mx-auto flex flex-row justify-end mt-12'>
|
||||||
<div className='w-[15vw] flex flex-row justify-between'>
|
<div className='w-fit flex flex-row justify-between'>
|
||||||
<Button onClick={() => router.push(`/draft/${draft?.id}/edit`)} label="Edit" severity='warning' outlined className="w-auto my-2" />
|
<Button onClick={handleSubmit} label="Publish" severity='success' outlined className="w-auto m-2" />
|
||||||
<Button onClick={handleSubmit} label="Publish" severity='success' outlined className="w-auto my-2" />
|
<Button onClick={() => router.push(`/draft/${draft?.id}/edit`)} label="Edit" severity='warning' outlined className="w-auto m-2" />
|
||||||
|
<Button onClick={handleDelete} label="Delete" severity='danger' outlined className="w-auto m-2 mr-0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]'>
|
<div className='w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]'>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user