mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 19:01:19 +00:00
Lotta good stuff
This commit is contained in:
parent
07e41a7ea3
commit
9b31e6cf18
@ -107,7 +107,7 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
||||
return (
|
||||
<div className='w-full px-24 pt-12 mx-auto mt-4 max-tab:px-0 max-mob:px-0 max-tab:pt-2 max-mob:pt-2'>
|
||||
<div className='w-full flex flex-row justify-between max-tab:flex-col max-mob:flex-col'>
|
||||
<i className='pi pi-arrow-left pl-8 cursor-pointer hover:opacity-75 max-tab:pl-2 max-mob:pl-2' onClick={() => router.push('/')} />
|
||||
<i className='pi pi-arrow-left pr-8 cursor-pointer hover:opacity-75' onClick={() => router.push('/')} />
|
||||
<div className='w-[75vw] mx-auto flex flex-row items-start justify-between max-tab:flex-col max-mob:flex-col max-tab:w-[95vw] max-mob:w-[95vw]'>
|
||||
<div className='flex flex-col items-start max-w-[45vw] max-tab:max-w-[100vw] max-mob:max-w-[100vw]'>
|
||||
<div className='pt-2 flex flex-row justify-start w-full'>
|
||||
@ -184,7 +184,7 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
||||
)}
|
||||
<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]'>
|
||||
{
|
||||
processedEvent?.content && <MDDisplay source={processedEvent.content} />
|
||||
processedEvent?.content && <MDDisplay className='p-4 rounded-lg' source={processedEvent.content} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -92,7 +92,7 @@ const CourseLesson = ({ lesson, course }) => {
|
||||
</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]'>
|
||||
{
|
||||
lesson?.content && <MDDisplay source={lesson.content} />
|
||||
lesson?.content && <MDDisplay className='p-4 rounded-lg' source={lesson.content} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -413,7 +413,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
||||
</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]'>
|
||||
{
|
||||
processedEvent?.content && <MDDisplay source={processedEvent.content} />
|
||||
processedEvent?.content && <MDDisplay className='p-4 rounded-lg' source={processedEvent.content} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -116,7 +116,7 @@ const DraftCourseLesson = ({ lesson, course }) => {
|
||||
</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]'>
|
||||
{
|
||||
lesson?.content && <MDDisplay source={lesson.content} />
|
||||
lesson?.content && <MDDisplay className='p-4 rounded-lg' source={lesson.content} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@ const ResourceDetails = ({processedEvent, topics, title, summary, image, price,
|
||||
|
||||
return (
|
||||
<div className='w-full flex flex-row justify-between max-tab:flex-col max-mob:flex-col'>
|
||||
<i className='pi pi-arrow-left pl-8 cursor-pointer hover:opacity-75 max-tab:pl-2 max-mob:pl-2' onClick={() => router.push('/')} />
|
||||
<i className='pi pi-arrow-left pr-8 cursor-pointer hover:opacity-75' onClick={() => router.push('/')} />
|
||||
<div className='w-[75vw] mx-auto flex flex-row items-start justify-between max-tab:flex-col max-mob:flex-col max-tab:w-[95vw] max-mob:w-[95vw]'>
|
||||
<div className='flex flex-col items-start max-w-[45vw] max-tab:max-w-[100vw] max-mob:max-w-[100vw]'>
|
||||
<div className='pt-2 flex flex-row justify-start w-full'>
|
||||
|
@ -34,6 +34,7 @@ const MessageInput = ({ collapsed, onToggle }) => {
|
||||
<Button
|
||||
label="Send"
|
||||
icon="pi pi-send"
|
||||
outlined
|
||||
className='mt-2'
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import axios from "axios";
|
||||
import { InputText } from "primereact/inputtext";
|
||||
import { InputTextarea } from "primereact/inputtextarea";
|
||||
import { InputNumber } from "primereact/inputnumber";
|
||||
import { InputSwitch } from "primereact/inputswitch";
|
||||
import { Button } from "primereact/button";
|
||||
@ -20,6 +21,7 @@ import 'primeicons/primeicons.css';
|
||||
import { Tooltip } from 'primereact/tooltip';
|
||||
import 'primereact/resources/primereact.min.css';
|
||||
|
||||
// todo make the summarry save in a formatted way so we can keep this spaces and line breaks
|
||||
const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
const [title, setTitle] = useState(draft?.title || '');
|
||||
const [summary, setSummary] = useState(draft?.summary || '');
|
||||
@ -221,7 +223,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
<InputText value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Title" />
|
||||
</div>
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
<InputText value={summary} onChange={(e) => setSummary(e.target.value)} placeholder="Summary" />
|
||||
<InputTextarea value={summary} onChange={(e) => setSummary(e.target.value)} placeholder="Summary" />
|
||||
</div>
|
||||
<div className="p-inputgroup flex-1 mt-4">
|
||||
<InputText value={coverImage} onChange={(e) => setCoverImage(e.target.value)} placeholder="Cover Image URL" />
|
||||
@ -229,7 +231,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
|
||||
<div className="p-inputgroup flex-1 mt-8 flex-col">
|
||||
<p className="py-2">Paid Resource</p>
|
||||
<InputSwitch checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
||||
<InputSwitch autoResize checked={isPaidResource} onChange={(e) => setIsPaidResource(e.value)} />
|
||||
{isPaidResource && (
|
||||
<div className="p-inputgroup flex-1 py-4">
|
||||
<InputNumber value={price} onValueChange={(e) => setPrice(e.value)} placeholder="Price (sats)" />
|
||||
@ -284,7 +286,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center mt-8">
|
||||
<Button type="submit" severity="success" outlined label={draft ? "Update" : "Submit"} />
|
||||
<Button type="submit" severity="success" outlined label={draft ? "Update Draft" : "Save Draft"} />
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
@ -49,8 +49,22 @@ const CourseForm = ({ draft = null }) => {
|
||||
}, [draft, resources, workshops, drafts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!resourcesLoading && !workshopsLoading && !draftsLoading && resources && workshops && drafts) {
|
||||
setAllContent([...resources, ...workshops, ...drafts]);
|
||||
console.log('allContent', allContent);
|
||||
}, [allContent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!resourcesLoading && !workshopsLoading && !draftsLoading) {
|
||||
let combinedContent = [];
|
||||
if (resources) {
|
||||
combinedContent = [...combinedContent, ...resources];
|
||||
}
|
||||
if (workshops) {
|
||||
combinedContent = [...combinedContent, ...workshops];
|
||||
}
|
||||
if (drafts) {
|
||||
combinedContent = [...combinedContent, ...drafts];
|
||||
}
|
||||
setAllContent(combinedContent);
|
||||
}
|
||||
}, [resources, workshops, drafts, resourcesLoading, workshopsLoading, draftsLoading]);
|
||||
|
||||
|
@ -154,7 +154,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
|
||||
<Dropdown
|
||||
options={contentOptions}
|
||||
onChange={(e) => handleContentSelect(e.value, index)}
|
||||
placeholder="Select Existing Lesson"
|
||||
placeholder={lesson.id ? lesson.title : "Create New Lesson"}
|
||||
optionLabel="label"
|
||||
optionGroupLabel="label"
|
||||
optionGroupChildren="items"
|
||||
|
@ -8,8 +8,8 @@ export function useCourses() {
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [courses, setCourses] = useState();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [coursesLoading, setCoursesLoading] = useState(false);
|
||||
const [coursesError, setCoursesError] = useState(null);
|
||||
|
||||
const { contentIds } = useContentIdsQuery()
|
||||
const {ndk, addSigner} = useNDKContext();
|
||||
@ -24,12 +24,12 @@ export function useCourses() {
|
||||
};
|
||||
|
||||
const fetchCoursesFromNDK = async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setCoursesLoading(true);
|
||||
setCoursesError(null);
|
||||
try {
|
||||
if (!contentIds || contentIds.length === 0) {
|
||||
console.log('No content IDs found');
|
||||
setIsLoading(false);
|
||||
setCoursesLoading(false);
|
||||
return []; // Return early if no content IDs are found
|
||||
}
|
||||
|
||||
@ -41,15 +41,15 @@ export function useCourses() {
|
||||
if (events && events.size > 0) {
|
||||
const eventsArray = Array.from(events);
|
||||
const courses = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
||||
setIsLoading(false);
|
||||
setCoursesLoading(false);
|
||||
return courses;
|
||||
}
|
||||
setIsLoading(false);
|
||||
setCoursesLoading(false);
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching courses from NDK:', error);
|
||||
setError(error);
|
||||
setIsLoading(false);
|
||||
setCoursesError(error);
|
||||
setCoursesLoading(false);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@ -64,5 +64,5 @@ export function useCourses() {
|
||||
}
|
||||
}, [isClient, contentIds]);
|
||||
|
||||
return { courses, isLoading, error };
|
||||
return { courses, coursesLoading, coursesError };
|
||||
}
|
@ -8,8 +8,8 @@ export function useResources() {
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [resources, setResources] = useState();
|
||||
// Add new state variables for loading and error
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [resourcesLoading, setResourcesLoading] = useState(false);
|
||||
const [resourcesError, setResourcesError] = useState(null);
|
||||
|
||||
const { contentIds } = useContentIdsQuery()
|
||||
const {ndk, addSigner} = useNDKContext();
|
||||
@ -25,12 +25,12 @@ export function useResources() {
|
||||
};
|
||||
|
||||
const fetchResourcesFromNDK = async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setResourcesLoading(true);
|
||||
setResourcesError(null);
|
||||
try {
|
||||
if (!contentIds || contentIds.length === 0) {
|
||||
console.log('No content IDs found');
|
||||
setIsLoading(false);
|
||||
setResourcesLoading(false);
|
||||
return []; // Return early if no content IDs are found
|
||||
}
|
||||
|
||||
@ -42,15 +42,15 @@ export function useResources() {
|
||||
if (events && events.size > 0) {
|
||||
const eventsArray = Array.from(events);
|
||||
const resources = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
||||
setIsLoading(false);
|
||||
setResourcesLoading(false);
|
||||
return resources;
|
||||
}
|
||||
setIsLoading(false);
|
||||
setResourcesLoading(false);
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching resources from NDK:', error);
|
||||
setError(error);
|
||||
setIsLoading(false);
|
||||
setResourcesError(error);
|
||||
setResourcesLoading(false);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@ -65,5 +65,5 @@ export function useResources() {
|
||||
}
|
||||
}, [isClient, contentIds]);
|
||||
|
||||
return { resources, isLoading, error };
|
||||
return { resources, resourcesLoading, resourcesError };
|
||||
}
|
@ -8,8 +8,8 @@ export function useWorkshops() {
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [workshops, setWorkshops] = useState();
|
||||
// Add new state variables for loading and error
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [workshopsLoading, setWorkshopsLoading] = useState(false);
|
||||
const [workshopsError, setWorkshopsError] = useState(null);
|
||||
|
||||
const { contentIds } = useContentIdsQuery()
|
||||
const {ndk, addSigner} = useNDKContext();
|
||||
@ -25,12 +25,12 @@ export function useWorkshops() {
|
||||
};
|
||||
|
||||
const fetchWorkshopsFromNDK = async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setWorkshopsLoading(true);
|
||||
setWorkshopsError(null);
|
||||
try {
|
||||
if (!contentIds || contentIds.length === 0) {
|
||||
console.log('No content IDs found');
|
||||
setIsLoading(false);
|
||||
setWorkshopsLoading(false);
|
||||
return []; // Return early if no content IDs are found
|
||||
}
|
||||
|
||||
@ -42,15 +42,15 @@ export function useWorkshops() {
|
||||
if (events && events.size > 0) {
|
||||
const eventsArray = Array.from(events);
|
||||
const workshops = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
|
||||
setIsLoading(false);
|
||||
setWorkshopsLoading(false);
|
||||
return workshops;
|
||||
}
|
||||
setIsLoading(false);
|
||||
setWorkshopsLoading(false);
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching workshops from NDK:', error);
|
||||
setError(error);
|
||||
setIsLoading(false);
|
||||
setWorkshopsError(error);
|
||||
setWorkshopsLoading(false);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@ -65,5 +65,5 @@ export function useWorkshops() {
|
||||
}
|
||||
}, [isClient, contentIds]);
|
||||
|
||||
return { workshops, isLoading, error };
|
||||
return { workshops, workshopsLoading, workshopsError };
|
||||
}
|
@ -45,26 +45,26 @@ export default function SignIn() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-fit mx-auto mt-24 flex flex-col justify-center">
|
||||
<div className="w-[100vw] 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"
|
||||
className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
|
||||
rounded
|
||||
onClick={handleNostrSignIn}
|
||||
/>
|
||||
<Button
|
||||
label={"login anonymously"}
|
||||
icon="pi pi-user"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
|
||||
rounded
|
||||
onClick={handleAnonymousSignIn}
|
||||
/>
|
||||
<Button
|
||||
label={"login with email"}
|
||||
icon="pi pi-envelope"
|
||||
className="text-[#f8f8ff] w-[250px] my-4"
|
||||
className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
|
||||
rounded
|
||||
onClick={handleEmailSignIn}
|
||||
/>
|
||||
|
@ -190,7 +190,7 @@ const Course = () => {
|
||||
<CourseLesson key={index} lesson={lesson} course={course} />
|
||||
))}
|
||||
<div className="mx-auto my-6">
|
||||
{course?.content && <MDDisplay source={course.content} />}
|
||||
{course?.content && <MDDisplay className='p-4 rounded-lg' source={course.content} />}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -2,7 +2,6 @@ import React, { useState } from "react";
|
||||
import MenuTab from "@/components/menutab/MenuTab";
|
||||
import ResourceForm from "@/components/forms/ResourceForm";
|
||||
import WorkshopForm from "@/components/forms/WorkshopForm";
|
||||
// import CourseForm from "@/components/forms/CourseForm";
|
||||
import CourseForm from "@/components/forms/course/CourseForm";
|
||||
|
||||
const Create = () => {
|
||||
|
@ -179,13 +179,13 @@ export default function Details() {
|
||||
|
||||
const renderContent = () => {
|
||||
if (decryptedContent) {
|
||||
return <MDDisplay source={decryptedContent} />;
|
||||
return <MDDisplay className='p-4 rounded-lg' source={decryptedContent} />;
|
||||
}
|
||||
if (paidResource && !decryptedContent) {
|
||||
return <p className="text-center text-xl text-red-500">This content is paid and needs to be purchased before viewing.</p>;
|
||||
}
|
||||
if (processedEvent?.content) {
|
||||
return <MDDisplay source={processedEvent.content} />;
|
||||
return <MDDisplay className='p-4 rounded-lg' source={processedEvent.content} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -226,10 +226,10 @@ export default function Draft() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='w-full px-24 pt-12 mx-auto mt-4 max-tab:px-0 max-mob:px-0 max-tab:pt-2 max-mob:pt-2'>
|
||||
<div className='w-full px-12 pt-12 mx-auto mt-4'>
|
||||
<div className='w-full flex flex-row justify-between max-tab:flex-col max-mob:flex-col'>
|
||||
<i className='pi pi-arrow-left pl-8 cursor-pointer hover:opacity-75 max-tab:pl-2 max-mob:pl-2' onClick={() => router.push('/')} />
|
||||
<div className='w-[75vw] mx-auto flex flex-row items-start justify-between max-tab:flex-col max-mob:flex-col max-tab:w-[95vw] max-mob:w-[95vw]'>
|
||||
<i className='pi pi-arrow-left pr-8 cursor-pointer hover:opacity-75' onClick={() => router.push('/')} />
|
||||
<div className='w-[75vw] mx-auto flex flex-row items-start justify-between'>
|
||||
<div className='flex flex-col items-start max-w-[45vw] max-tab:max-w-[100vw] max-mob:max-w-[100vw]'>
|
||||
<div className='pt-2 flex flex-row justify-start w-full'>
|
||||
{/* List out topics */}
|
||||
@ -302,7 +302,7 @@ export default function Draft() {
|
||||
</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]'>
|
||||
{
|
||||
draft?.content && <MDDisplay source={draft.content} />
|
||||
draft?.content && <MDDisplay className='p-4 rounded-lg' source={draft.content} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -81,6 +81,7 @@ const Feed = () => {
|
||||
className="w-fit"
|
||||
/>
|
||||
<Button
|
||||
className='text-[#f8f8ff]'
|
||||
icon={isMessageInputCollapsed ? "pi pi-plus" : "pi pi-minus"}
|
||||
onClick={() => setIsMessageInputCollapsed(!isMessageInputCollapsed)}
|
||||
/>
|
||||
|
@ -61,21 +61,6 @@ div {
|
||||
max-height: 400px !important;
|
||||
}
|
||||
|
||||
/* accordian */
|
||||
.p-accordion .p-accordion-content {
|
||||
border: none !important;
|
||||
padding-top: 0px !important;
|
||||
}
|
||||
|
||||
.p-accordion .p-accordion-header-link {
|
||||
border: none !important;
|
||||
padding-bottom: 12px !important;
|
||||
padding-top: 12px !important;
|
||||
margin-bottom: 8px !important;
|
||||
border-bottom-left-radius: 7px !important;
|
||||
border-bottom-right-radius: 7px !important;
|
||||
}
|
||||
|
||||
/* hero banner animation */
|
||||
@keyframes flip {
|
||||
0%, 100% {
|
||||
|
Loading…
x
Reference in New Issue
Block a user