Lotta good stuff

This commit is contained in:
austinkelsay 2024-09-03 17:02:24 -05:00
parent 07e41a7ea3
commit 9b31e6cf18
19 changed files with 71 additions and 69 deletions

View File

@ -107,7 +107,7 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
return ( 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-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'> <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='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='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'> <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]'> <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>
</div> </div>

View File

@ -92,7 +92,7 @@ const CourseLesson = ({ lesson, course }) => {
</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]'>
{ {
lesson?.content && <MDDisplay source={lesson.content} /> lesson?.content && <MDDisplay className='p-4 rounded-lg' source={lesson.content} />
} }
</div> </div>
</div> </div>

View File

@ -413,7 +413,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
</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]'>
{ {
processedEvent?.content && <MDDisplay source={processedEvent.content} /> processedEvent?.content && <MDDisplay className='p-4 rounded-lg' source={processedEvent.content} />
} }
</div> </div>
</div> </div>

View File

@ -116,7 +116,7 @@ const DraftCourseLesson = ({ lesson, course }) => {
</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]'>
{ {
lesson?.content && <MDDisplay source={lesson.content} /> lesson?.content && <MDDisplay className='p-4 rounded-lg' source={lesson.content} />
} }
</div> </div>
</div> </div>

View File

@ -28,7 +28,7 @@ const ResourceDetails = ({processedEvent, topics, title, summary, image, price,
return ( return (
<div className='w-full flex flex-row justify-between max-tab:flex-col max-mob:flex-col'> <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='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='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'> <div className='pt-2 flex flex-row justify-start w-full'>

View File

@ -34,6 +34,7 @@ const MessageInput = ({ collapsed, onToggle }) => {
<Button <Button
label="Send" label="Send"
icon="pi pi-send" icon="pi pi-send"
outlined
className='mt-2' className='mt-2'
/> />
</div> </div>

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback } from "react";
import axios from "axios"; import axios from "axios";
import { InputText } from "primereact/inputtext"; import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { InputNumber } from "primereact/inputnumber"; import { InputNumber } from "primereact/inputnumber";
import { InputSwitch } from "primereact/inputswitch"; import { InputSwitch } from "primereact/inputswitch";
import { Button } from "primereact/button"; import { Button } from "primereact/button";
@ -20,6 +21,7 @@ import 'primeicons/primeicons.css';
import { Tooltip } from 'primereact/tooltip'; import { Tooltip } from 'primereact/tooltip';
import 'primereact/resources/primereact.min.css'; 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 ResourceForm = ({ draft = null, isPublished = false }) => {
const [title, setTitle] = useState(draft?.title || ''); const [title, setTitle] = useState(draft?.title || '');
const [summary, setSummary] = useState(draft?.summary || ''); 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" /> <InputText value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Title" />
</div> </div>
<div className="p-inputgroup flex-1 mt-4"> <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>
<div className="p-inputgroup flex-1 mt-4"> <div className="p-inputgroup flex-1 mt-4">
<InputText value={coverImage} onChange={(e) => setCoverImage(e.target.value)} placeholder="Cover Image URL" /> <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"> <div className="p-inputgroup flex-1 mt-8 flex-col">
<p className="py-2">Paid Resource</p> <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 && ( {isPaidResource && (
<div className="p-inputgroup flex-1 py-4"> <div className="p-inputgroup flex-1 py-4">
<InputNumber value={price} onValueChange={(e) => setPrice(e.value)} placeholder="Price (sats)" /> <InputNumber value={price} onValueChange={(e) => setPrice(e.value)} placeholder="Price (sats)" />
@ -284,7 +286,7 @@ const ResourceForm = ({ draft = null, isPublished = false }) => {
</div> </div>
</div> </div>
<div className="flex justify-center mt-8"> <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> </div>
</form> </form>
); );

View File

@ -49,8 +49,22 @@ const CourseForm = ({ draft = null }) => {
}, [draft, resources, workshops, drafts]); }, [draft, resources, workshops, drafts]);
useEffect(() => { useEffect(() => {
if (!resourcesLoading && !workshopsLoading && !draftsLoading && resources && workshops && drafts) { console.log('allContent', allContent);
setAllContent([...resources, ...workshops, ...drafts]); }, [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]); }, [resources, workshops, drafts, resourcesLoading, workshopsLoading, draftsLoading]);

View File

@ -154,7 +154,7 @@ const LessonSelector = ({ isPaidCourse, lessons, setLessons, allContent, onNewRe
<Dropdown <Dropdown
options={contentOptions} options={contentOptions}
onChange={(e) => handleContentSelect(e.value, index)} onChange={(e) => handleContentSelect(e.value, index)}
placeholder="Select Existing Lesson" placeholder={lesson.id ? lesson.title : "Create New Lesson"}
optionLabel="label" optionLabel="label"
optionGroupLabel="label" optionGroupLabel="label"
optionGroupChildren="items" optionGroupChildren="items"

View File

@ -8,8 +8,8 @@ export function useCourses() {
const [isClient, setIsClient] = useState(false); const [isClient, setIsClient] = useState(false);
const [courses, setCourses] = useState(); const [courses, setCourses] = useState();
const [isLoading, setIsLoading] = useState(false); const [coursesLoading, setCoursesLoading] = useState(false);
const [error, setError] = useState(null); const [coursesError, setCoursesError] = useState(null);
const { contentIds } = useContentIdsQuery() const { contentIds } = useContentIdsQuery()
const {ndk, addSigner} = useNDKContext(); const {ndk, addSigner} = useNDKContext();
@ -24,12 +24,12 @@ export function useCourses() {
}; };
const fetchCoursesFromNDK = async () => { const fetchCoursesFromNDK = async () => {
setIsLoading(true); setCoursesLoading(true);
setError(null); setCoursesError(null);
try { try {
if (!contentIds || contentIds.length === 0) { if (!contentIds || contentIds.length === 0) {
console.log('No content IDs found'); console.log('No content IDs found');
setIsLoading(false); setCoursesLoading(false);
return []; // Return early if no content IDs are found return []; // Return early if no content IDs are found
} }
@ -41,15 +41,15 @@ export function useCourses() {
if (events && events.size > 0) { if (events && events.size > 0) {
const eventsArray = Array.from(events); const eventsArray = Array.from(events);
const courses = eventsArray.filter(event => hasRequiredProperties(event, contentIds)); const courses = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
setIsLoading(false); setCoursesLoading(false);
return courses; return courses;
} }
setIsLoading(false); setCoursesLoading(false);
return []; return [];
} catch (error) { } catch (error) {
console.error('Error fetching courses from NDK:', error); console.error('Error fetching courses from NDK:', error);
setError(error); setCoursesError(error);
setIsLoading(false); setCoursesLoading(false);
return []; return [];
} }
}; };
@ -64,5 +64,5 @@ export function useCourses() {
} }
}, [isClient, contentIds]); }, [isClient, contentIds]);
return { courses, isLoading, error }; return { courses, coursesLoading, coursesError };
} }

View File

@ -8,8 +8,8 @@ export function useResources() {
const [isClient, setIsClient] = useState(false); const [isClient, setIsClient] = useState(false);
const [resources, setResources] = useState(); const [resources, setResources] = useState();
// Add new state variables for loading and error // Add new state variables for loading and error
const [isLoading, setIsLoading] = useState(false); const [resourcesLoading, setResourcesLoading] = useState(false);
const [error, setError] = useState(null); const [resourcesError, setResourcesError] = useState(null);
const { contentIds } = useContentIdsQuery() const { contentIds } = useContentIdsQuery()
const {ndk, addSigner} = useNDKContext(); const {ndk, addSigner} = useNDKContext();
@ -25,12 +25,12 @@ export function useResources() {
}; };
const fetchResourcesFromNDK = async () => { const fetchResourcesFromNDK = async () => {
setIsLoading(true); setResourcesLoading(true);
setError(null); setResourcesError(null);
try { try {
if (!contentIds || contentIds.length === 0) { if (!contentIds || contentIds.length === 0) {
console.log('No content IDs found'); console.log('No content IDs found');
setIsLoading(false); setResourcesLoading(false);
return []; // Return early if no content IDs are found return []; // Return early if no content IDs are found
} }
@ -42,15 +42,15 @@ export function useResources() {
if (events && events.size > 0) { if (events && events.size > 0) {
const eventsArray = Array.from(events); const eventsArray = Array.from(events);
const resources = eventsArray.filter(event => hasRequiredProperties(event, contentIds)); const resources = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
setIsLoading(false); setResourcesLoading(false);
return resources; return resources;
} }
setIsLoading(false); setResourcesLoading(false);
return []; return [];
} catch (error) { } catch (error) {
console.error('Error fetching resources from NDK:', error); console.error('Error fetching resources from NDK:', error);
setError(error); setResourcesError(error);
setIsLoading(false); setResourcesLoading(false);
return []; return [];
} }
}; };
@ -65,5 +65,5 @@ export function useResources() {
} }
}, [isClient, contentIds]); }, [isClient, contentIds]);
return { resources, isLoading, error }; return { resources, resourcesLoading, resourcesError };
} }

