mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 08:42:02 +00:00
Add aothor pubkey as env var, improve login/signup flow
This commit is contained in:
parent
43d0c6d321
commit
6b3991d332
@ -8,7 +8,7 @@ import { Dropdown } from "primereact/dropdown";
|
||||
import { v4 as uuidv4, v4 } from 'uuid';
|
||||
import { useLocalStorageWithEffect } from "@/hooks/useLocalStorage";
|
||||
import { useNostr } from "@/hooks/useNostr";
|
||||
import {nip19} from "nostr-tools"
|
||||
import { nip19 } from "nostr-tools"
|
||||
import { parseEvent } from "@/utils/nostr";
|
||||
import ContentDropdownItem from "@/components/content/dropdowns/ContentDropdownItem";
|
||||
import 'primeicons/primeicons.css';
|
||||
@ -119,12 +119,12 @@ const CourseForm = () => {
|
||||
if (published) {
|
||||
// delete the draft
|
||||
axios.delete(`/api/drafts/${lesson.id}`)
|
||||
.then((response) => {
|
||||
console.log('Draft deleted:', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error deleting draft:', error);
|
||||
});
|
||||
.then((response) => {
|
||||
console.log('Draft deleted:', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error deleting draft:', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,17 +178,22 @@ const CourseForm = () => {
|
||||
const signedCourseEvent = await window?.nostr?.signEvent(courseEvent);
|
||||
console.log('signedCourseEvent:', signedCourseEvent);
|
||||
// Publish the course event using Nostr
|
||||
await publish(signedCourseEvent);
|
||||
const published = await publish(signedCourseEvent);
|
||||
|
||||
// Reset the form fields after publishing the course
|
||||
setTitle('');
|
||||
setSummary('');
|
||||
setChecked(false);
|
||||
setPrice(0);
|
||||
setCoverImage('');
|
||||
setLessons([{ id: uuidv4(), title: 'Select a lesson' }]);
|
||||
setSelectedLessons([]);
|
||||
setTopics(['']);
|
||||
if (published) {
|
||||
|
||||
// Reset the form fields after publishing the course
|
||||
setTitle('');
|
||||
setSummary('');
|
||||
setChecked(false);
|
||||
setPrice(0);
|
||||
setCoverImage('');
|
||||
setLessons([{ id: uuidv4(), title: 'Select a lesson' }]);
|
||||
setSelectedLessons([]);
|
||||
setTopics(['']);
|
||||
} else {
|
||||
// Handle error
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
19
src/db/models/genericModels.js
Normal file
19
src/db/models/genericModels.js
Normal file
@ -0,0 +1,19 @@
|
||||
import prisma from "../prisma";
|
||||
|
||||
export const getAllContentIds = async () => {
|
||||
const courseIds = await prisma.course.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
const resourceIds = await prisma.resource.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
const combinedIds = [...courseIds, ...resourceIds].map((item) => item.id);
|
||||
|
||||
return combinedIds;
|
||||
};
|
@ -1,28 +1,17 @@
|
||||
// db/prisma.js
|
||||
|
||||
// Import the PrismaClient class from the @prisma/client package.
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
|
||||
// Declare a variable to hold our Prisma client instance.
|
||||
let prisma;
|
||||
|
||||
// Check if the application is running in a production environment.
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// In production, always create a new instance of PrismaClient.
|
||||
prisma = new PrismaClient();
|
||||
} else {
|
||||
// In development or other non-production environments...
|
||||
|
||||
// Check if there is already an instance of PrismaClient attached to the global object.
|
||||
if (!global.prisma) {
|
||||
// If not, create a new instance of PrismaClient...
|
||||
global.prisma = new PrismaClient();
|
||||
}
|
||||
// ...and assign it to the prisma variable. This ensures that in development,
|
||||
// the same instance of PrismaClient is reused across hot reloads and server restarts,
|
||||
// which can help prevent the exhaustion of database connections during development.
|
||||
prisma = global.prisma;
|
||||
// Check if there is already an instance of PrismaClient attached to the global object.
|
||||
// If not, create a new instance of PrismaClient and attach it to the global object.
|
||||
// This ensures that the same instance of PrismaClient is reused across multiple invocations.
|
||||
if (!global.prisma) {
|
||||
global.prisma = new PrismaClient();
|
||||
}
|
||||
|
||||
// Assign the global PrismaClient instance to the prisma variable.
|
||||
prisma = global.prisma;
|
||||
|
||||
// Export the prisma client instance, making it available for import in other parts of the application.
|
||||
export default prisma;
|
||||
module.exports = prisma;
|
||||
|
@ -61,42 +61,46 @@ export const useLogin = () => {
|
||||
|
||||
const nostrLogin = useCallback(async () => {
|
||||
if (!window || !window.nostr) {
|
||||
showToast('error', 'Nostr Unavailable', 'Nostr is not available');
|
||||
return;
|
||||
showToast('error', 'Nostr Unavailable', 'Nostr is not available');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const publicKey = await window.nostr.getPublicKey();
|
||||
if (!publicKey) {
|
||||
alert('Failed to obtain public key');
|
||||
return;
|
||||
showToast('error', 'Public Key Error', 'Failed to obtain public key');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const response = await axios.get(`/api/users/${publicKey}`);
|
||||
if (response.status !== 200) throw new Error('User not found');
|
||||
;
|
||||
window.localStorage.setItem('user', JSON.stringify(response.data));
|
||||
router.push('/').then(() => window.location.reload());
|
||||
} catch (error) {
|
||||
const response = await axios.get(`/api/users/${publicKey}`);
|
||||
let userData;
|
||||
|
||||
if (response.status === 204) {
|
||||
// User not found, create a new user
|
||||
const kind0 = await fetchKind0(publicKey);
|
||||
const fields = await findKind0Fields(kind0);
|
||||
const payload = { pubkey: publicKey, ...fields };
|
||||
|
||||
try {
|
||||
const createUserResponse = await axios.post(`/api/users`, payload);
|
||||
if (createUserResponse.status === 201) {
|
||||
window.localStorage.setItem('user', JSON.stringify(createUserResponse.data));
|
||||
router.push('/').then(() => window.location.reload());
|
||||
} else {
|
||||
console.error('Error creating user:', createUserResponse);
|
||||
}
|
||||
} catch (createError) {
|
||||
console.error('Error creating user:', createError);
|
||||
showToast('error', 'Error Creating User', 'Failed to create user');
|
||||
|
||||
let fields = {};
|
||||
if (kind0) {
|
||||
fields = await findKind0Fields(kind0);
|
||||
}
|
||||
|
||||
const payload = { pubkey: publicKey, ...fields };
|
||||
const createUserResponse = await axios.post(`/api/users`, payload);
|
||||
if (createUserResponse.status !== 201) {
|
||||
throw new Error('Failed to create user');
|
||||
}
|
||||
userData = createUserResponse.data;
|
||||
} else {
|
||||
userData = response.data;
|
||||
}
|
||||
|
||||
window.localStorage.setItem('user', JSON.stringify(userData));
|
||||
router.push('/').then(() => window.location.reload());
|
||||
} catch (error) {
|
||||
console.error('Error during login:', error);
|
||||
showToast('error', 'Login Error', error.message || 'Failed to log in');
|
||||
}
|
||||
}, [router, showToast, fetchKind0]);
|
||||
}, [router, showToast, fetchKind0]);
|
||||
|
||||
const anonymousLogin = useCallback(() => {
|
||||
try {
|
||||
|
@ -14,6 +14,8 @@ const defaultRelays = [
|
||||
"wss://relay.primal.net/"
|
||||
];
|
||||
|
||||
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
||||
|
||||
export function useNostr() {
|
||||
const pool = useContext(NostrContext);
|
||||
const subscriptionQueue = useRef([]);
|
||||
@ -175,12 +177,12 @@ export function useNostr() {
|
||||
aTagsAlt.push(`${event.kind}:${event.pubkey}:${event.d}`);
|
||||
eTags.push(event.id);
|
||||
});
|
||||
|
||||
|
||||
// Create filters for batch querying
|
||||
const filterA = { kinds: [9735], '#a': aTags };
|
||||
const filterE = { kinds: [9735], '#e': eTags };
|
||||
const filterAAlt = { kinds: [9735], '#a': aTagsAlt };
|
||||
|
||||
|
||||
// Perform batch queries
|
||||
// const [zapsA, zapsE] = await Promise.all([
|
||||
// pool.querySync(defaultRelays, filterA),
|
||||
@ -212,7 +214,7 @@ export function useNostr() {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return new Promise((resolve) => {
|
||||
querySyncQueue.current.push(async () => {
|
||||
const zaps = await querySyncFn();
|
||||
@ -222,32 +224,33 @@ export function useNostr() {
|
||||
});
|
||||
},
|
||||
[pool, processQuerySyncQueue]
|
||||
);
|
||||
);
|
||||
|
||||
const fetchKind0 = useCallback(
|
||||
async (publicKey) => {
|
||||
try {
|
||||
const kind0 = await new Promise((resolve, reject) => {
|
||||
subscribe(
|
||||
[{ authors: [publicKey], kinds: [0] }],
|
||||
{
|
||||
onevent: (event) => {
|
||||
resolve(JSON.parse(event.content));
|
||||
},
|
||||
onerror: (error) => {
|
||||
reject(error);
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
return kind0;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch kind 0 for event:', error);
|
||||
return [];
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const timeout = setTimeout(() => {
|
||||
resolve(null); // Resolve with null if no event is received within the timeout
|
||||
}, 10000); // 10 seconds timeout
|
||||
|
||||
subscribe(
|
||||
[{ authors: [publicKey], kinds: [0] }],
|
||||
{
|
||||
onevent: (event) => {
|
||||
clearTimeout(timeout);
|
||||
resolve(JSON.parse(event.content));
|
||||
},
|
||||
onerror: (error) => {
|
||||
clearTimeout(timeout);
|
||||
console.error('Error fetching kind 0:', error);
|
||||
resolve(null);
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
[subscribe]
|
||||
);
|
||||
);
|
||||
|
||||
const zapEvent = useCallback(
|
||||
async (event, amount, comment) => {
|
||||
@ -334,7 +337,7 @@ export function useNostr() {
|
||||
);
|
||||
|
||||
const fetchResources = useCallback(async () => {
|
||||
const filter = [{ kinds: [30023, 30402], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = (tags) => {
|
||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
// Check if 'resource' tag exists
|
||||
@ -374,12 +377,12 @@ export function useNostr() {
|
||||
}, [subscribe]);
|
||||
|
||||
const fetchWorkshops = useCallback(async () => {
|
||||
const filter = [{ kinds: [30023, 30402], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023, 30402], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = (tags) => {
|
||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
|
||||
const hasWorkshop = tags.some(([tag, value]) => tag === "t" && value === "workshop");
|
||||
|
||||
|
||||
return hasPlebDevs && hasWorkshop;
|
||||
};
|
||||
|
||||
@ -414,7 +417,7 @@ export function useNostr() {
|
||||
}, [subscribe]);
|
||||
|
||||
const fetchCourses = useCallback(async () => {
|
||||
const filter = [{ kinds: [30023], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = (tags) => {
|
||||
const hasPlebDevs = tags.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
|
||||
@ -453,5 +456,94 @@ export function useNostr() {
|
||||
});
|
||||
}, [subscribe]);
|
||||
|
||||
return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchKind0, fetchResources, fetchWorkshops, fetchCourses, zapEvent, fetchZapsForEvents };
|
||||
const publishResource = useCallback(
|
||||
async (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');
|
||||
const userId = JSON.parse(user).id;
|
||||
|
||||
const payload = {
|
||||
|
||||
};
|
||||
|
||||
if (payload && payload.user) {
|
||||
try {
|
||||
const response = await axios.post('/api/resources', payload);
|
||||
|
||||
if (response.status === 201) {
|
||||
try {
|
||||
const deleteResponse = await axios.delete(`/api/drafts/${resourceEvent.id}`);
|
||||
|
||||
if (deleteResponse.status === 204) {
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting draft:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating resource:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[publish]
|
||||
);
|
||||
|
||||
|
||||
const publishCourse = useCallback(
|
||||
async (courseEvent) => {
|
||||
const published = await publish(courseEvent);
|
||||
|
||||
if (published) {
|
||||
const user = window.localStorage.getItem('user');
|
||||
const pubkey = JSON.parse(user).pubkey;
|
||||
|
||||
const payload = {
|
||||
title: courseEvent.title,
|
||||
summary: courseEvent.summary,
|
||||
type: 'course',
|
||||
content: courseEvent.content,
|
||||
image: courseEvent.image,
|
||||
user: pubkey,
|
||||
topics: [...courseEvent.topics.map(topic => topic.trim().toLowerCase()), 'plebdevs', 'course']
|
||||
};
|
||||
|
||||
if (payload && payload.user) {
|
||||
try {
|
||||
const response = await axios.post('/api/courses', payload);
|
||||
|
||||
if (response.status === 201) {
|
||||
try {
|
||||
const deleteResponse = await axios.delete(`/api/drafts/${courseEvent.id}`);
|
||||
|
||||
if (deleteResponse.status === 204) {
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting draft:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating course:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[publish]
|
||||
);
|
||||
|
||||
return { subscribe, publish, fetchSingleEvent, fetchZapsForEvent, fetchKind0, fetchResources, fetchWorkshops, fetchCourses, zapEvent, fetchZapsForEvents, publishResource, publishCourse };
|
||||
}
|
@ -13,6 +13,8 @@ const initialRelays = [
|
||||
"wss://relay.primal.net/"
|
||||
];
|
||||
|
||||
const AUTHOR_PUBKEY = process.env.NEXT_PUBLIC_AUTHOR_PUBKEY;
|
||||
|
||||
export const useNostr = () => {
|
||||
const [relays, setRelays] = useState(initialRelays);
|
||||
const [relayStatuses, setRelayStatuses] = useState({});
|
||||
@ -159,7 +161,7 @@ export const useNostr = () => {
|
||||
|
||||
// Fetch resources, workshops, courses, and streams with appropriate filters and update functions
|
||||
const fetchResources = async () => {
|
||||
const filter = [{ kinds: [30023], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = async (eventData) => {
|
||||
const hasPlebDevs = eventData.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
const hasResource = eventData.some(([tag, value]) => tag === "t" && value === "resource");
|
||||
@ -181,7 +183,7 @@ export const useNostr = () => {
|
||||
};
|
||||
|
||||
const fetchWorkshops = async () => {
|
||||
const filter = [{ kinds: [30023], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = async (eventData) => {
|
||||
const hasPlebDevs = eventData.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
const hasWorkshop = eventData.some(([tag, value]) => tag === "t" && value === "workshop");
|
||||
@ -203,7 +205,7 @@ export const useNostr = () => {
|
||||
};
|
||||
|
||||
const fetchCourses = async () => {
|
||||
const filter = [{ kinds: [30023], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"] }];
|
||||
const filter = [{ kinds: [30023], authors: [AUTHOR_PUBKEY] }];
|
||||
const hasRequiredTags = async (eventData) => {
|
||||
const hasPlebDevs = eventData.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
const hasCourse = eventData.some(([tag, value]) => tag === "t" && value === "course");
|
||||
@ -226,7 +228,7 @@ export const useNostr = () => {
|
||||
};
|
||||
|
||||
// const fetchStreams = () => {
|
||||
// const filter = [{kinds: [30311], authors: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741"]}];
|
||||
// const filter = [{kinds: [30311], authors: [AUTHOR_PUBKEY]}];
|
||||
// const hasRequiredTags = (eventData) => eventData.some(([tag, value]) => tag === "t" && value === "plebdevs");
|
||||
// fetchEvents(filter, 'streams', hasRequiredTags);
|
||||
// }
|
||||
|
16
src/pages/api/content/all.js
Normal file
16
src/pages/api/content/all.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { getAllContentIds } from '../../../db/models/genericModels';
|
||||
|
||||
export default async function handler(req, res) {
|
||||
if (req.method === 'GET') {
|
||||
try {
|
||||
const ids = await getAllContentIds();
|
||||
res.status(200).json(ids);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
} else {
|
||||
// Handle any other HTTP method
|
||||
res.setHeader('Allow', ['GET', 'POST']);
|
||||
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ import { getUserById, getUserByPubkey, updateUser, deleteUser } from "@/db/model
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { slug } = req.query;
|
||||
|
||||
// Determine if slug is a pubkey or an ID
|
||||
const isPubkey = /^[0-9a-fA-F]{64}$/.test(slug);
|
||||
|
||||
@ -15,44 +14,46 @@ export default async function handler(req, res) {
|
||||
// Assume slug is an ID
|
||||
const id = parseInt(slug);
|
||||
if (isNaN(id)) {
|
||||
return res.status(400).json({ error: "Invalid identifier" });
|
||||
res.status(400).json({ error: "Invalid identifier" });
|
||||
return;
|
||||
}
|
||||
user = await getUserById(id);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return res.status(204).end();
|
||||
res.status(204).end();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (req.method) {
|
||||
case 'GET':
|
||||
return res.status(200).json(user);
|
||||
|
||||
res.status(200).json(user);
|
||||
break;
|
||||
case 'PUT':
|
||||
if (!isPubkey) {
|
||||
// Update operation should be done with an ID, not a pubkey
|
||||
const updatedUser = await updateUser(parseInt(slug), req.body);
|
||||
return res.status(200).json(updatedUser);
|
||||
res.status(200).json(updatedUser);
|
||||
} else {
|
||||
// Handle attempt to update user with pubkey
|
||||
return res.status(400).json({ error: "Cannot update user with pubkey. Use ID instead." });
|
||||
res.status(400).json({ error: "Cannot update user with pubkey. Use ID instead." });
|
||||
}
|
||||
|
||||
break;
|
||||
case 'DELETE':
|
||||
if (!isPubkey) {
|
||||
// Delete operation should be done with an ID, not a pubkey
|
||||
await deleteUser(parseInt(slug));
|
||||
return res.status(204).end();
|
||||
res.status(204).end();
|
||||
} else {
|
||||
// Handle attempt to delete user with pubkey
|
||||
return res.status(400).json({ error: "Cannot delete user with pubkey. Use ID instead." });
|
||||
res.status(400).json({ error: "Cannot delete user with pubkey. Use ID instead." });
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
|
||||
return res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||
}
|
||||
} catch (error) {
|
||||
return res.status(500).json({ error: error.message });
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ export default function Details() {
|
||||
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
|
||||
const { publish, fetchSingleEvent } = useNostr();
|
||||
const { publishCourse, publishResource, fetchSingleEvent } = useNostr();
|
||||
|
||||
const [user] = useLocalStorageWithEffect('user', {});
|
||||
|
||||
@ -109,18 +109,25 @@ export default function Details() {
|
||||
return;
|
||||
}
|
||||
|
||||
await publish(signedEvent);
|
||||
let published;
|
||||
|
||||
// check if the event is published
|
||||
const publishedEvent = await fetchSingleEvent(signedEvent.id);
|
||||
if (type === 'resource' || type === 'workshop') {
|
||||
published = await publishResource(signedEvent);
|
||||
} else if (type === 'course') {
|
||||
published = await publishCourse(signedEvent);
|
||||
}
|
||||
|
||||
console.log('publishedEvent:', publishedEvent);
|
||||
|
||||
if (publishedEvent) {
|
||||
// show success message
|
||||
showToast('success', 'Success', `${type} published successfully.`);
|
||||
// delete the draft
|
||||
await axios.delete(`/api/drafts/${draft.id}`)
|
||||
if (published) {
|
||||
// check if the event is published
|
||||
const publishedEvent = await fetchSingleEvent(signedEvent.id);
|
||||
|
||||
console.log('publishedEvent:', publishedEvent);
|
||||
|
||||
if (publishedEvent) {
|
||||
// show success message
|
||||
showToast('success', 'Success', `${type} published successfully.`);
|
||||
// delete the draft
|
||||
await axios.delete(`/api/drafts/${draft.id}`)
|
||||
.then(res => {
|
||||
if (res.status === 204) {
|
||||
showToast('success', 'Success', 'Draft deleted successfully.');
|
||||
@ -132,6 +139,7 @@ export default function Details() {
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,30 @@
|
||||
import Head from 'next/head'
|
||||
import React from 'react';
|
||||
import CoursesCarousel from '@/components/content/carousels/CoursesCarousel'
|
||||
import WorkshopsCarousel from '@/components/content/carousels/WorkshopsCarousel'
|
||||
import Head from 'next/head';
|
||||
import React, { useEffect } from 'react';
|
||||
import CoursesCarousel from '@/components/content/carousels/CoursesCarousel';
|
||||
import WorkshopsCarousel from '@/components/content/carousels/WorkshopsCarousel';
|
||||
import HeroBanner from '@/components/banner/HeroBanner';
|
||||
import ResourcesCarousel from '@/components/content/carousels/ResourcesCarousel';
|
||||
import { useLocalStorageWithEffect } from '@/hooks/useLocalStorage';
|
||||
import axios from 'axios';
|
||||
|
||||
export default function Home() {
|
||||
const [contentIds, setContentIds] = useLocalStorageWithEffect('contentIds', []);
|
||||
|
||||
// this is ready so now we can pass all ids into fetch hooks from loacl storage
|
||||
useEffect(() => {
|
||||
const fetchContentIds = async () => {
|
||||
try {
|
||||
const response = await axios.get('/api/content/all');
|
||||
const ids = response.data;
|
||||
setContentIds(ids);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch content IDs:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchContentIds();
|
||||
}, [setContentIds]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@ -21,5 +40,5 @@ export default function Home() {
|
||||
<ResourcesCarousel />
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user