Merge branch 'dev'

# Conflicts:
#	app/layout.tsx
#	app/page.tsx
#	components/AppSwitcher.tsx
#	docker-compose.yml
This commit is contained in:
Jeff Emmett 2026-02-25 13:37:24 -08:00
commit 3ca157a588
6 changed files with 36 additions and 36 deletions

View File

@ -3,15 +3,8 @@
@tailwind utilities;
:root {
--background: #ffffff;
--foreground: #171717;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
--background: #0f172a;
--foreground: #e2e8f0;
}
body {

View File

@ -1,8 +1,6 @@
import type { Metadata } from 'next'
import localFont from 'next/font/local'
import './globals.css'
import { Header } from '@/components/Header'
import { EcosystemFooter } from '@/components/EcosystemFooter'
const geistSans = localFont({
src: './fonts/GeistVF.woff',
@ -19,7 +17,7 @@ export const metadata: Metadata = {
title: 'rFunds - Threshold-Based Flow Funding',
description: 'Design, simulate, and share continuous funding flows with threshold-based mechanisms. Create interconnected funding funnels with overflow routing and outcome tracking.',
icons: {
icon: "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>💸</text></svg>",
icon: "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📊</text></svg>",
},
openGraph: {
title: 'rFunds - Threshold-Based Flow Funding',
@ -36,13 +34,8 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<head>
<script defer src="https://rdata.online/collect.js" data-website-id="0ebf1cfd-57e4-4fbe-925d-cd541d7bb3a8" />
</head>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<Header current="funds" />
{children}
<EcosystemFooter current="funds" />
</body>
</html>
)

View File

@ -1,8 +1,31 @@
import Link from 'next/link'
import { Header } from '@/components/Header'
import { EcosystemFooter } from '@/components/EcosystemFooter'
export default function Home() {
return (
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-white">
{/* Nav */}
<Header
current="funds"
actions={
<>
<Link
href="/tbff"
className="text-sm text-slate-300 hover:text-white transition-colors"
>
Demo
</Link>
<Link
href="/space"
className="text-sm px-4 py-2 bg-emerald-600 hover:bg-emerald-500 rounded-lg transition-colors font-medium"
>
Create Space
</Link>
</>
}
/>
{/* Hero */}
<section className="max-w-6xl mx-auto px-6 pt-20 pb-16">
<div className="text-center max-w-3xl mx-auto">
@ -20,12 +43,6 @@ export default function Home() {
>
Try the Demo
</Link>
<Link
href="/river"
className="px-6 py-3 bg-cyan-700 hover:bg-cyan-600 rounded-xl text-lg font-medium transition-all border border-cyan-600"
>
River View
</Link>
<Link
href="/space"
className="px-6 py-3 bg-emerald-600 hover:bg-emerald-500 rounded-xl text-lg font-medium transition-all shadow-lg shadow-emerald-900/30"
@ -139,6 +156,9 @@ export default function Home() {
Create Your Space
</Link>
</section>
{/* Footer */}
<EcosystemFooter current="rFunds" />
</div>
)
}

View File

@ -16,7 +16,7 @@ const MODULES: AppModule[] = [
// Creating
{ id: 'space', name: 'rSpace', badge: 'rS', color: 'bg-teal-300', emoji: '🎨', description: 'Real-time collaborative canvas', domain: 'rspace.online' },
{ id: 'notes', name: 'rNotes', badge: 'rN', color: 'bg-amber-300', emoji: '📝', description: 'Group note-taking & knowledge capture', domain: 'rnotes.online' },
{ id: 'pubs', name: 'rPubs', badge: 'rP', color: 'bg-rose-300', emoji: '📖', description: 'Collaborative publishing platform', domain: 'rpubs.online' },
{ id: 'pubs', name: 'rPubs', badge: 'rP', color: 'bg-rose-300', emoji: '📰', description: 'Collaborative publishing platform', domain: 'rpubs.online' },
// Planning
{ id: 'cal', name: 'rCal', badge: 'rC', color: 'bg-sky-300', emoji: '📅', description: 'Collaborative scheduling & events', domain: 'rcal.online' },
{ id: 'trips', name: 'rTrips', badge: 'rT', color: 'bg-emerald-300', emoji: '✈️', description: 'Group travel planning in real time', domain: 'rtrips.online' },
@ -27,7 +27,7 @@ const MODULES: AppModule[] = [
{ id: 'mail', name: 'rMail', badge: 'rMa', color: 'bg-blue-200', emoji: '✉️', description: 'Community email & newsletters', domain: 'rmail.online' },
{ id: 'forum', name: 'rForum', badge: 'rFo', color: 'bg-amber-200', emoji: '💭', description: 'Threaded community discussions', domain: 'rforum.online' },
// Deciding
{ id: 'choices', name: 'rChoices', badge: 'rCo', color: 'bg-fuchsia-300', emoji: '⚖️', description: 'Collaborative decision making', domain: 'rchoices.online' },
{ id: 'choices', name: 'rChoices', badge: 'rCo', color: 'bg-fuchsia-300', emoji: '🔀', description: 'Collaborative decision making', domain: 'rchoices.online' },
{ id: 'vote', name: 'rVote', badge: 'rV', color: 'bg-violet-300', emoji: '🗳️', description: 'Real-time polls & governance', domain: 'rvote.online' },
// Funding & Commerce
{ id: 'funds', name: 'rFunds', badge: 'rF', color: 'bg-lime-300', emoji: '💸', description: 'Collaborative fundraising & grants', domain: 'rfunds.online' },
@ -38,14 +38,14 @@ const MODULES: AppModule[] = [
// Social & Media
{ id: 'photos', name: 'rPhotos', badge: 'rPh', color: 'bg-pink-200', emoji: '📸', description: 'Shared community photo albums', domain: 'rphotos.online' },
{ id: 'tube', name: 'rTube', badge: 'rTu', color: 'bg-pink-300', emoji: '🎬', description: 'Group video platform', domain: 'rtube.online' },
{ id: 'network', name: 'rNetwork', badge: 'rNe', color: 'bg-blue-300', emoji: '🕸️', description: 'Community network & social graph', domain: 'rnetwork.online' },
{ id: 'network', name: 'rNetwork', badge: 'rNe', color: 'bg-blue-300', emoji: '🌐', description: 'Community network & social graph', domain: 'rnetwork.online' },
{ id: 'socials', name: 'rSocials', badge: 'rSo', color: 'bg-sky-200', emoji: '📢', description: 'Social media management', domain: 'rsocials.online' },
{ id: 'files', name: 'rFiles', badge: 'rFi', color: 'bg-cyan-300', emoji: '📁', description: 'Collaborative file storage', domain: 'rfiles.online' },
{ id: 'data', name: 'rData', badge: 'rD', color: 'bg-purple-300', emoji: '📊', description: 'Analytics & insights dashboard', domain: 'rdata.online' },
// Work & Productivity
{ id: 'work', name: 'rWork', badge: 'rWo', color: 'bg-slate-300', emoji: '📋', description: 'Project & task management', domain: 'rwork.online' },
{ id: 'work', name: 'rWork', badge: 'rWo', color: 'bg-slate-300', emoji: '💼', description: 'Project & task management', domain: 'rwork.online' },
// Identity & Infrastructure
{ id: 'ids', name: 'rIDs', badge: 'rId', color: 'bg-emerald-300', emoji: '🔐', description: 'Passkey identity & zero-knowledge auth', domain: 'ridentity.online' },
{ id: 'ids', name: 'rIDs', badge: 'rId', color: 'bg-emerald-300', emoji: '🔑', description: 'Passkey identity & zero-knowledge auth', domain: 'ridentity.online' },
{ id: 'stack', name: 'rStack', badge: 'r*', color: 'bg-gradient-to-br from-cyan-300 via-violet-300 to-rose-300', emoji: '📦', description: 'Open-source community infrastructure', domain: 'rstack.online' },
];

View File

@ -6,14 +6,8 @@ services:
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.rfunds.rule=Host(`rfunds.online`) || Host(`www.rfunds.online`)"
- "traefik.http.routers.rfunds.priority=120"
- "traefik.http.routers.rfunds.rule=Host(`rfunds.online`) || Host(`www.rfunds.online`) || HostRegexp(`{subdomain:[a-z0-9-]+}.rfunds.online`)"
- "traefik.http.services.rfunds.loadbalancer.server.port=3000"
# Wildcard router: any space subdomain routes to this app
- "traefik.http.routers.rfunds-spaces.rule=HostRegexp(`{space:[a-z0-9-]+}.rfunds.online`)"
- "traefik.http.routers.rfunds-spaces.priority=100"
- "traefik.http.routers.rfunds-spaces.entrypoints=web"
- "traefik.http.routers.rfunds-spaces.service=rfunds"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/"]
interval: 30s

View File

@ -9,7 +9,7 @@ import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { EncryptIDClient } from '@encryptid/sdk/client'
const ENCRYPTID_SERVER = process.env.NEXT_PUBLIC_ENCRYPTID_SERVER_URL || 'https://encryptid.jeffemmett.com'
const ENCRYPTID_SERVER = process.env.NEXT_PUBLIC_ENCRYPTID_SERVER_URL || 'https://auth.ridentity.online'
const client = new EncryptIDClient(ENCRYPTID_SERVER)
interface AuthState {