View File

@ -8,8 +8,8 @@ export function useWorkshops() {
const [isClient, setIsClient] = useState(false); const [isClient, setIsClient] = useState(false);
const [workshops, setWorkshops] = useState(); const [workshops, setWorkshops] = useState();
// Add new state variables for loading and error // Add new state variables for loading and error
const [isLoading, setIsLoading] = useState(false); const [workshopsLoading, setWorkshopsLoading] = useState(false);
const [error, setError] = useState(null); const [workshopsError, setWorkshopsError] = useState(null);
const { contentIds } = useContentIdsQuery() const { contentIds } = useContentIdsQuery()
const {ndk, addSigner} = useNDKContext(); const {ndk, addSigner} = useNDKContext();
@ -25,12 +25,12 @@ export function useWorkshops() {
}; };
const fetchWorkshopsFromNDK = async () => { const fetchWorkshopsFromNDK = async () => {
setIsLoading(true); setWorkshopsLoading(true);
setError(null); setWorkshopsError(null);
try { try {
if (!contentIds || contentIds.length === 0) { if (!contentIds || contentIds.length === 0) {
console.log('No content IDs found'); console.log('No content IDs found');
setIsLoading(false); setWorkshopsLoading(false);
return []; // Return early if no content IDs are found return []; // Return early if no content IDs are found
} }
@ -42,15 +42,15 @@ export function useWorkshops() {
if (events && events.size > 0) { if (events && events.size > 0) {
const eventsArray = Array.from(events); const eventsArray = Array.from(events);
const workshops = eventsArray.filter(event => hasRequiredProperties(event, contentIds)); const workshops = eventsArray.filter(event => hasRequiredProperties(event, contentIds));
setIsLoading(false); setWorkshopsLoading(false);
return workshops; return workshops;
} }
setIsLoading(false); setWorkshopsLoading(false);
return []; return [];
} catch (error) { } catch (error) {
console.error('Error fetching workshops from NDK:', error); console.error('Error fetching workshops from NDK:', error);
setError(error); setWorkshopsError(error);
setIsLoading(false); setWorkshopsLoading(false);
return []; return [];
} }
}; };
@ -65,5 +65,5 @@ export function useWorkshops() {
} }
}, [isClient, contentIds]); }, [isClient, contentIds]);
return { workshops, isLoading, error }; return { workshops, workshopsLoading, workshopsError };
} }

