Consolidate profile and settings tabs, fix some styles

This commit is contained in:
austinkelsay 2025-03-28 10:59:52 -05:00
parent ffa57f9455
commit 3a59114683
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE
11 changed files with 41 additions and 74 deletions

View File

@ -3,7 +3,7 @@ import { Dialog } from 'primereact/dialog';
import { Tooltip } from 'primereact/tooltip';
import useWindowWidth from '@/hooks/useWindowWidth';
const MoreInfo = ({ tooltip, modalTitle, modalBody, className = '' }) => {
const MoreInfo = ({ tooltip, modalTitle, modalBody, className = '', tooltipPosition = 'right' }) => {
const [visible, setVisible] = useState(false);
const windowWidth = useWindowWidth();
const isMobile = windowWidth < 768;
@ -14,11 +14,9 @@ const MoreInfo = ({ tooltip, modalTitle, modalBody, className = '' }) => {
className={`pi pi-question-circle cursor-pointer ${className}`}
onClick={() => setVisible(true)}
data-pr-tooltip={tooltip}
data-pr-position="right"
data-pr-at="right+5 top"
data-pr-my="left center-2"
data-pr-position={tooltipPosition}
/>
{!isMobile && <Tooltip target=".pi-question-circle" />}
{!isMobile && <Tooltip target=".pi-question-circle" position={tooltipPosition} />}
<Dialog
header={modalTitle}

View File

@ -1,20 +1,19 @@
import React, { useState, useRef, useEffect } from 'react';
import Image from 'next/image';
import UserAvatar from './user/UserAvatar';
import { Menubar } from 'primereact/menubar';
import { Menu } from 'primereact/menu';
import { useRouter } from 'next/router';
import SearchBar from '../search/SearchBar';
import { useSession } from 'next-auth/react';
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();
const { data: session } = useSession();
const [isHovered, setIsHovered] = useState(false);
const [showMobileSearch, setShowMobileSearch] = useState(false);
const menu = useRef(null);
@ -47,7 +46,7 @@ const Navbar = () => {
{
label: 'Subscribe',
icon: 'pi pi-star',
command: () => router.push('/about')
command: () => session?.user ? router.push('/profile?tab=subscribe') : router.push('/about')
},
{
label: 'About',
@ -62,7 +61,7 @@ const Navbar = () => {
<div className='px-10 py-8 bg-gray-800 border-t-0 border-l-0 border-r-0 rounded-none fixed z-10 w-[100vw] max-tab:px-[5%] max-mob:px-[5%] flex justify-between' style={{ height: navbarHeight }}>
{/* Left section */}
<div className='flex items-center flex-1'>
<div onClick={() => router.push('/')} className="flex flex-row items-center justify-center cursor-pointer">
<div onClick={() => router.push('/')} className="flex flex-row items-center justify-center cursor-pointer hover:opacity-80">
<Image
alt="logo"
src="/images/plebdevs-icon.png"

View File

@ -58,10 +58,10 @@ const UserRelaysTable = ({ ndk, userRelays, setUserRelays, reInitializeNDK }) =>
<div className="text-[#f8f8ff]">
<div className="flex items-center justify-between">
<div>
<h2 className="text-xl font-bold">Relays</h2>
<p className="text-gray-400">Manage your connected relays</p>
</div>
<GenericButton
outlined
icon="pi pi-plus"
label="Add Relay"
severity="success"
@ -78,7 +78,7 @@ const UserRelaysTable = ({ ndk, userRelays, setUserRelays, reInitializeNDK }) =>
className="flex-1"
/>
<GenericButton
label="Add"
label="+"
severity="success"
outlined
onClick={addRelay}
@ -122,7 +122,7 @@ const UserRelaysTable = ({ ndk, userRelays, setUserRelays, reInitializeNDK }) =>
};
return (
<div className="bg-gray-800 rounded-lg border border-gray-700 w-full">
<div className="w-full">
<DataTable
value={userRelays}
className="border-none"

View File

@ -10,6 +10,7 @@ import UserProgress from "@/components/profile/progress/UserProgress";
import UserProgressTable from '@/components/profile/DataTables/UserProgressTable';
import UserPurchaseTable from '@/components/profile/DataTables/UserPurchaseTable';
import BitcoinLightningCard from '@/components/profile/BitcoinLightningCard';
import UserAccountLinking from "@/components/profile/UserAccountLinking";
const UserProfile = () => {
const windowWidth = useWindowWidth();
@ -42,6 +43,7 @@ const UserProfile = () => {
<div className="w-[22%] h-full max-lap:w-full">
{user && <UserProfileCard user={user} />}
<BitcoinLightningCard />
{user && <UserAccountLinking session={session} />}
</div>
<div className="w-[78%] flex flex-col justify-center mx-auto max-lap:w-full">

View File

@ -2,19 +2,24 @@ import React, { useRef, useState } from 'react';
import Image from 'next/image';
import { Menu } from 'primereact/menu';
import { Tooltip } from 'primereact/tooltip';
import { Dialog } from 'primereact/dialog';
import { nip19 } from 'nostr-tools';
import { useImageProxy } from '@/hooks/useImageProxy';
import { useToast } from '@/hooks/useToast';
import UserBadges from '@/components/profile/UserBadges';
import useWindowWidth from '@/hooks/useWindowWidth';
import MoreInfo from '@/components/MoreInfo';
import UserRelaysTable from '@/components/profile/DataTables/UserRelaysTable';
import { useNDKContext } from "@/context/NDKContext";
const UserProfileCard = ({ user }) => {
const [showBadges, setShowBadges] = useState(false);
const [showRelaysModal, setShowRelaysModal] = useState(false);
const menu = useRef(null);
const { showToast } = useToast();
const { returnImageProxy } = useImageProxy();
const windowWidth = useWindowWidth();
const { ndk, userRelays, setUserRelays, reInitializeNDK } = useNDKContext();
const copyToClipboard = (text) => {
navigator.clipboard.writeText(text);
@ -43,6 +48,11 @@ const UserProfileCard = ({ user }) => {
label: 'Open Nostr Profile',
icon: 'pi pi-external-link',
command: () => window.open(`https://nostr.com/${nip19.npubEncode(user?.pubkey)}`, '_blank')
},
{
label: 'Manage Relays',
icon: 'pi pi-server',
command: () => setShowRelaysModal(true)
}
];
@ -282,6 +292,20 @@ const UserProfileCard = ({ user }) => {
visible={showBadges}
onHide={() => setShowBadges(false)}
/>
<Dialog
visible={showRelaysModal}
onHide={() => setShowRelaysModal(false)}
header="Manage Relays"
className="w-[90vw] max-w-[800px]"
modal
>
<UserRelaysTable
ndk={ndk}
userRelays={userRelays}
setUserRelays={setUserRelays}
reInitializeNDK={reInitializeNDK}
/>
</Dialog>
</>
);
};

View File

@ -1,47 +0,0 @@
import React, { useState, useEffect } from "react";
import UserProfileCard from "@/components/profile/UserProfileCard";
import { useSession } from 'next-auth/react';
import { useNDKContext } from "@/context/NDKContext";
import useWindowWidth from "@/hooks/useWindowWidth";
import UserRelaysTable from "@/components/profile/DataTables/UserRelaysTable";
import UserAccountLinking from "@/components/profile/UserAccountLinking";
const UserSettings = () => {
const [user, setUser] = useState(null);
const { ndk, userRelays, setUserRelays, reInitializeNDK } = useNDKContext();
const { data: session } = useSession();
const windowWidth = useWindowWidth();
useEffect(() => {
if (session?.user) {
setUser(session.user);
}
}, [session]);
return (
user && (
<div className="py-4 px-1">
{windowWidth < 768 && (
<h1 className="text-3xl font-bold mb-6">Settings</h1>
)}
<div className="w-full flex flex-row max-lap:flex-col">
<div className="w-[22%] h-full max-lap:w-full">
<UserProfileCard user={user} />
{user && <UserAccountLinking session={session} />}
</div>
<div className="w-[78%] flex flex-col justify-center mx-2 max-lap:mx-0 max-lap:w-full">
<UserRelaysTable
ndk={ndk}
userRelays={userRelays}
setUserRelays={setUserRelays}
reInitializeNDK={reInitializeNDK}
/>
</div>
</div>
</div>
)
);
};
export default UserSettings;

View File

@ -117,7 +117,7 @@ const UserSubscription = () => {
{!subscribed && (
<Card
title="Subscribe to PlebDevs"
className="mb-2 max-lap:h-auto border border-gray-700"
className="max-lap:h-auto border border-gray-700"
pt={{
body: { className: 'py-2' },
content: { className: 'pt-0' }
@ -190,7 +190,7 @@ const UserSubscription = () => {
</>
)}
<Card title="Frequently Asked Questions" className="border border-gray-700 rounded-lg">
<Card title="Frequently Asked Questions" className="mt-2 border border-gray-700 rounded-lg">
<div className="flex flex-col gap-4">
<div>
<h3 className="text-lg font-semibold">How does the subscription work?</h3>

View File

@ -9,7 +9,7 @@ const appConfig = {
"wss://purplerelay.com/",
"wss://relay.devs.tools/"
],
authorPubkeys: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345"],
authorPubkeys: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345", "6260f29fa75c91aaa292f082e5e87b438d2ab4fdf96af398567b01802ee2fcd4"],
customLightningAddresses: [
{
// todo remove need for lowercase

View File

@ -211,6 +211,7 @@ const AboutPage = () => {
<h2 className="text-xl font-bold m-0">Subscribe to PlebDevs</h2>
<MoreInfo
tooltip="Subscription FAQ"
tooltipPosition='top'
modalTitle="Frequently Asked Questions"
modalBody={faqContent}
className="text-gray-400 hover:text-white"

View File

@ -116,8 +116,6 @@ export default function Home() {
const [selectedTopic, setSelectedTopic] = useState('Top');
const [filteredContent, setFilteredContent] = useState([]);
const memoizedFilteredContent = useMemo(() => filteredContent, [filteredContent]);
useEffect(() => {
if (documents && !documentsLoading) {
const processedDocuments = documents.map(document => ({...parseEvent(document), type: 'document'}));

View File

@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react";
import { TabView, TabPanel } from "primereact/tabview";
import UserProfile from "@/components/profile/UserProfile";
import UserSettings from "@/components/profile/UserSettings";
import UserContent from "@/components/profile/UserContent";
import UserSubscription from "@/components/profile/subscription/UserSubscription";
import { useRouter } from "next/router";
@ -16,7 +15,7 @@ const Profile = () => {
const [activeTab, setActiveTab] = useState(0);
const {isAdmin, isLoading} = useIsAdmin();
const tabs = ["profile", "settings", "content", "subscribe"];
const tabs = ["profile", "content", "subscribe"];
useEffect(() => {
const { tab } = router.query;
@ -74,13 +73,6 @@ const Profile = () => {
}}>
<UserProfile />
</TabPanel>
<TabPanel header="Settings" pt={{
headerAction: {
className: "bg-transparent"
},
}}>
<UserSettings />
</TabPanel>
{isAdmin && (
<TabPanel header="Content" pt={{
headerAction: {