mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 19:01:19 +00:00
Mobile styling fixes, search bar and interactive carousela now both play along with mobile view
This commit is contained in:
parent
38244a8da7
commit
7091da9ecd
@ -0,0 +1,211 @@
|
||||
import Image from "next/image"
|
||||
import { useState } from "react"
|
||||
import { useImageProxy } from "@/hooks/useImageProxy"
|
||||
import GenericButton from "@/components/buttons/GenericButton"
|
||||
import { useRouter } from "next/router"
|
||||
import useWindowWidth from "@/hooks/useWindowWidth"
|
||||
|
||||
// With current spacing the title can only be 1 line
|
||||
const promotions = [
|
||||
{
|
||||
id: 1,
|
||||
category: "PLEBDEVS",
|
||||
title: "Developer education & community platform",
|
||||
description: "PlebDevs is your gateway to mastering Bitcoin, Lightning, and Nostr technologies. Join our community of aspiring developers and start your journey today!",
|
||||
icon: "pi pi-code",
|
||||
image: "https://media.istockphoto.com/id/537331500/photo/programming-code-abstract-technology-background-of-software-deve.jpg?s=612x612&w=0&k=20&c=jlYes8ZfnCmD0lLn-vKvzQoKXrWaEcVypHnB5MuO-g8=",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
category: "COURSES",
|
||||
title: "Structured learning paths for new devs",
|
||||
description: "Dive into our comprehensive courses covering Bitcoin protocol, Lightning Network, and Nostr. From basics to advanced topics, we've got you covered.",
|
||||
icon: "pi pi-book",
|
||||
image: "https://media.istockphoto.com/id/1224500457/photo/programming-code-abstract-technology-background-of-software-developer-and-computer-script.jpg?s=612x612&w=0&k=20&c=nHMypkMTU1HUUW85Zt0Ff7MDbq17n0eVeXaoM9Knt4Q=",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
category: "WORKSHOPS",
|
||||
title: "Hands-on Video Workshops",
|
||||
description: "Watch and learn with our interactive video workshops. Get practical experience building real Bitcoin and Lightning applications.",
|
||||
icon: "pi pi-video",
|
||||
image: "https://newsroom.siliconslopes.com/content/images/2018/10/code.jpg",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
category: "RESOURCES",
|
||||
title: "In-depth Resources and Documentation",
|
||||
description: "Access our extensive library of resources, including guides, documentation, and best practices for Bitcoin development.",
|
||||
icon: "pi pi-file",
|
||||
image: "https://img.freepik.com/free-photo/programming-background-with-person-working-with-codes-computer_23-2150010125.jpg",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
category: "COMMUNITY",
|
||||
title: "Join Our Community",
|
||||
description: "Connect with other developers, share your projects, and get support from our community of Bitcoin enthusiasts.",
|
||||
icon: "pi pi-users",
|
||||
image: "https://pikwizard.com/pw/medium/50238b1cad4ff412fdafc1325efa1c9f.jpg",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
category: "LIGHTNING / NOSTR",
|
||||
title: "Lightning and Nostr integrated",
|
||||
description: "This platform is the first of its kind to integrate Lightning Network and Nostr protocols, allowing users to send and receive payments and interact with the Nostr network.",
|
||||
icon: "pi pi-bolt",
|
||||
image: "https://www.financemagnates.com/wp-content/uploads/2016/05/Bicoin-lightning.jpg",
|
||||
},
|
||||
]
|
||||
|
||||
const InteractivePromotionalCarousel = () => {
|
||||
const [selectedPromotion, setSelectedPromotion] = useState(promotions[0])
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const windowWidth = useWindowWidth();
|
||||
const isMobileView = windowWidth <= 1360;
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className={`flex ${isMobileView ? 'flex-col' : 'flex-row'} bg-gray-900 text-white m-4 mx-14 rounded-lg ${isMobileView ? 'h-auto' : 'h-[620px]'}`}>
|
||||
<div className={isMobileView ? 'w-full' : 'lg:w-2/3 relative'}>
|
||||
<Image
|
||||
src={returnImageProxy(selectedPromotion.image)}
|
||||
alt={selectedPromotion.title}
|
||||
width={800}
|
||||
height={600}
|
||||
className={`object-cover w-full ${isMobileView ? 'h-[300px]' : 'h-full'} rounded-lg opacity-75`}
|
||||
/>
|
||||
{isMobileView ? (
|
||||
<div className="p-6 space-y-2">
|
||||
<div className="uppercase text-sm font-bold text-[#f8f8ff]">{selectedPromotion.category}</div>
|
||||
<h2 className="text-4xl font-bold leading-tight text-white drop-shadow-lg">
|
||||
{selectedPromotion.title}
|
||||
</h2>
|
||||
<p className="text-lg text-white drop-shadow-md">{selectedPromotion.description}</p>
|
||||
<div className="flex flex-row gap-2 mt-4">
|
||||
{
|
||||
(() => {
|
||||
switch (selectedPromotion.category) {
|
||||
case "PLEBDEVS":
|
||||
return (
|
||||
<>
|
||||
<GenericButton onClick={() => router.push('/about')} severity="success" icon={<i className="pi pi-question-circle pr-2 pb-[2px]" />} label="Learn More" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/content?tag=all')} severity="primary" icon={<i className="pi pi-eye pr-2" />} label="View all content" className="py-2 font-semibold" size="small" outlined />
|
||||
</>
|
||||
);
|
||||
case "COURSES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="View All Courses" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "WORKSHOPS":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=workshops')} icon={<i className="pi pi-video pr-2" />} label="View All Workshops" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "RESOURCES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=resources')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Resources" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "COMMUNITY":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/feed?channel=global')} icon={<i className="pi pi-users pr-2 pb-1" />} label="Open Community Feed" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "LIGHTNING / NOSTR":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/70 to-transparent rounded-lg" />
|
||||
<div className={`absolute bottom-0 left-0 p-6 space-y-2 ${isMobileView ? 'pb-16' : ''}`}>
|
||||
<div className="uppercase text-sm font-bold text-[#f8f8ff]">{selectedPromotion.category}</div>
|
||||
<h2 className="text-4xl font-bold leading-tight text-white drop-shadow-lg">
|
||||
{selectedPromotion.title}
|
||||
</h2>
|
||||
<p className="text-lg text-white drop-shadow-md">{selectedPromotion.description}</p>
|
||||
<div className="flex flex-row gap-2 mt-4">
|
||||
{
|
||||
(() => {
|
||||
switch (selectedPromotion.category) {
|
||||
case "PLEBDEVS":
|
||||
return (
|
||||
<>
|
||||
<GenericButton onClick={() => router.push('/about')} severity="success" icon={<i className="pi pi-question-circle pr-2 pb-[2px]" />} label="Learn More" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/content?tag=all')} severity="primary" icon={<i className="pi pi-eye pr-2" />} label="View all content" className="py-2 font-semibold" size="small" outlined />
|
||||
</>
|
||||
);
|
||||
case "COURSES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="View All Courses" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "WORKSHOPS":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=workshops')} icon={<i className="pi pi-video pr-2" />} label="View All Workshops" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "RESOURCES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=resources')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Resources" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "COMMUNITY":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/feed?channel=global')} icon={<i className="pi pi-users pr-2 pb-1" />} label="Open Community Feed" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "LIGHTNING / NOSTR":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className={isMobileView ? 'w-full p-4' : 'lg:w-1/3 p-6 space-y-4'}>
|
||||
{isMobileView ? (
|
||||
<div className="flex overflow-x-auto pb-4 space-x-4">
|
||||
{promotions.map((promo) => (
|
||||
<div
|
||||
key={promo.id}
|
||||
className={`flex-shrink-0 w-48 space-y-2 cursor-pointer transition-colors duration-200 ${selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
||||
} p-3 rounded-lg shadow-lg`}
|
||||
onClick={() => setSelectedPromotion(promo)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
||||
<div className="text-sm font-bold text-[#f8f8ff]">{promo.category}</div>
|
||||
</div>
|
||||
<h4 className="text-white font-semibold">{promo.title}</h4>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
promotions.map((promo) => (
|
||||
<div
|
||||
key={promo.id}
|
||||
className={`space-y-2 cursor-pointer transition-colors duration-200 ${selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
||||
} p-3 rounded-lg shadow-lg`}
|
||||
onClick={() => setSelectedPromotion(promo)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
||||
<div className="text-sm font-bold text-[#f8f8ff]">{promo.category}</div>
|
||||
</div>
|
||||
<h4 className="text-white font-semibold">{promo.title}</h4>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default InteractivePromotionalCarousel;
|
@ -179,7 +179,7 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
||||
anchor={nAddress}
|
||||
user={user?.pubkey || null}
|
||||
relays="wss://nos.lol/, wss://relay.damus.io/, wss://relay.snort.social/, wss://relay.nostr.band/, wss://relay.mutinywallet.com/, wss://relay.primal.net/"
|
||||
disable=""
|
||||
disable="zaps"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -85,7 +85,7 @@ const CommunityMessage = ({ message, searchQuery, windowWidth, platform }) => {
|
||||
anchor={nip19.noteEncode(message.id)}
|
||||
user={npub || null}
|
||||
relays="wss://nos.lol/, wss://relay.damus.io/, wss://relay.snort.social/, wss://relay.nostr.band/, wss://relay.mutinywallet.com/, wss://relay.primal.net/"
|
||||
disable=""
|
||||
disable="zaps"
|
||||
/>
|
||||
</div>
|
||||
</Panel>
|
||||
|
@ -1,137 +0,0 @@
|
||||
import Image from "next/image"
|
||||
import { useState } from "react"
|
||||
import { useImageProxy } from "@/hooks/useImageProxy"
|
||||
import GenericButton from "@/components/buttons/GenericButton"
|
||||
import { useRouter } from "next/router"
|
||||
const promotions = [
|
||||
{
|
||||
id: 1,
|
||||
category: "PLEBDEVS",
|
||||
title: "Learn how to code, build Bitcoin, Lightning, and Nostr apps, become a developer.",
|
||||
description: "PlebDevs is your gateway to mastering Bitcoin, Lightning, and Nostr technologies. Join our community of aspiring developers and start your journey today!",
|
||||
icon: "pi pi-code",
|
||||
image: "https://media.istockphoto.com/id/537331500/photo/programming-code-abstract-technology-background-of-software-deve.jpg?s=612x612&w=0&k=20&c=jlYes8ZfnCmD0lLn-vKvzQoKXrWaEcVypHnB5MuO-g8=",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
category: "COURSES",
|
||||
title: "Structured Learning Paths for Bitcoin Developers",
|
||||
description: "Dive into our comprehensive courses covering Bitcoin protocol, Lightning Network, and Nostr. From basics to advanced topics, we've got you covered.",
|
||||
icon: "pi pi-book",
|
||||
image: "https://media.istockphoto.com/id/1224500457/photo/programming-code-abstract-technology-background-of-software-developer-and-computer-script.jpg?s=612x612&w=0&k=20&c=nHMypkMTU1HUUW85Zt0Ff7MDbq17n0eVeXaoM9Knt4Q=",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
category: "WORKSHOPS",
|
||||
title: "Hands-on Video Workshops",
|
||||
description: "Watch and learn with our interactive video workshops. Get practical experience building real Bitcoin and Lightning applications.",
|
||||
icon: "pi pi-video",
|
||||
image: "https://newsroom.siliconslopes.com/content/images/2018/10/code.jpg",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
category: "RESOURCES",
|
||||
title: "In-depth Resources and Documentation",
|
||||
description: "Access our extensive library of resources, including guides, documentation, and best practices for Bitcoin development.",
|
||||
icon: "pi pi-file",
|
||||
image: "https://img.freepik.com/free-photo/programming-background-with-person-working-with-codes-computer_23-2150010125.jpg",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
category: "COMMUNITY",
|
||||
title: "Join Our Community",
|
||||
description: "Connect with other developers, share your projects, and get support from our community of Bitcoin enthusiasts.",
|
||||
icon: "pi pi-users",
|
||||
image: "https://pikwizard.com/pw/medium/50238b1cad4ff412fdafc1325efa1c9f.jpg",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
category: "LIGHTNING / NOSTR",
|
||||
title: "Lightning and Nostr integrated",
|
||||
description: "This platform is the first of its kind to integrate Lightning Network and Nostr protocols, allowing users to send and receive payments and interact with the Nostr network.",
|
||||
icon: "pi pi-bolt",
|
||||
image: "https://www.financemagnates.com/wp-content/uploads/2016/05/Bicoin-lightning.jpg",
|
||||
},
|
||||
]
|
||||
|
||||
export function InteractivePromotionalCarousel() {
|
||||
const [selectedPromotion, setSelectedPromotion] = useState(promotions[0])
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row bg-gray-900 text-white m-4 mx-14 rounded-lg h-[620px]">
|
||||
<div className="lg:w-2/3 relative">
|
||||
<Image
|
||||
src={returnImageProxy(selectedPromotion.image)}
|
||||
alt={selectedPromotion.title}
|
||||
width={800}
|
||||
height={600}
|
||||
className="object-cover w-full h-full rounded-lg opacity-75" // Added opacity
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black via-black/70 to-transparent rounded-lg" /> {/* Modified gradient */}
|
||||
<div className="absolute bottom-0 left-0 p-6 space-y-2">
|
||||
<div className="uppercase text-sm font-bold text-[#f8f8ff]">{selectedPromotion.category}</div> {/* Changed color */}
|
||||
<h2 className="text-4xl font-bold leading-tight text-white drop-shadow-lg">
|
||||
{selectedPromotion.title}
|
||||
</h2>
|
||||
<p className="text-lg text-white drop-shadow-md">{selectedPromotion.description}</p>
|
||||
<div className="flex flex-row gap-2 mt-4">
|
||||
{
|
||||
(() => {
|
||||
switch (selectedPromotion.category) {
|
||||
case "PLEBDEVS":
|
||||
return (
|
||||
<>
|
||||
<GenericButton onClick={() => router.push('/about')} severity="success" icon={<i className="pi pi-question-circle pr-2 pb-[2px]" />} label="Learn More" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
<GenericButton onClick={() => router.push('/content?tag=all')} severity="primary" icon={<i className="pi pi-eye pr-2" />} label="View all content" className="py-2 font-semibold" size="small" outlined />
|
||||
</>
|
||||
);
|
||||
case "COURSES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="View All Courses" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "WORKSHOPS":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=workshops')} icon={<i className="pi pi-video pr-2" />} label="View All Workshops" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "RESOURCES":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/content?tag=resources')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Resources" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "COMMUNITY":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/feed?channel=global')} icon={<i className="pi pi-users pr-2 pb-1" />} label="Open Community Feed" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
case "LIGHTNING / NOSTR":
|
||||
return (
|
||||
<GenericButton onClick={() => router.push('/subscribe')} severity="warning" icon={<i className="pi pi-star pr-2 pb-1" />} label="Subscribe" className="py-2 font-semibold" size="small" outlined />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="lg:w-1/3 p-6 space-y-4"> {/* Reduced space-y */}
|
||||
{promotions.map((promo) => (
|
||||
<div
|
||||
key={promo.id}
|
||||
className={`space-y-2 cursor-pointer transition-colors duration-200 ${
|
||||
selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
||||
} p-3 rounded-lg shadow-lg`} // Added shadow and changed hover color
|
||||
onClick={() => setSelectedPromotion(promo)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i> {/* Changed icon color */}
|
||||
<div className="text-sm font-bold text-[#f8f8ff]">{promo.category}</div> {/* Changed text style */}
|
||||
</div>
|
||||
<h4 className="text-white font-semibold">{promo.title}</h4> {/* Changed text style */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -7,9 +7,11 @@ import SearchBar from '../search/SearchBar';
|
||||
import 'primereact/resources/primereact.min.css';
|
||||
import 'primeicons/primeicons.css';
|
||||
import { useNDKContext } from '@/context/NDKContext';
|
||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||
|
||||
const Navbar = () => {
|
||||
const router = useRouter();
|
||||
const windowWidth = useWindowWidth();
|
||||
const navbarHeight = '60px';
|
||||
const {ndk} = useNDKContext();
|
||||
|
||||
@ -25,7 +27,7 @@ const Navbar = () => {
|
||||
/>
|
||||
<h1 className="text-white text-xl font-semibold max-tab:text-2xl max-mob:text-2xl">PlebDevs</h1>
|
||||
</div>
|
||||
{ndk && <SearchBar />}
|
||||
{ndk && windowWidth > 600 && <SearchBar />}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -9,12 +9,14 @@ import MessageDropdownItem from '@/components/content/dropdowns/MessageDropdownI
|
||||
import { useContentSearch } from '@/hooks/useContentSearch';
|
||||
import { useCommunitySearch } from '@/hooks/useCommunitySearch';
|
||||
import { useRouter } from 'next/router';
|
||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||
import styles from './searchbar.module.css';
|
||||
|
||||
const SearchBar = () => {
|
||||
const { searchContent, searchResults: contentResults } = useContentSearch();
|
||||
const { searchCommunity, searchResults: communityResults } = useCommunitySearch();
|
||||
const router = useRouter();
|
||||
const windowWidth = useWindowWidth();
|
||||
const [selectedSearchOption, setSelectedSearchOption] = useState({ name: 'Content', code: 'content', icon: 'pi pi-video' });
|
||||
const searchOptions = [
|
||||
{ name: 'Content', code: 'content', icon: 'pi pi-video' },
|
||||
@ -71,11 +73,11 @@ const SearchBar = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='absolute left-[50%] transform -translate-x-[50%]'>
|
||||
<div className={`absolute ${windowWidth < 700 ? "left-[40%]" : "left-[50%]"} transform -translate-x-[50%]`}>
|
||||
<IconField iconPosition="left">
|
||||
<InputIcon className="pi pi-search"> </InputIcon>
|
||||
<InputText
|
||||
className='w-[300px]'
|
||||
className={`${windowWidth > 845 ? 'w-[300px]' : 'w-[160px]'}`}
|
||||
value={searchTerm}
|
||||
onChange={handleSearch}
|
||||
placeholder={`Search ${selectedSearchOption.name.toLowerCase()}`}
|
||||
|
@ -76,7 +76,6 @@ const ContentPage = () => {
|
||||
const [processedCourses, setProcessedCourses] = useState([]);
|
||||
const [allContent, setAllContent] = useState([]);
|
||||
const [allTopics, setAllTopics] = useState([]);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedTopic, setSelectedTopic] = useState('All')
|
||||
const [filteredContent, setFilteredContent] = useState([]);
|
||||
|
||||
@ -165,13 +164,6 @@ const ContentPage = () => {
|
||||
<div className="w-full px-4">
|
||||
<div className="w-fit mx-4 mt-8 flex flex-col items-start">
|
||||
<h1 className="text-3xl font-bold mb-4 ml-1">All Content</h1>
|
||||
<InputText
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
placeholder="Search"
|
||||
icon="pi pi-search"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
<MenuTab
|
||||
items={['Courses', 'Workshops', 'Resources', ...allTopics.filter(topic => !['Courses', 'Workshops', 'Resources'].includes(topic))]}
|
||||
|
@ -4,12 +4,21 @@ import { useRouter } from "next/router";
|
||||
import CourseForm from "@/components/forms/course/CourseForm";
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||
|
||||
export default function Edit() {
|
||||
const [draft, setDraft] = useState(null);
|
||||
const { ndk } = useNDKContext();
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
const { isAdmin, isLoading } = useIsAdmin();
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
if (!isAdmin) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAdmin, router, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (router.isReady) {
|
||||
|
@ -6,17 +6,26 @@ import DraftCourseDetails from "@/components/content/courses/DraftCourseDetails"
|
||||
import DraftCourseLesson from "@/components/content/courses/DraftCourseLesson";
|
||||
import { useNDKContext } from "@/context/NDKContext";
|
||||
import { useSession } from "next-auth/react";
|
||||
|
||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||
const DraftCourse = () => {
|
||||
const { data: session, status } = useSession();
|
||||
const [course, setCourse] = useState(null);
|
||||
const [lessons, setLessons] = useState([]);
|
||||
const [lessonsWithAuthors, setLessonsWithAuthors] = useState([]);
|
||||
const { isAdmin, isLoading } = useIsAdmin();
|
||||
|
||||
const router = useRouter();
|
||||
const {ndk, addSigner} = useNDKContext();
|
||||
const { slug } = router.query;
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
if (!isAdmin) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAdmin, router, isLoading]);
|
||||
|
||||
const fetchAuthor = useCallback(async (pubkey) => {
|
||||
if (!pubkey) return;
|
||||
const author = await ndk.getUser({ pubkey });
|
||||
|
@ -4,10 +4,19 @@ import axios from "axios";
|
||||
import ResourceForm from "@/components/forms/ResourceForm";
|
||||
import WorkshopForm from "@/components/forms/WorkshopForm";
|
||||
import CourseForm from "@/components/forms/course/CourseForm";
|
||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||
|
||||
const Edit = () => {
|
||||
const [draft, setDraft] = useState(null);
|
||||
const router = useRouter();
|
||||
const { isAdmin, isLoading } = useIsAdmin();
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
if (!isAdmin) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAdmin, router, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (router.isReady) {
|
||||
|
@ -18,6 +18,7 @@ import 'primeicons/primeicons.css';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { validateEvent } from '@/utils/nostr';
|
||||
import { defaultRelayUrls } from '@/context/NDKContext';
|
||||
import { useIsAdmin } from "@/hooks/useIsAdmin";
|
||||
|
||||
const MDDisplay = dynamic(
|
||||
() => import("@uiw/react-markdown-preview"),
|
||||
@ -36,6 +37,15 @@ export default function Draft() {
|
||||
const router = useRouter();
|
||||
const { showToast } = useToast();
|
||||
const { ndk, addSigner } = useNDKContext();
|
||||
const { isAdmin, isLoading } = useIsAdmin();
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
if (!isAdmin) {
|
||||
router.push('/');
|
||||
}
|
||||
}, [isAdmin, router, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
|
@ -2,12 +2,9 @@ import Head from 'next/head';
|
||||
import React 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 { InteractivePromotionalCarousel } from '@/components/interactive-news-carousel';
|
||||
import InteractivePromotionalCarousel from '@/components/content/carousels/InteractivePromotionalCarousel';
|
||||
|
||||
// todo append link to plebdevs item in each published course or resource description
|
||||
// todo perhaps need to update slug on details on course pages to be d tag instead of db id
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
@ -18,7 +15,6 @@ export default function Home() {
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<main>
|
||||
{/* <HeroBanner /> */}
|
||||
<InteractivePromotionalCarousel />
|
||||
<CoursesCarousel />
|
||||
<WorkshopsCarousel />
|
||||
|
@ -3,7 +3,7 @@ export const highlightText = (text, query) => {
|
||||
const parts = text.split(new RegExp(`(${query})`, 'gi'));
|
||||
return parts.map((part, index) =>
|
||||
part.toLowerCase() === query.toLowerCase()
|
||||
? <span key={index} className="bg-yellow-300 text-black">{part}</span>
|
||||
? <span key={index} className="text-yellow-300">{part}</span>
|
||||
: part
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user