View File

@ -45,26 +45,26 @@ export default function SignIn() {
} }
return ( 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> <h1 className="text-center mb-8">Sign In</h1>
<Button <Button
label={"login with nostr"} label={"login with nostr"}
icon="pi pi-user" icon="pi pi-user"
className="text-[#f8f8ff] w-[250px] my-4" className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
rounded rounded
onClick={handleNostrSignIn} onClick={handleNostrSignIn}
/> />
<Button <Button
label={"login anonymously"} label={"login anonymously"}
icon="pi pi-user" icon="pi pi-user"
className="text-[#f8f8ff] w-[250px] my-4" className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
rounded rounded
onClick={handleAnonymousSignIn} onClick={handleAnonymousSignIn}
/> />
<Button <Button
label={"login with email"} label={"login with email"}
icon="pi pi-envelope" icon="pi pi-envelope"
className="text-[#f8f8ff] w-[250px] my-4" className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
rounded rounded
onClick={handleEmailSignIn} onClick={handleEmailSignIn}
/> />

View File

@ -190,7 +190,7 @@ const Course = () => {
<CourseLesson key={index} lesson={lesson} course={course} /> <CourseLesson key={index} lesson={lesson} course={course} />
))} ))}
<div className="mx-auto my-6"> <div className="mx-auto my-6">
{course?.content && <MDDisplay source={course.content} />} {course?.content && <MDDisplay className='p-4 rounded-lg' source={course.content} />}
</div> </div>
</> </>
); );

