forked from mito-systems/sol-mem-gen
131 lines
4.6 KiB
TypeScript
131 lines
4.6 KiB
TypeScript
'use client'
|
|
|
|
import React, { useState } from 'react'
|
|
import WalletHeader from '../components/WalletHeader'
|
|
import AIServiceCard from '../components/AIServiceCard'
|
|
import { generateWithFlux, FluxGenerationResult, FLUX_MODELS } from '../services/fluxService'
|
|
import { processMTMPayment } from '../services/paymentService'
|
|
import { connectWallet, WalletState } from '../services/walletService'
|
|
import { WalletType } from '../services/types'
|
|
|
|
const Page: React.FC = (): React.ReactElement => {
|
|
const [walletState, setWalletState] = useState<WalletState>({
|
|
connected: false,
|
|
publicKey: null,
|
|
type: null
|
|
})
|
|
|
|
const handleConnect = async (walletType: WalletType): Promise<void> => {
|
|
try {
|
|
const newWalletState = await connectWallet(walletType)
|
|
setWalletState(newWalletState)
|
|
} catch (error) {
|
|
console.error('Wallet connection error:', error)
|
|
setWalletState({
|
|
connected: false,
|
|
publicKey: null,
|
|
type: null
|
|
})
|
|
}
|
|
}
|
|
|
|
const handleFluxGeneration = (modelId: string, cost: number) => {
|
|
return async (prompt: string): Promise<FluxGenerationResult> => {
|
|
const type = walletState.type;
|
|
if (!walletState.connected || !walletState.publicKey ||
|
|
(type === 'phantom' && !window.phantom) ||
|
|
(type === 'solflare' && !window.solflare)) {
|
|
return { error: 'Wallet not connected' }
|
|
}
|
|
|
|
// Process payment first
|
|
const paymentResult = await processMTMPayment(
|
|
walletState.publicKey,
|
|
cost,
|
|
walletState.type
|
|
)
|
|
|
|
if (!paymentResult.success) {
|
|
return { error: paymentResult.error }
|
|
}
|
|
|
|
const transactionSignature = paymentResult.transactionSignature;
|
|
|
|
// Then generate image with specified model
|
|
return generateWithFlux(prompt, modelId, transactionSignature)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen w-full flex flex-col items-center bg-gradient-to-b from-gray-900 via-gray-800 to-gray-900">
|
|
<div className="container max-w-7xl mx-auto px-4 py-8">
|
|
{/* Header */}
|
|
<div className="text-center mb-8">
|
|
<h1 className="text-4xl sm:text-5xl font-bold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-green-400 to-emerald-600">
|
|
Mark's Meme Market
|
|
</h1>
|
|
<p className="text-gray-400 text-lg mb-8">
|
|
Use MTM to generate memes
|
|
</p>
|
|
|
|
<WalletHeader
|
|
walletState={walletState}
|
|
onConnect={handleConnect}
|
|
/>
|
|
</div>
|
|
|
|
{/* Flux Models Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
|
|
{FLUX_MODELS.map((model) => (
|
|
<AIServiceCard
|
|
key={model.modelId}
|
|
title={model.name}
|
|
description={model.description}
|
|
tokenCost={model.cost}
|
|
isWalletConnected={walletState.connected}
|
|
onGenerate={handleFluxGeneration(model.modelId, model.cost)}
|
|
/>
|
|
))}
|
|
|
|
{/* Coming Soon Card */}
|
|
<div className="relative bg-gray-800/50 backdrop-blur-lg rounded-2xl shadow-xl border border-gray-700/50 overflow-hidden group">
|
|
<div className="absolute inset-0 bg-gradient-to-br from-yellow-500/10 to-orange-500/10 opacity-50"></div>
|
|
<div className="relative p-6 flex flex-col h-full">
|
|
<div className="flex-1">
|
|
<h3 className="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-yellow-400 to-orange-500">
|
|
Coming Soon
|
|
</h3>
|
|
<p className="mt-2 text-gray-400">
|
|
New AI model integration in development. Stay tuned for more amazing features!
|
|
</p>
|
|
<div className="mt-2 inline-block px-3 py-1 bg-orange-500/20 rounded-full">
|
|
<span className="text-orange-300 text-sm">TBD</span>
|
|
</div>
|
|
</div>
|
|
<div className="mt-6">
|
|
<button
|
|
disabled
|
|
className="w-full bg-gradient-to-r from-yellow-500/50 to-orange-500/50
|
|
text-white/50 font-semibold py-4 px-6 rounded-xl
|
|
cursor-not-allowed opacity-50"
|
|
>
|
|
Coming Soon
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Info Section */}
|
|
<div className="mt-12 text-center text-gray-400">
|
|
<p className="text-sm">
|
|
Powered by Mark • Use at your own risk
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Page
|