free mode

This commit is contained in:
zramsay 2025-01-14 07:15:24 -05:00
parent f4dde9b83d
commit c56df13405
2 changed files with 36 additions and 30 deletions

View File

@ -10,14 +10,17 @@ import { processMTMPayment } from '../services/paymentService'
import { connectWallet, WalletState } from '../services/walletService' import { connectWallet, WalletState } from '../services/walletService'
import { WalletType } from '../services/types' import { WalletType } from '../services/types'
const FREE_MODE = process.env.NEXT_PUBLIC_FREE_MODE === 'true'
const Page: React.FC = (): React.ReactElement => { const Page: React.FC = (): React.ReactElement => {
const [walletState, setWalletState] = useState<WalletState>({ const [walletState, setWalletState] = useState<WalletState>({
connected: false, connected: FREE_MODE ? true : false, // Always "connected" in free mode
publicKey: null, publicKey: null,
type: null type: null
}) })
const handleConnect = async (walletType: WalletType): Promise<void> => { const handleConnect = async (walletType: WalletType): Promise<void> => {
if (FREE_MODE) return
try { try {
const newWalletState = await connectWallet(walletType) const newWalletState = await connectWallet(walletType)
setWalletState(newWalletState) setWalletState(newWalletState)
@ -33,19 +36,22 @@ const Page: React.FC = (): React.ReactElement => {
const handleImageAnalysis = (cost: number) => { const handleImageAnalysis = (cost: number) => {
return async (imageFile: File): Promise<VisionAnalysisResult> => { return async (imageFile: File): Promise<VisionAnalysisResult> => {
if (!walletState.connected || !walletState.publicKey || !walletState.type) { // In free mode, skip wallet checks and payment
if (!FREE_MODE && (!walletState.connected || !walletState.publicKey || !walletState.type)) {
return { error: 'Wallet not connected' } return { error: 'Wallet not connected' }
} }
// Process payment first // Only process payment if not in free mode
const paymentResult = await processMTMPayment( if (!FREE_MODE) {
walletState.publicKey, const paymentResult = await processMTMPayment(
cost, walletState.publicKey!,
walletState.type cost,
) walletState.type!
)
if (!paymentResult.success) { if (!paymentResult.success) {
return { error: paymentResult.error } return { error: paymentResult.error }
}
} }
// Then analyze the image // Then analyze the image
@ -66,11 +72,13 @@ const Page: React.FC = (): React.ReactElement => {
<p className="text-emerald-200 text-lg mb-8"> <p className="text-emerald-200 text-lg mb-8">
Go outside and touch grass Go outside and touch grass
</p> </p>
{!FREE_MODE && (
<WalletHeader <WalletHeader
walletState={walletState} walletState={walletState}
onConnect={handleConnect} onConnect={handleConnect}
/> />
)}
</div> </div>
{/* Single Analysis Card */} {/* Single Analysis Card */}

View File

@ -1,8 +1,11 @@
// src/components/ImageAnalysisCard.tsx
'use client' 'use client'
import React, { useState, useRef } from 'react' import React, { useState, useRef } from 'react'
import { Leaf } from 'lucide-react' import { Leaf } from 'lucide-react'
const FREE_MODE = process.env.NEXT_PUBLIC_FREE_MODE === 'true'
interface ImageAnalysisCardProps { interface ImageAnalysisCardProps {
title: string title: string
description: string description: string
@ -48,7 +51,7 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
const handleAnalyze = async () => { const handleAnalyze = async () => {
const file = fileInputRef.current?.files?.[0] const file = fileInputRef.current?.files?.[0]
if (!file || !isWalletConnected) return if (!file || (!FREE_MODE && !isWalletConnected)) return
setAnalysisState({ setAnalysisState({
...analysisState, ...analysisState,
@ -88,7 +91,7 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
} }
return ( return (
<div className="w-full bg-green-950/50 backdrop-blur-lg rounded-2xl shadow-xl border border-emerald-800/50 mb-8 hover:shadow-emerald-500/20 transition-all duration-300"> <div className="w-full bg-emerald-900/20 backdrop-blur-lg rounded-2xl shadow-xl border border-emerald-800/50 mb-8 hover:shadow-emerald-500/20 transition-all duration-300">
<div className="p-6"> <div className="p-6">
<div className="mb-4"> <div className="mb-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -98,9 +101,11 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
</h2> </h2>
</div> </div>
<p className="text-emerald-200 mt-2">{description}</p> <p className="text-emerald-200 mt-2">{description}</p>
<div className="mt-2 inline-block px-3 py-1 bg-emerald-500/20 rounded-full text-emerald-200 text-sm"> {!FREE_MODE && (
Cost: {tokenCost} MTM <div className="mt-2 inline-block px-3 py-1 bg-emerald-500/20 rounded-full text-emerald-200 text-sm">
</div> Cost: {tokenCost} MTM
</div>
)}
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
@ -115,7 +120,7 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
type="file" type="file"
accept="image/*" accept="image/*"
onChange={handleFileSelect} onChange={handleFileSelect}
disabled={!isWalletConnected} disabled={!FREE_MODE && !isWalletConnected}
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer className="absolute inset-0 w-full h-full opacity-0 cursor-pointer
disabled:cursor-not-allowed" disabled:cursor-not-allowed"
/> />
@ -136,13 +141,13 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
<button <button
onClick={handleAnalyze} onClick={handleAnalyze}
disabled={!isWalletConnected || analysisState.loading || !analysisState.imageUrl} disabled={(!FREE_MODE && !isWalletConnected) || analysisState.loading || !analysisState.imageUrl}
className="w-full bg-gradient-to-r from-emerald-500 to-teal-500 hover:from-emerald-600 className="w-full bg-gradient-to-r from-emerald-500 to-teal-500 hover:from-emerald-600
hover:to-teal-600 text-white font-semibold py-4 px-6 rounded-xl hover:to-teal-600 text-white font-semibold py-4 px-6 rounded-xl
transition-all duration-200 shadow-lg hover:shadow-emerald-500/25 transition-all duration-200 shadow-lg hover:shadow-emerald-500/25
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:shadow-none" disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:shadow-none"
> >
{analysisState.loading ? 'Revealing the magic...' : `Pay ${tokenCost} MTM & Analyze`} {analysisState.loading ? 'Processing...' : FREE_MODE ? 'Analyze' : `Pay ${tokenCost} MTM & Analyze`}
</button> </button>
</div> </div>
@ -152,19 +157,12 @@ const ImageAnalysisCard: React.FC<ImageAnalysisCardProps> = ({
</div> </div>
)} )}
{analysisState.description && ( {analysisState.description && (
<div className="mt-4 space-y-4"> <div className="mt-4 bg-green-900/30 border border-emerald-800/50 rounded-xl p-4">
{analysisState.description.split('\n\n').map((paragraph, index) => ( <p className="text-emerald-200 whitespace-pre-wrap">{analysisState.description}</p>
<p key={index} className={`
text-emerald-200 whitespace-pre-wrap
${index === 1 ? 'mt-4 text-sm italic' : ''}
`}>
{paragraph}
</p>
))}
</div> </div>
)} )}
</div> </div>
</div> </div>
) )
} }