mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-13 15:57:01 +08:00
feat: implement hybrid database architecture and frontend encryption
- Add PostgreSQL + SQLite hybrid database support with automatic switching - Implement frontend AES-GCM + RSA-OAEP encryption for sensitive data - Add comprehensive DatabaseInterface with all required methods - Fix compilation issues with interface consistency - Update all database method signatures to use DatabaseInterface - Add missing UpdateTraderInitialBalance method to PostgreSQL implementation - Integrate RSA public key distribution via /api/config endpoint - Add frontend crypto service with proper error handling - Support graceful degradation between encrypted and plaintext transmission - Add directory creation for RSA keys and PEM parsing fixes - Test both SQLite and PostgreSQL modes successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
@@ -19,61 +19,112 @@ export function LandingPage() {
|
||||
const { user, logout } = useAuth()
|
||||
const { language, setLanguage } = useLanguage()
|
||||
const isLoggedIn = !!user
|
||||
|
||||
console.log('LandingPage - user:', user, 'isLoggedIn:', isLoggedIn);
|
||||
|
||||
console.log('LandingPage - user:', user, 'isLoggedIn:', isLoggedIn)
|
||||
return (
|
||||
<>
|
||||
<HeaderBar
|
||||
onLoginClick={() => setShowLoginModal(true)}
|
||||
isLoggedIn={isLoggedIn}
|
||||
<HeaderBar
|
||||
onLoginClick={() => setShowLoginModal(true)}
|
||||
isLoggedIn={isLoggedIn}
|
||||
isHomePage={true}
|
||||
language={language}
|
||||
onLanguageChange={setLanguage}
|
||||
user={user}
|
||||
onLogout={logout}
|
||||
onPageChange={(page) => {
|
||||
console.log('LandingPage onPageChange called with:', page);
|
||||
console.log('LandingPage onPageChange called with:', page)
|
||||
if (page === 'competition') {
|
||||
window.location.href = '/competition';
|
||||
window.location.href = '/competition'
|
||||
} else if (page === 'traders') {
|
||||
window.location.href = '/traders';
|
||||
window.location.href = '/traders'
|
||||
} else if (page === 'trader') {
|
||||
window.location.href = '/dashboard';
|
||||
window.location.href = '/dashboard'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className='min-h-screen px-4 sm:px-6 lg:px-8' style={{ background: 'var(--brand-black)', color: 'var(--brand-light-gray)' }}>
|
||||
<HeroSection language={language} />
|
||||
<AboutSection language={language} />
|
||||
<FeaturesSection language={language} />
|
||||
<HowItWorksSection language={language} />
|
||||
<CommunitySection />
|
||||
<div
|
||||
className="min-h-screen px-4 sm:px-6 lg:px-8"
|
||||
style={{
|
||||
background: 'var(--brand-black)',
|
||||
color: 'var(--brand-light-gray)',
|
||||
}}
|
||||
>
|
||||
<HeroSection language={language} />
|
||||
<AboutSection language={language} />
|
||||
<FeaturesSection language={language} />
|
||||
<HowItWorksSection language={language} />
|
||||
<CommunitySection />
|
||||
|
||||
{/* CTA */}
|
||||
<AnimatedSection backgroundColor='var(--panel-bg)'>
|
||||
<div className='max-w-4xl mx-auto text-center'>
|
||||
<motion.h2 className='text-5xl font-bold mb-6' style={{ color: 'var(--brand-light-gray)' }} initial={{ opacity: 0, y: 30 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>
|
||||
{t('readyToDefine', language)}
|
||||
</motion.h2>
|
||||
<motion.p className='text-xl mb-12' style={{ color: 'var(--text-secondary)' }} initial={{ opacity: 0, y: 30 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: 0.1 }}>
|
||||
{t('startWithCrypto', language)}
|
||||
</motion.p>
|
||||
<div className='flex flex-wrap justify-center gap-4'>
|
||||
<motion.button onClick={() => setShowLoginModal(true)} className='flex items-center gap-2 px-10 py-4 rounded-lg font-semibold text-lg' style={{ background: 'var(--brand-yellow)', color: 'var(--brand-black)' }} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
|
||||
{t('getStartedNow', language)}
|
||||
<motion.div animate={{ x: [0, 5, 0] }} transition={{ duration: 1.5, repeat: Infinity }}>
|
||||
<ArrowRight className='w-5 h-5' />
|
||||
</motion.div>
|
||||
</motion.button>
|
||||
<motion.a href='https://github.com/tinkle-community/nofx/tree/dev' target='_blank' rel='noopener noreferrer' className='flex items-center gap-2 px-10 py-4 rounded-lg font-semibold text-lg' style={{ background: 'transparent', color: 'var(--brand-light-gray)', border: '2px solid var(--brand-yellow)' }} whileHover={{ scale: 1.05, backgroundColor: 'rgba(240, 185, 11, 0.1)' }} whileTap={{ scale: 0.95 }}>
|
||||
{t('viewSourceCode', language)}
|
||||
</motion.a>
|
||||
{/* CTA */}
|
||||
<AnimatedSection backgroundColor="var(--panel-bg)">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<motion.h2
|
||||
className="text-5xl font-bold mb-6"
|
||||
style={{ color: 'var(--brand-light-gray)' }}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
{t('readyToDefine', language)}
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
className="text-xl mb-12"
|
||||
style={{ color: 'var(--text-secondary)' }}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
{t('startWithCrypto', language)}
|
||||
</motion.p>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<motion.button
|
||||
onClick={() => setShowLoginModal(true)}
|
||||
className="flex items-center gap-2 px-10 py-4 rounded-lg font-semibold text-lg"
|
||||
style={{
|
||||
background: 'var(--brand-yellow)',
|
||||
color: 'var(--brand-black)',
|
||||
}}
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
{t('getStartedNow', language)}
|
||||
<motion.div
|
||||
animate={{ x: [0, 5, 0] }}
|
||||
transition={{ duration: 1.5, repeat: Infinity }}
|
||||
>
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</motion.div>
|
||||
</motion.button>
|
||||
<motion.a
|
||||
href="https://github.com/tinkle-community/nofx/tree/dev"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 px-10 py-4 rounded-lg font-semibold text-lg"
|
||||
style={{
|
||||
background: 'transparent',
|
||||
color: 'var(--brand-light-gray)',
|
||||
border: '2px solid var(--brand-yellow)',
|
||||
}}
|
||||
whileHover={{
|
||||
scale: 1.05,
|
||||
backgroundColor: 'rgba(240, 185, 11, 0.1)',
|
||||
}}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
{t('viewSourceCode', language)}
|
||||
</motion.a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AnimatedSection>
|
||||
</AnimatedSection>
|
||||
|
||||
{showLoginModal && <LoginModal onClose={() => setShowLoginModal(false)} language={language} />}
|
||||
<FooterSection language={language} />
|
||||
{showLoginModal && (
|
||||
<LoginModal
|
||||
onClose={() => setShowLoginModal(false)}
|
||||
language={language}
|
||||
/>
|
||||
)}
|
||||
<FooterSection language={language} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user