mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-06 18:31:00 +00:00
Styling fixes, add video to promotional carousel
This commit is contained in:
parent
3ce3a2f037
commit
17ca8fcf59
BIN
public/videos/plebdevs-montage.mp4
Normal file
BIN
public/videos/plebdevs-montage.mp4
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import { useState } from "react"
|
import { useState, useRef, useEffect } from "react"
|
||||||
import { useImageProxy } from "@/hooks/useImageProxy"
|
import { useImageProxy } from "@/hooks/useImageProxy"
|
||||||
import GenericButton from "@/components/buttons/GenericButton"
|
import GenericButton from "@/components/buttons/GenericButton"
|
||||||
import { useRouter } from "next/router"
|
import { useRouter } from "next/router"
|
||||||
@ -13,61 +13,61 @@ const promotions = [
|
|||||||
title: "Developer education & community platform",
|
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!",
|
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",
|
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=",
|
video: "/videos/plebdevs-montage.mp4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
category: "COURSES",
|
category: "CONTENT",
|
||||||
title: "Structured learning paths for new devs",
|
title: "Comprehensive Learning Resources",
|
||||||
description: "Dive into our comprehensive courses covering Bitcoin protocol, Lightning Network, and Nostr. From basics to advanced topics, we've got you covered.",
|
description: "Access our extensive library of courses, videos, and documents. From structured learning paths to hands-on workshops, we've got everything you need to master Bitcoin, Lightning, and Nostr development.",
|
||||||
icon: "pi pi-book",
|
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=",
|
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,
|
id: 3,
|
||||||
category: "VIDEOS",
|
|
||||||
title: "Hands-on workshops and devleloper video content",
|
|
||||||
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: "DOCUMENTS",
|
|
||||||
title: "In-depth Resources and Documentation",
|
|
||||||
description: "Access our extensive library of documents, including guides, resources, 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",
|
category: "COMMUNITY",
|
||||||
title: "Join Our Community",
|
title: "Join Our Community of learners, hackers, and plebs",
|
||||||
description: "Connect with other developers, share your projects, and get support from our community of Bitcoin enthusiasts.",
|
description: "Connect with other developers, share your projects, and get support from our community of Bitcoin enthusiasts.",
|
||||||
icon: "pi pi-users",
|
icon: "pi pi-users",
|
||||||
image: "https://pikwizard.com/pw/medium/50238b1cad4ff412fdafc1325efa1c9f.jpg",
|
image: "https://pikwizard.com/pw/medium/50238b1cad4ff412fdafc1325efa1c9f.jpg",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
id: 4,
|
||||||
category: "LIGHTNING / NOSTR",
|
category: "LIGHTNING / NOSTR",
|
||||||
title: "Lightning and Nostr integrated",
|
title: "Lightning and Nostr integrated platform",
|
||||||
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.",
|
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",
|
icon: "pi pi-bolt",
|
||||||
image: "https://www.financemagnates.com/wp-content/uploads/2016/05/Bicoin-lightning.jpg",
|
image: "https://www.financemagnates.com/wp-content/uploads/2016/05/Bicoin-lightning.jpg",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// todo bigger ore simple CTA to get users into the content
|
|
||||||
const InteractivePromotionalCarousel = () => {
|
const InteractivePromotionalCarousel = () => {
|
||||||
const [selectedPromotion, setSelectedPromotion] = useState(promotions[0])
|
const [selectedPromotion, setSelectedPromotion] = useState(promotions[0])
|
||||||
const { returnImageProxy } = useImageProxy();
|
const { returnImageProxy } = useImageProxy();
|
||||||
const windowWidth = useWindowWidth();
|
const windowWidth = useWindowWidth();
|
||||||
const isMobileView = windowWidth <= 1360;
|
const isMobileView = windowWidth <= 1360;
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const videoRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (videoRef.current && selectedPromotion.video) {
|
||||||
|
videoRef.current.play();
|
||||||
|
}
|
||||||
|
}, [selectedPromotion]);
|
||||||
|
|
||||||
return (
|
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]'} ${isMobileView ? 'w-full mx-0 ml-0 mt-0' : null}`}>
|
<div className={`flex ${isMobileView ? 'flex-col' : 'flex-row'} bg-gray-900 text-white m-4 mx-14 rounded-lg ${isMobileView ? 'h-auto' : 'h-[620px]'} ${isMobileView ? 'w-full mx-0 ml-0 mt-0' : null}`}>
|
||||||
<div className={isMobileView ? 'w-full' : 'lg:w-2/3 relative'}>
|
<div className={isMobileView ? 'w-full' : 'lg:w-2/3 relative'}>
|
||||||
|
{selectedPromotion.video ? (
|
||||||
|
<video
|
||||||
|
ref={videoRef}
|
||||||
|
src={selectedPromotion.video}
|
||||||
|
className={`object-cover w-full ${isMobileView ? 'h-[300px]' : 'h-full'} rounded-lg`}
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
playsInline
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<Image
|
<Image
|
||||||
src={returnImageProxy(selectedPromotion.image)}
|
src={returnImageProxy(selectedPromotion.image)}
|
||||||
alt={selectedPromotion.title}
|
alt={selectedPromotion.title}
|
||||||
@ -75,6 +75,7 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
height={600}
|
height={600}
|
||||||
className={`object-cover w-full ${isMobileView ? 'h-[300px]' : 'h-full'} rounded-lg opacity-75`}
|
className={`object-cover w-full ${isMobileView ? 'h-[300px]' : 'h-full'} rounded-lg opacity-75`}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
{isMobileView ? (
|
{isMobileView ? (
|
||||||
<div className="p-6 space-y-2">
|
<div className="p-6 space-y-2">
|
||||||
<div className="uppercase text-sm font-bold text-[#f8f8ff]">{selectedPromotion.category}</div>
|
<div className="uppercase text-sm font-bold text-[#f8f8ff]">{selectedPromotion.category}</div>
|
||||||
@ -93,17 +94,13 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
<GenericButton onClick={() => router.push('/content?tag=all')} severity="primary" icon={<i className="pi pi-eye pr-2" />} label="View all content" className="w-fit 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="w-fit py-2 font-semibold" size="small" outlined />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
case "COURSES":
|
case "CONTENT":
|
||||||
return (
|
return (
|
||||||
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="View All Courses" className="w-fit py-2 font-semibold" size="small" outlined />
|
<>
|
||||||
);
|
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="Courses" className="py-2 font-semibold" size="small" outlined />
|
||||||
case "VIDEOS":
|
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="Videos" className="py-2 font-semibold" size="small" outlined />
|
||||||
return (
|
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="Documents" className="py-2 font-semibold" size="small" outlined />
|
||||||
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="w-fit py-2 font-semibold" size="small" outlined />
|
</>
|
||||||
);
|
|
||||||
case "DOCUMENTS":
|
|
||||||
return (
|
|
||||||
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Documents" className="w-fit py-2 font-semibold" size="small" outlined />
|
|
||||||
);
|
);
|
||||||
case "COMMUNITY":
|
case "COMMUNITY":
|
||||||
return (
|
return (
|
||||||
@ -141,17 +138,13 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
<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 />
|
<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":
|
case "CONTENT":
|
||||||
return (
|
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 />
|
<>
|
||||||
);
|
<GenericButton onClick={() => router.push('/content?tag=courses')} icon={<i className="pi pi-book pr-2 pb-1" />} label="Courses" className="py-2 font-semibold" size="small" outlined />
|
||||||
case "VIDEOS":
|
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="Videos" className="py-2 font-semibold" size="small" outlined />
|
||||||
return (
|
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="Documents" className="py-2 font-semibold" size="small" outlined />
|
||||||
<GenericButton onClick={() => router.push('/content?tag=videos')} icon={<i className="pi pi-video pr-2" />} label="View All Videos" className="py-2 font-semibold" size="small" outlined />
|
</>
|
||||||
);
|
|
||||||
case "DOCUMENTS":
|
|
||||||
return (
|
|
||||||
<GenericButton onClick={() => router.push('/content?tag=documents')} icon={<i className="pi pi-file pr-2 pb-1" />} label="View All Documents" className="py-2 font-semibold" size="small" outlined />
|
|
||||||
);
|
);
|
||||||
case "COMMUNITY":
|
case "COMMUNITY":
|
||||||
return (
|
return (
|
||||||
@ -177,8 +170,8 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
{promotions.map((promo) => (
|
{promotions.map((promo) => (
|
||||||
<div
|
<div
|
||||||
key={promo.id}
|
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"
|
className={`flex-shrink-0 w-64 space-y-4 cursor-pointer transition-colors duration-200 bg-gray-800 ${selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
||||||
} p-3 rounded-lg shadow-lg`}
|
} p-4 rounded-lg shadow-lg`}
|
||||||
onClick={() => setSelectedPromotion(promo)}>
|
onClick={() => setSelectedPromotion(promo)}>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
||||||
@ -192,14 +185,14 @@ const InteractivePromotionalCarousel = () => {
|
|||||||
promotions.map((promo) => (
|
promotions.map((promo) => (
|
||||||
<div
|
<div
|
||||||
key={promo.id}
|
key={promo.id}
|
||||||
className={`space-y-2 cursor-pointer transition-colors duration-200 ${selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
className={`space-y-8 cursor-pointer transition-colors duration-200 bg-gray-800 ${selectedPromotion.id === promo.id ? "bg-gray-800" : "hover:bg-gray-700"
|
||||||
} p-3 rounded-lg shadow-lg`}
|
} p-4 rounded-lg shadow-lg`}
|
||||||
onClick={() => setSelectedPromotion(promo)}>
|
onClick={() => setSelectedPromotion(promo)}>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
<i className={`${promo.icon} text-2xl text-[#f8f8ff]`}></i>
|
||||||
<div className="text-sm font-bold text-[#f8f8ff]">{promo.category}</div>
|
<div className="text-lg font-semibold text-[#f8f8ff]">{promo.category}</div>
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-white font-semibold">{promo.title}</h4>
|
<h4 className="text-white text-lg">{promo.title}</h4>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
@ -103,7 +103,7 @@ export default function CourseDetailsNew({ processedEvent, paidCourse, lessons,
|
|||||||
if (paidCourse && !decryptionPerformed) {
|
if (paidCourse && !decryptionPerformed) {
|
||||||
return (
|
return (
|
||||||
<CoursePaymentButton
|
<CoursePaymentButton
|
||||||
lnAddress={lnAddress}
|
lnAddress={author?.lnAddress}
|
||||||
amount={processedEvent.price}
|
amount={processedEvent.price}
|
||||||
onSuccess={handlePaymentSuccess}
|
onSuccess={handlePaymentSuccess}
|
||||||
onError={handlePaymentError}
|
onError={handlePaymentError}
|
||||||
|
@ -21,8 +21,6 @@ const MDDisplay = dynamic(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const lnAddress = process.env.NEXT_PUBLIC_LIGHTNING_ADDRESS;
|
|
||||||
|
|
||||||
const DocumentDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
const DocumentDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -96,7 +94,7 @@ const DocumentDetails = ({ processedEvent, topics, title, summary, image, price,
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row items-center justify-center w-full mt-4">
|
<div className="flex flex-row items-center justify-center w-full mt-4">
|
||||||
<ResourcePaymentButton
|
<ResourcePaymentButton
|
||||||
lnAddress={lnAddress}
|
lnAddress={author?.lightningAddress}
|
||||||
amount={price}
|
amount={price}
|
||||||
onSuccess={handlePaymentSuccess}
|
onSuccess={handlePaymentSuccess}
|
||||||
onError={handlePaymentError}
|
onError={handlePaymentError}
|
||||||
|
@ -21,8 +21,6 @@ const MDDisplay = dynamic(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const lnAddress = process.env.NEXT_PUBLIC_LIGHTNING_ADDRESS;
|
|
||||||
|
|
||||||
const VideoDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
const VideoDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -99,7 +97,7 @@ const VideoDetails = ({ processedEvent, topics, title, summary, image, price, au
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row items-center justify-center w-full mt-4 z-10">
|
<div className="flex flex-row items-center justify-center w-full mt-4 z-10">
|
||||||
<ResourcePaymentButton
|
<ResourcePaymentButton
|
||||||
lnAddress={lnAddress}
|
lnAddress={author?.lnAddress}
|
||||||
amount={price}
|
amount={price}
|
||||||
onSuccess={handlePaymentSuccess}
|
onSuccess={handlePaymentSuccess}
|
||||||
onError={handlePaymentError}
|
onError={handlePaymentError}
|
||||||
|
@ -23,7 +23,6 @@ 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 DocumentForm = ({ draft = null, isPublished = false }) => {
|
const DocumentForm = ({ 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 || '');
|
||||||
|
@ -41,7 +41,7 @@ const allTasks = [
|
|||||||
const UserProgress = () => {
|
const UserProgress = () => {
|
||||||
const [progress, setProgress] = useState(0);
|
const [progress, setProgress] = useState(0);
|
||||||
const [currentTier, setCurrentTier] = useState('Pleb');
|
const [currentTier, setCurrentTier] = useState('Pleb');
|
||||||
const [expanded, setExpanded] = useState(null);
|
const [expandedItems, setExpandedItems] = useState({});
|
||||||
const [completedCourses, setCompletedCourses] = useState([]);
|
const [completedCourses, setCompletedCourses] = useState([]);
|
||||||
const [tasks, setTasks] = useState([]);
|
const [tasks, setTasks] = useState([]);
|
||||||
|
|
||||||
@ -91,6 +91,13 @@ const UserProgress = () => {
|
|||||||
fetchProgress();
|
fetchProgress();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleAccordionChange = (index, isExpanded) => {
|
||||||
|
setExpandedItems(prev => ({
|
||||||
|
...prev,
|
||||||
|
[index]: isExpanded
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-800 rounded-3xl p-6 w-[500px] max-mob:w-full max-tab:w-full mx-auto my-8">
|
<div className="bg-gray-800 rounded-3xl p-6 w-[500px] max-mob:w-full max-tab:w-full mx-auto my-8">
|
||||||
<h1 className="text-3xl font-bold text-white mb-2">Dev Journey (Coming Soon)</h1>
|
<h1 className="text-3xl font-bold text-white mb-2">Dev Journey (Coming Soon)</h1>
|
||||||
@ -115,7 +122,11 @@ const UserProgress = () => {
|
|||||||
{tasks.map((task, index) => (
|
{tasks.map((task, index) => (
|
||||||
<li key={index}>
|
<li key={index}>
|
||||||
{task.subTasks ? (
|
{task.subTasks ? (
|
||||||
<Accordion className="border-none" onTabOpen={(e) => setExpanded(true)} onTabClose={(e) => setExpanded(false)}>
|
<Accordion
|
||||||
|
className="border-none"
|
||||||
|
onTabChange={(e) => handleAccordionChange(index, e.index === 0)}
|
||||||
|
activeIndex={expandedItems[index] ? 0 : null}
|
||||||
|
>
|
||||||
<AccordionTab
|
<AccordionTab
|
||||||
pt={{
|
pt={{
|
||||||
root: { className: 'border-none p-0' },
|
root: { className: 'border-none p-0' },
|
||||||
@ -129,10 +140,12 @@ const UserProgress = () => {
|
|||||||
<div className="bg-gray-800 flex items-center justify-between w-full font-normal">
|
<div className="bg-gray-800 flex items-center justify-between w-full font-normal">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div className="w-6 h-6 bg-gray-700 rounded-full flex items-center justify-center mr-3">
|
<div className="w-6 h-6 bg-gray-700 rounded-full flex items-center justify-center mr-3">
|
||||||
<i className="pi pi-info-circle text-white text-lg"></i>
|
<i className="pi pi-info-circle text-white text-2xl"></i>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center justify-between w-[160px] max-mob:w-[100px]">
|
||||||
<span className="text-lg text-gray-400">{task.status}</span>
|
<span className="text-lg text-gray-400">{task.status}</span>
|
||||||
<i className={`pi pi-chevron-down text-gray-400 ml-2 transition-transform duration-300 ${expanded ? 'rotate-180' : ''}`} />
|
<i className={`pi pi-chevron-down text-gray-400 ml-2 transition-transform duration-300 ${expandedItems[index] ? 'rotate-180' : ''}`} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="bg-blue-500 text-white text-xs px-2 py-1 rounded-full w-20 text-center">
|
<span className="bg-blue-500 text-white text-xs px-2 py-1 rounded-full w-20 text-center">
|
||||||
{task.tier}
|
{task.tier}
|
||||||
|
@ -98,28 +98,30 @@ const AboutPage = () => {
|
|||||||
severity="secondary"
|
severity="secondary"
|
||||||
outlined
|
outlined
|
||||||
icon="pi pi-github"
|
icon="pi pi-github"
|
||||||
label="GitHub"
|
tooltip="Github"
|
||||||
|
className="text-gray-300"
|
||||||
onClick={() => window.open('https://github.com/pleb-devs', '_blank')}
|
onClick={() => window.open('https://github.com/pleb-devs', '_blank')}
|
||||||
/>
|
/>
|
||||||
<GenericButton
|
<GenericButton
|
||||||
severity="info"
|
severity="info"
|
||||||
outlined
|
outlined
|
||||||
icon="pi pi-twitter"
|
icon="pi pi-twitter"
|
||||||
label="X.com"
|
tooltip="X"
|
||||||
onClick={() => window.open('https://x.com/pleb_devs', '_blank')}
|
onClick={() => window.open('https://x.com/pleb_devs', '_blank')}
|
||||||
/>
|
/>
|
||||||
<GenericButton
|
<GenericButton
|
||||||
severity="help"
|
severity="help"
|
||||||
outlined
|
outlined
|
||||||
icon={<Image src={NostrIcon} alt="Nostr" width={20} height={20} className="mr-2" />}
|
icon={<Image src={NostrIcon} alt="Nostr" width={20} height={20} className="mr-0" />}
|
||||||
label="Nostr"
|
tooltip="Nostr"
|
||||||
onClick={() => window.open('https://nostr.com/plebdevs@plebdevs.com', '_blank')}
|
onClick={() => window.open('https://nostr.com/plebdevs@plebdevs.com', '_blank')}
|
||||||
/>
|
/>
|
||||||
<GenericButton
|
<GenericButton
|
||||||
severity="warning"
|
severity="warning"
|
||||||
|
className="text-yellow-400"
|
||||||
outlined
|
outlined
|
||||||
icon="pi pi-bolt"
|
icon="pi pi-bolt"
|
||||||
label="Donate"
|
tooltip="Donate"
|
||||||
onClick={() => copyToClipboard("austin@bitcoinpleb.dev")}
|
onClick={() => copyToClipboard("austin@bitcoinpleb.dev")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@ import VideosCarousel from '@/components/content/carousels/VideosCarousel';
|
|||||||
import DocumentsCarousel from '@/components/content/carousels/DocumentsCarousel';
|
import DocumentsCarousel from '@/components/content/carousels/DocumentsCarousel';
|
||||||
import InteractivePromotionalCarousel from '@/components/content/carousels/InteractivePromotionalCarousel';
|
import InteractivePromotionalCarousel from '@/components/content/carousels/InteractivePromotionalCarousel';
|
||||||
|
|
||||||
// todo: make paid course videos and documents not appear in carousels
|
// todo: make paid course video and document lessons not appear in carousels
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -34,6 +34,12 @@ export const findKind0Fields = async (kind0) => {
|
|||||||
fields.pubkey = pubkey;
|
fields.pubkey = pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lud16 = findTruthyPropertyValue(kind0, ['lud16', 'lightning', 'lnurl', 'lnurlp', 'lnurlw']);
|
||||||
|
|
||||||
|
if (lud16) {
|
||||||
|
fields.lightningAddress = lud16;
|
||||||
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user