From 983153f4b221f35e7f20c90a1199812e29db4d51 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 29 Sep 2026 11:47:33 +0530 Subject: [PATCH 01/19] fix: network indicator --- apps/web/src/components/dao-shell.tsx | 2 +- apps/web/src/components/dashboard/dashboard-header.tsx | 4 ++++ apps/web/src/components/network-indicator.tsx | 6 ++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/dao-shell.tsx b/apps/web/src/components/dao-shell.tsx index b8c1ecc..d71c21e 100644 --- a/apps/web/src/components/dao-shell.tsx +++ b/apps/web/src/components/dao-shell.tsx @@ -136,7 +136,7 @@ export function DaoShell({ children }: { children: ReactNode }) {
- +
diff --git a/apps/web/src/components/dashboard/dashboard-header.tsx b/apps/web/src/components/dashboard/dashboard-header.tsx index d2d69ed..81e72e2 100644 --- a/apps/web/src/components/dashboard/dashboard-header.tsx +++ b/apps/web/src/components/dashboard/dashboard-header.tsx @@ -2,7 +2,9 @@ import { Menu } from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; +import { NetworkIndicator } from '@/components/network-indicator'; import { WalletControls } from '@/components/wallet-controls'; +import { useDaoSessionStore } from '@/stores/dao-session-store'; interface DashboardHeaderProps { showMenuButton?: boolean; @@ -10,6 +12,7 @@ interface DashboardHeaderProps { } export function DashboardHeader({ showMenuButton = false, onMenuClick }: DashboardHeaderProps) { + const session = useDaoSessionStore(); return (
{showMenuButton ? ( @@ -25,6 +28,7 @@ export function DashboardHeader({ showMenuButton = false, onMenuClick }: Dashboa
+
diff --git a/apps/web/src/components/network-indicator.tsx b/apps/web/src/components/network-indicator.tsx index 99bb489..4d4a915 100644 --- a/apps/web/src/components/network-indicator.tsx +++ b/apps/web/src/components/network-indicator.tsx @@ -1,9 +1,11 @@ interface NetworkIndicatorProps { - networkLabel: string; isConnected?: boolean; } +import { getNetworkConfig, type NetworkName } from '@/config/networks'; + +export function NetworkIndicator({ isConnected = true }: NetworkIndicatorProps) { + const { label: networkLabel } = getNetworkConfig((process.env.NEXT_PUBLIC_NETWORK || 'testnet') as NetworkName); -export function NetworkIndicator({ networkLabel, isConnected = true }: NetworkIndicatorProps) { if (!isConnected) { return null; } From 8f232b354d5e8f9b83fe7c5c5bf709593543571b Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 29 Sep 2026 11:52:09 +0530 Subject: [PATCH 02/19] refactor(web): rename DAO session store to auth session store --- apps/web/src/app/create/page.tsx | 4 ++-- .../web/src/app/dao/[daoId]/admin/auction/page.tsx | 4 ++-- .../src/app/dao/[daoId]/admin/governance/page.tsx | 4 ++-- apps/web/src/app/dao/[daoId]/admin/owner/page.tsx | 4 ++-- apps/web/src/app/dao/[daoId]/admin/page.tsx | 4 ++-- apps/web/src/app/dao/[daoId]/admin/token/page.tsx | 4 ++-- apps/web/src/app/dao/[daoId]/auctions/page.tsx | 4 ++-- .../dao/[daoId]/proposals/[proposalId]/page.tsx | 4 ++-- .../src/app/dao/[daoId]/proposals/create/page.tsx | 4 ++-- apps/web/src/app/dao/[daoId]/proposals/page.tsx | 4 ++-- .../web/src/components/admin/admin-section-nav.tsx | 4 ++-- apps/web/src/components/dao-shell.tsx | 4 ++-- .../src/components/dashboard/dashboard-header.tsx | 4 ++-- .../src/components/dashboard/dashboard-shell.tsx | 4 ++-- .../components/proposal/proposal-draft-panel.tsx | 4 ++-- apps/web/src/components/wallet-controls.tsx | 14 +++++++------- .../components/action-form-wrapper.tsx | 4 ++-- .../components/proposal-action-queue.tsx | 4 ++-- apps/web/src/lib/use-admin-draft-status.ts | 4 ++-- apps/web/src/lib/use-admin-proposal-draft.tsx | 4 ++-- ...{dao-session-store.ts => auth-session-store.ts} | 14 +++++++------- docs/mvp-technical-plan.md | 2 +- 22 files changed, 53 insertions(+), 53 deletions(-) rename apps/web/src/stores/{dao-session-store.ts => auth-session-store.ts} (79%) diff --git a/apps/web/src/app/create/page.tsx b/apps/web/src/app/create/page.tsx index 29a4cbf..d0741e1 100644 --- a/apps/web/src/app/create/page.tsx +++ b/apps/web/src/app/create/page.tsx @@ -28,8 +28,8 @@ import { } from '@/lib/create-dao-schema'; import { getDeploymentConfig, isDeploymentConfigured } from '@/lib/deployment-config'; import { useDaoDeployment } from '@/lib/use-dao-deployment'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { useCreateDaoStore } from '@/stores/create-dao-store'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; type SectionStatus = 'complete' | 'active' | 'error' | 'pending'; @@ -175,7 +175,7 @@ function AccordionSection({ export default function CreateDaoPage() { const router = useRouter(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const sectionRefs = useRef>>({}); const basicInfo = useCreateDaoStore((state) => state.basicInfo); diff --git a/apps/web/src/app/dao/[daoId]/admin/auction/page.tsx b/apps/web/src/app/dao/[daoId]/admin/auction/page.tsx index 9d91358..74eef64 100644 --- a/apps/web/src/app/dao/[daoId]/admin/auction/page.tsx +++ b/apps/web/src/app/dao/[daoId]/admin/auction/page.tsx @@ -24,7 +24,7 @@ import { useTransactionFeedback } from '@/lib/transaction-feedback'; import { useAdminDraftStatus } from '@/lib/use-admin-draft-status'; import { useAdminProposalDraft } from '@/lib/use-admin-proposal-draft'; import { getStellarAddressError, isValidStellarAddress } from '@/lib/validation'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type AuctionStatus = { status: 'not-launched' | 'paused' | 'active'; @@ -45,7 +45,7 @@ const fetcher = async (url: string): Promise => { export default function AuctionAdminPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const tx = useTransactionFeedback(config.name); const [busy, setBusy] = useState(false); const [formMessage, setFormMessage] = useState(''); diff --git a/apps/web/src/app/dao/[daoId]/admin/governance/page.tsx b/apps/web/src/app/dao/[daoId]/admin/governance/page.tsx index ec6c499..5d1d729 100644 --- a/apps/web/src/app/dao/[daoId]/admin/governance/page.tsx +++ b/apps/web/src/app/dao/[daoId]/admin/governance/page.tsx @@ -24,7 +24,7 @@ import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; import { useAdminDraftStatus } from '@/lib/use-admin-draft-status'; import { useAdminProposalDraft } from '@/lib/use-admin-proposal-draft'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type Drafts = Partial<{ votingDelay: number; @@ -56,7 +56,7 @@ function formatSecondsValue(value: number | null | undefined) { export default function GovernanceAdminPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const [drafts, setDrafts] = useState(EMPTY_DRAFTS); const [formMessage, setFormMessage] = useState(''); const [busy, setBusy] = useState(false); diff --git a/apps/web/src/app/dao/[daoId]/admin/owner/page.tsx b/apps/web/src/app/dao/[daoId]/admin/owner/page.tsx index fa8298e..4570400 100644 --- a/apps/web/src/app/dao/[daoId]/admin/owner/page.tsx +++ b/apps/web/src/app/dao/[daoId]/admin/owner/page.tsx @@ -21,7 +21,7 @@ import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; import { useAdminDraftStatus } from '@/lib/use-admin-draft-status'; import { useAdminProposalDraft } from '@/lib/use-admin-proposal-draft'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; async function submitAuthorityUpdate( config: DaoNetworkConfig, @@ -63,7 +63,7 @@ async function submitAuthorityUpdate( export default function OwnerPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const [mintAuthority, setMintAuthority] = useState(''); const [governorAuthority, setGovernorAuthority] = useState(''); const [formMessage, setFormMessage] = useState(''); diff --git a/apps/web/src/app/dao/[daoId]/admin/page.tsx b/apps/web/src/app/dao/[daoId]/admin/page.tsx index 48e76eb..889da51 100644 --- a/apps/web/src/app/dao/[daoId]/admin/page.tsx +++ b/apps/web/src/app/dao/[daoId]/admin/page.tsx @@ -12,7 +12,7 @@ import { useDaoContext } from '@/contexts/dao-context'; import { treasuryHasAuthority, treasuryIsOwner } from '@/lib/admin-proposals'; import { useContractOwner } from '@/lib/admin-queries'; import { useGoldskyGovernorAuthorities, useGoldskyMintAuthorities } from '@/lib/goldsky-queries'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; function SectionCard({ title, @@ -50,7 +50,7 @@ function SectionCard({ export default function AdminPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const { data: mintAuthorities } = useGoldskyMintAuthorities(config.tokenContractId); const { data: governorAuthorities } = useGoldskyGovernorAuthorities(config.tokenContractId); const { data: tokenOwner } = useContractOwner(config, 'token', session.address || undefined); diff --git a/apps/web/src/app/dao/[daoId]/admin/token/page.tsx b/apps/web/src/app/dao/[daoId]/admin/token/page.tsx index 4aea530..d822eb8 100644 --- a/apps/web/src/app/dao/[daoId]/admin/token/page.tsx +++ b/apps/web/src/app/dao/[daoId]/admin/token/page.tsx @@ -21,11 +21,11 @@ import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; import { useAdminDraftStatus } from '@/lib/use-admin-draft-status'; import { useAdminProposalDraft } from '@/lib/use-admin-proposal-draft'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; export default function TokenAdminPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const [recipient, setRecipient] = useState(''); const [amount, setAmount] = useState('1'); const [formMessage, setFormMessage] = useState(''); diff --git a/apps/web/src/app/dao/[daoId]/auctions/page.tsx b/apps/web/src/app/dao/[daoId]/auctions/page.tsx index 566dfd9..fe65106 100644 --- a/apps/web/src/app/dao/[daoId]/auctions/page.tsx +++ b/apps/web/src/app/dao/[daoId]/auctions/page.tsx @@ -15,7 +15,7 @@ import { useDaoContext } from '@/contexts/dao-context'; import { getTreasuryAssets } from '@/lib/assets-config'; import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type AuctionData = { auction: { @@ -82,7 +82,7 @@ function formatRemaining(endTime: string, now: number) { export default function AuctionsPage() { const { daoId, daoConfig: config } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const tx = useTransactionFeedback(config.name); const { data, error, isLoading, mutate } = useSWR( `/api/dao/${encodeURIComponent(daoId)}/auctions`, diff --git a/apps/web/src/app/dao/[daoId]/proposals/[proposalId]/page.tsx b/apps/web/src/app/dao/[daoId]/proposals/[proposalId]/page.tsx index 838e676..5cc20ac 100644 --- a/apps/web/src/app/dao/[daoId]/proposals/[proposalId]/page.tsx +++ b/apps/web/src/app/dao/[daoId]/proposals/[proposalId]/page.tsx @@ -26,7 +26,7 @@ import { proposalActionMode } from '@/lib/proposal-state'; import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; import { useVotingPower } from '@/lib/voting-power'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type ProposalPageData = { detail: ProposalDetail; @@ -85,7 +85,7 @@ export default function ProposalDetailPage() { const { daoId, daoConfig: config } = useDaoContext(); const params = useParams<{ proposalId: string }>(); const proposalId = params.proposalId; - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const [voteReason, setVoteReason] = useState(''); const [selectedVoteType, setSelectedVoteType] = useState(null); const [formMessage, setFormMessage] = useState(''); diff --git a/apps/web/src/app/dao/[daoId]/proposals/create/page.tsx b/apps/web/src/app/dao/[daoId]/proposals/create/page.tsx index dd96d7f..9fb34dd 100644 --- a/apps/web/src/app/dao/[daoId]/proposals/create/page.tsx +++ b/apps/web/src/app/dao/[daoId]/proposals/create/page.tsx @@ -22,7 +22,7 @@ import { proposalIdToRouteId } from '@/lib/proposal-id'; import { encodeProposalMetadata, validateProposalMetadataDraft } from '@/lib/proposal-metadata'; import { waitForConfirmation } from '@/lib/transaction-confirmation'; import { useTransactionFeedback } from '@/lib/transaction-feedback'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { selectCanProceedToStep2, selectDraft, @@ -33,7 +33,7 @@ import { export default function ProposalCreatePage() { const { daoId } = useDaoContext(); const router = useRouter(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const { daoConfig: config } = useDaoContext(); // Zustand store hooks diff --git a/apps/web/src/app/dao/[daoId]/proposals/page.tsx b/apps/web/src/app/dao/[daoId]/proposals/page.tsx index 53064fe..4d2929b 100644 --- a/apps/web/src/app/dao/[daoId]/proposals/page.tsx +++ b/apps/web/src/app/dao/[daoId]/proposals/page.tsx @@ -14,7 +14,7 @@ import { Button, Callout, Heading, Input, Select, Skeleton, Text } from '@/compo import { useDaoContext } from '@/contexts/dao-context'; import { daoRoute } from '@/lib/dao-routes'; import { useProposalEligibility } from '@/lib/proposal-eligibility'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { selectHasDraft, useProposalComposerStore } from '@/stores/proposal-composer-store'; function formatTimestamp(timestamp: number) { @@ -39,7 +39,7 @@ export default function ProposalsPage() { const [query, setQuery] = useState(''); const [status, setStatus] = useState('all'); const router = useRouter(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const eligibility = useProposalEligibility(config, session.address); const hasDraft = useProposalComposerStore(selectHasDraft(session.address || null, daoId)); const { data, error, isLoading, mutate } = useSWR( diff --git a/apps/web/src/components/admin/admin-section-nav.tsx b/apps/web/src/components/admin/admin-section-nav.tsx index a0d3204..1d8c4df 100644 --- a/apps/web/src/components/admin/admin-section-nav.tsx +++ b/apps/web/src/components/admin/admin-section-nav.tsx @@ -7,7 +7,7 @@ import { Stack } from 'styled-system/jsx'; import { Badge, Button, Card, Text } from '@/components/ui'; import { daoAdminRoute } from '@/lib/dao-routes'; import { ProposalActionQueue } from '@/lib/proposal-actions'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { selectDraft, useProposalComposerStore } from '@/stores/proposal-composer-store'; const ITEMS: Array<{ section: string; label: string }> = [ @@ -28,7 +28,7 @@ export function AdminSectionNav({ showDraftTray?: boolean; }) { const router = useRouter(); - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const draft = useProposalComposerStore(selectDraft(address || null, daoId)); return ( diff --git a/apps/web/src/components/dao-shell.tsx b/apps/web/src/components/dao-shell.tsx index d71c21e..482ff6d 100644 --- a/apps/web/src/components/dao-shell.tsx +++ b/apps/web/src/components/dao-shell.tsx @@ -26,7 +26,7 @@ import { Callout } from '@/components/ui'; import { WalletControls } from '@/components/wallet-controls'; import { useDaoContext } from '@/contexts/dao-context'; import { useGoldskyMember } from '@/lib/goldsky-queries'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type NavItem = { href: Route; label: string; icon: LucideIcon; exact?: boolean }; @@ -86,7 +86,7 @@ function hasDaoMembership(member: ReturnType['data']) { export function DaoShell({ children }: { children: ReactNode }) { const pathname = usePathname(); const { daoId, daoConfig: currentNetwork } = useDaoContext(); - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); const { data: memberLookup } = useGoldskyMember(currentNetwork.tokenContractId, session.address); const walletDisabled = Boolean(session.address && session.walletNetworkIssue); diff --git a/apps/web/src/components/dashboard/dashboard-header.tsx b/apps/web/src/components/dashboard/dashboard-header.tsx index 81e72e2..31185da 100644 --- a/apps/web/src/components/dashboard/dashboard-header.tsx +++ b/apps/web/src/components/dashboard/dashboard-header.tsx @@ -4,7 +4,7 @@ import Link from 'next/link'; import { NetworkIndicator } from '@/components/network-indicator'; import { WalletControls } from '@/components/wallet-controls'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; interface DashboardHeaderProps { showMenuButton?: boolean; @@ -12,7 +12,7 @@ interface DashboardHeaderProps { } export function DashboardHeader({ showMenuButton = false, onMenuClick }: DashboardHeaderProps) { - const session = useDaoSessionStore(); + const session = useAuthSessionStore(); return (
{showMenuButton ? ( diff --git a/apps/web/src/components/dashboard/dashboard-shell.tsx b/apps/web/src/components/dashboard/dashboard-shell.tsx index af78c82..3b04508 100644 --- a/apps/web/src/components/dashboard/dashboard-shell.tsx +++ b/apps/web/src/components/dashboard/dashboard-shell.tsx @@ -7,7 +7,7 @@ import { MarketplaceComingSoon } from '@/components/marketplace/marketplace-comi import { Callout } from '@/components/ui'; import type { DaoConfig } from '@/lib/dao-db'; import { useDashboardData } from '@/lib/goldsky-queries'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { DashboardFeed } from './dashboard-feed'; import { DashboardFooter } from './dashboard-footer'; @@ -18,7 +18,7 @@ import { DashboardWelcome } from './dashboard-welcome'; export function DashboardShell({ daos, loadError }: { daos: DaoConfig[]; loadError: boolean }) { const [sidebarOpen, setSidebarOpen] = useState(false); - const sessionAddress = useDaoSessionStore((state) => state.address); + const sessionAddress = useAuthSessionStore((state) => state.address); const isNewcomer = !sessionAddress; const { data: dashboardData, error: dashboardError, isLoading: dashboardLoading } = useDashboardData(sessionAddress); diff --git a/apps/web/src/components/proposal/proposal-draft-panel.tsx b/apps/web/src/components/proposal/proposal-draft-panel.tsx index 6c4198b..07858f6 100644 --- a/apps/web/src/components/proposal/proposal-draft-panel.tsx +++ b/apps/web/src/components/proposal/proposal-draft-panel.tsx @@ -7,11 +7,11 @@ import { Stack } from 'styled-system/jsx'; import { ProposalActionConfirmDialog } from '@/components/proposal/proposal-action-confirm-dialog'; import { Badge, Button, Card, Heading, Text } from '@/components/ui'; import { ProposalActionQueue } from '@/lib/proposal-actions'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { selectDraft, selectHasDraft, useProposalComposerStore } from '@/stores/proposal-composer-store'; export function ProposalDraftPanel({ daoId }: { daoId: string }) { - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const draft = useProposalComposerStore(selectDraft(address || null, daoId)); const hasDraft = useProposalComposerStore(selectHasDraft(address || null, daoId)); const reset = useProposalComposerStore((state) => state.reset); diff --git a/apps/web/src/components/wallet-controls.tsx b/apps/web/src/components/wallet-controls.tsx index 4e0bf70..22426a6 100644 --- a/apps/web/src/components/wallet-controls.tsx +++ b/apps/web/src/components/wallet-controls.tsx @@ -21,7 +21,7 @@ import { import { getExplorerAccountUrl } from '@/lib/explorer-links'; import { useWalletBalance } from '@/lib/wallet-balance'; import { initializeWalletKit, isWalletConnectSelected } from '@/lib/wallet-kit'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; type WalletNetwork = { name: NetworkName; @@ -36,7 +36,7 @@ function shortenAddress(value: string) { async function validateWalletNetwork( currentNetwork: WalletNetwork, - updateSession: ReturnType['updateSession'] + updateSession: ReturnType['updateSession'] ) { try { const walletNetwork = await StellarWalletsKit.getNetwork(); @@ -81,11 +81,11 @@ export function WalletControls({ network }: { network?: WalletNetwork }) { const networkName = currentNetwork.name; const networkLabel = currentNetwork.label; const networkPassphrase = currentNetwork.passphrase; - const session = useDaoSessionStore(); - const updateSession = useDaoSessionStore((state) => state.updateSession); - const setAuthStatus = useDaoSessionStore((state) => state.setAuthStatus); - const setAuthenticatedAddress = useDaoSessionStore((state) => state.setAuthenticatedAddress); - const resetAuth = useDaoSessionStore((state) => state.resetAuth); + const session = useAuthSessionStore(); + const updateSession = useAuthSessionStore((state) => state.updateSession); + const setAuthStatus = useAuthSessionStore((state) => state.setAuthStatus); + const setAuthenticatedAddress = useAuthSessionStore((state) => state.setAuthenticatedAddress); + const resetAuth = useAuthSessionStore((state) => state.resetAuth); const { data: authSession, mutate: mutateAuthSession } = useAuthSession(); const [copied, setCopied] = useState(false); const [walletAddress, setWalletAddress] = useState(undefined); diff --git a/apps/web/src/lib/proposal-actions/components/action-form-wrapper.tsx b/apps/web/src/lib/proposal-actions/components/action-form-wrapper.tsx index 2ac0f40..adc6f33 100644 --- a/apps/web/src/lib/proposal-actions/components/action-form-wrapper.tsx +++ b/apps/web/src/lib/proposal-actions/components/action-form-wrapper.tsx @@ -6,7 +6,7 @@ import { Suspense, useCallback, useState } from 'react'; import { ProposalActionConfirmDialog } from '@/components/proposal/proposal-action-confirm-dialog'; import { Skeleton } from '@/components/ui'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { normalizeWalletAddress, selectValidationErrors, @@ -34,7 +34,7 @@ type ConfirmDialogState = { export function ActionFormWrapper({ daoId }: { daoId: string }) { const context = useActionFormContext(); const [confirmDialog, setConfirmDialog] = useState(null); - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const walletKey = normalizeWalletAddress(address); // Subscribe to only what we need (performance optimization) diff --git a/apps/web/src/lib/proposal-actions/components/proposal-action-queue.tsx b/apps/web/src/lib/proposal-actions/components/proposal-action-queue.tsx index 4be7a2a..ab17b10 100644 --- a/apps/web/src/lib/proposal-actions/components/proposal-action-queue.tsx +++ b/apps/web/src/lib/proposal-actions/components/proposal-action-queue.tsx @@ -8,7 +8,7 @@ import { Stack } from 'styled-system/jsx'; import { ProposalActionConfirmDialog } from '@/components/proposal/proposal-action-confirm-dialog'; import { Badge, Button, Card, Text } from '@/components/ui'; import { getProposalActionSummary } from '@/lib/proposal-call'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { normalizeWalletAddress, useProposalComposerStore } from '@/stores/proposal-composer-store'; import { getActionHandler } from '../registry'; @@ -22,7 +22,7 @@ type ConfirmDialogState = { } | null; export function ProposalActionQueue({ daoId, editable = true }: { daoId: string; editable?: boolean }) { - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const walletKey = normalizeWalletAddress(address); const queuedActions = useProposalComposerStore((s) => s.draftsByWallet[walletKey]?.[daoId]?.queuedActions ?? []); const editingState = useProposalComposerStore((s) => s.draftsByWallet[walletKey]?.[daoId]?.editingState ?? null); diff --git a/apps/web/src/lib/use-admin-draft-status.ts b/apps/web/src/lib/use-admin-draft-status.ts index 26af6ad..d272e11 100644 --- a/apps/web/src/lib/use-admin-draft-status.ts +++ b/apps/web/src/lib/use-admin-draft-status.ts @@ -1,6 +1,6 @@ import { getProposalActionResourceKey } from '@/lib/proposal-action-identity'; import type { ProposalActionType, ProposalQueuedAction } from '@/lib/proposal-actions/types'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { normalizeWalletAddress, useProposalComposerStore } from '@/stores/proposal-composer-store'; /** @@ -8,7 +8,7 @@ import { normalizeWalletAddress, useProposalComposerStore } from '@/stores/propo * Useful for forms to show draft previews and detect conflicts */ export function useAdminDraftStatus(daoId: string, actionTypes: ProposalActionType | ProposalActionType[]) { - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const draft = useProposalComposerStore((state) => { if (!address) return null; const walletKey = normalizeWalletAddress(address); diff --git a/apps/web/src/lib/use-admin-proposal-draft.tsx b/apps/web/src/lib/use-admin-proposal-draft.tsx index 1f14cf8..b9fdcf0 100644 --- a/apps/web/src/lib/use-admin-proposal-draft.tsx +++ b/apps/web/src/lib/use-admin-proposal-draft.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import { analyzeProposalAction, type ProposalDraftFinding } from '@/lib/proposal-action-identity'; import type { ProposalQueuedAction } from '@/lib/proposal-actions/types'; import { getProposalActionSummary } from '@/lib/proposal-call'; -import { useDaoSessionStore } from '@/stores/dao-session-store'; +import { useAuthSessionStore } from '@/stores/auth-session-store'; import { normalizeWalletAddress, useProposalComposerStore } from '@/stores/proposal-composer-store'; export type AdminProposalRequest = { @@ -22,7 +22,7 @@ export type PendingAdminProposal = AdminProposalRequest & { }; export function useAdminProposalDraft() { - const address = useDaoSessionStore((state) => state.address); + const address = useAuthSessionStore((state) => state.address); const [pending, setPending] = useState(null); function requestAdd(request: AdminProposalRequest) { diff --git a/apps/web/src/stores/dao-session-store.ts b/apps/web/src/stores/auth-session-store.ts similarity index 79% rename from apps/web/src/stores/dao-session-store.ts rename to apps/web/src/stores/auth-session-store.ts index e6a793e..062b876 100644 --- a/apps/web/src/stores/dao-session-store.ts +++ b/apps/web/src/stores/auth-session-store.ts @@ -4,7 +4,7 @@ import { create } from 'zustand'; import type { AuthStatus } from '@/lib/auth/types'; -type DaoSessionState = { +type AuthSessionState = { address: string; status: string; authStatus: AuthStatus; @@ -14,16 +14,16 @@ type DaoSessionState = { walletNetworkIssue: string; }; -type DaoSessionActions = { - updateSession: (patch: Partial) => void; +type AuthSessionActions = { + updateSession: (patch: Partial) => void; setAuthStatus: (authStatus: AuthStatus, authError?: string) => void; setAuthenticatedAddress: (address: string) => void; resetAuth: () => void; }; -type DaoSessionStore = DaoSessionState & DaoSessionActions; +type AuthSessionStore = AuthSessionState & AuthSessionActions; -const initialState: DaoSessionState = { +const initialState: AuthSessionState = { address: '', status: 'Disconnected', authStatus: 'anonymous', @@ -33,7 +33,7 @@ const initialState: DaoSessionState = { walletNetworkIssue: '' }; -export const useDaoSessionStore = create((set) => ({ +export const useAuthSessionStore = create((set) => ({ ...initialState, updateSession: (patch) => set((current) => { @@ -41,7 +41,7 @@ export const useDaoSessionStore = create((set) => ({ const next = { ...current }; for (const [key, value] of Object.entries(patch) as Array< - [keyof DaoSessionState, DaoSessionState[keyof DaoSessionState]] + [keyof AuthSessionState, AuthSessionState[keyof AuthSessionState]] >) { if (typeof value !== 'undefined' && next[key] !== value) { next[key] = value as never; diff --git a/docs/mvp-technical-plan.md b/docs/mvp-technical-plan.md index 614570a..9c84328 100644 --- a/docs/mvp-technical-plan.md +++ b/docs/mvp-technical-plan.md @@ -41,7 +41,7 @@ Important baseline details: - Refund transfers currently invoke the asset directly. Persistent claim accounting and a claim entrypoint are missing. - None of the four protocol contracts currently exposes WASM replacement. New deployments must include upgrade entrypoints from initialization; Manager cannot retrofit the existing contracts through an absent interface. - Deployment currently uses an admin owner for all modules. Final governance authority and Auction mint permission must be explicitly established. -- `dao-session-store.ts` persists wallet state, not DAO identity. `dao-config.ts` resolves an environment-selected deployment; this is not runtime multi-DAO selection. +- `auth-session-store.ts` persists wallet state, not DAO identity. `dao-config.ts` resolves an environment-selected deployment; this is not runtime multi-DAO selection. - The app already has SAC transfer forms, bidding, combined settlement/next-auction creation, and owner-unpause controls. Adapt those flows. - Token metadata is currently an app-generated SVG keyed by token ID and deployment-wide branding. IPFS artwork ingestion, on-chain seeds, and DAO-scoped metadata resolution are new work. - Indexed tables already contain `deployment_id`, currently derived from deployment label/network. The work is durable identity and complete isolation, not simply adding a column. From bec71cbc88b94d2512f67fef9ab3877d62e07e7d Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 29 Sep 2026 12:00:27 +0530 Subject: [PATCH 03/19] fix(web): improve mobile DAO header --- apps/web/src/app/globals.css | 10 ++++++++++ apps/web/src/components/dao-shell.tsx | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index e4be677..aaa9809 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -2222,6 +2222,7 @@ textarea { .dao-exit-button__icon { flex: 0 0 auto; + transform: rotate(180deg); } @media (max-width: 680px) { @@ -2404,6 +2405,15 @@ textarea { padding: 9px; border-radius: 14px; } + .app-header__top { + grid-template-columns: 1fr; + gap: 8px; + } + .header-actions { + justify-content: flex-end; + padding-top: 8px; + border-top: 1px solid var(--border-default); + } .brand-mark { width: 38px; height: 38px; diff --git a/apps/web/src/components/dao-shell.tsx b/apps/web/src/components/dao-shell.tsx index 482ff6d..c88ab90 100644 --- a/apps/web/src/components/dao-shell.tsx +++ b/apps/web/src/components/dao-shell.tsx @@ -2,10 +2,10 @@ import type { LucideIcon } from 'lucide-react'; import { - ArrowLeft, Gavel, Landmark, LayoutDashboard, + LogOut, MoreHorizontal, Settings, ShieldAlert, @@ -111,7 +111,7 @@ export function DaoShell({ children }: { children: ReactNode }) {
-
{item.title} - {item.summary} + {formatActivitySummary(item)} Open DAO