View File

@ -2,7 +2,6 @@ import React, { useState } from "react";
import MenuTab from "@/components/menutab/MenuTab"; import MenuTab from "@/components/menutab/MenuTab";
import ResourceForm from "@/components/forms/ResourceForm"; import ResourceForm from "@/components/forms/ResourceForm";
import WorkshopForm from "@/components/forms/WorkshopForm"; import WorkshopForm from "@/components/forms/WorkshopForm";
// import CourseForm from "@/components/forms/CourseForm";
import CourseForm from "@/components/forms/course/CourseForm"; import CourseForm from "@/components/forms/course/CourseForm";
const Create = () => { const Create = () => {

View File

@ -179,13 +179,13 @@ export default function Details() {
const renderContent = () => { const renderContent = () => {
if (decryptedContent) { if (decryptedContent) {
return <MDDisplay source={decryptedContent} />; return <MDDisplay className='p-4 rounded-lg' source={decryptedContent} />;
} }
if (paidResource && !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>; 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) { if (processedEvent?.content) {
return <MDDisplay source={processedEvent.content} />; return <MDDisplay className='p-4 rounded-lg' source={processedEvent.content} />;
} }
return null; return null;
} }

View File

@ -226,10 +226,10 @@ export default function Draft() {
}; };
return ( 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'> <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='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='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'> <div className='pt-2 flex flex-row justify-start w-full'>
{/* List out topics */} {/* List out topics */}
@ -302,7 +302,7 @@ export default function Draft() {
</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]'>
{ {
draft?.content && <MDDisplay source={draft.content} /> draft?.content && <MDDisplay className='p-4 rounded-lg' source={draft.content} />
} }
</div> </div>
</div> </div>

View File

@ -81,6 +81,7 @@ const Feed = () => {
className="w-fit" className="w-fit"
/> />
<Button <Button
className='text-[#f8f8ff]'
icon={isMessageInputCollapsed ? "pi pi-plus" : "pi pi-minus"} icon={isMessageInputCollapsed ? "pi pi-plus" : "pi pi-minus"}
onClick={() => setIsMessageInputCollapsed(!isMessageInputCollapsed)} onClick={() => setIsMessageInputCollapsed(!isMessageInputCollapsed)}
/> />

View File

@ -61,21 +61,6 @@ div {
max-height: 400px !important; 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 */ /* hero banner animation */
@keyframes flip { @keyframes flip {
0%, 100% { 0%, 100% {