generated from scaffold-eth/scaffold-eth-2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4f04085
commit 0f8722a
Showing
12 changed files
with
322 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,13 +37,15 @@ | |
}, | ||
"packageManager": "[email protected]", | ||
"devDependencies": { | ||
"@types/canvas-confetti": "^1.6.4", | ||
"husky": "^8.0.1", | ||
"lint-staged": "^13.0.3" | ||
}, | ||
"engines": { | ||
"node": ">=18.17.0" | ||
}, | ||
"dependencies": { | ||
"axios": "^1.7.7" | ||
"axios": "^1.7.7", | ||
"canvas-confetti": "^1.9.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,62 @@ | ||
"use client"; | ||
|
||
import { useRouter } from "next/navigation"; | ||
import { useState } from "react"; | ||
import { useRouter, useSearchParams } from "next/navigation"; | ||
import { Address } from "viem"; | ||
import { useAccount } from "wagmi"; | ||
import ReviewPage from "~~/components/inspectorAiComponents/ReviewPage"; | ||
import { AddressInput } from "~~/components/scaffold-eth"; | ||
import { RainbowKitCustomConnectButton } from "~~/components/scaffold-eth"; | ||
|
||
// Expected URL structure: /?address=0x1234...5678&chain=ethereum | ||
// Example: http://localhost:3000/?address=0x1234567890123456789012345678901234567890&chain=ethereum | ||
|
||
export default function Home() { | ||
const router = useRouter(); | ||
const { isConnected } = useAccount(); | ||
const router = useRouter(); | ||
const searchParams = useSearchParams(); | ||
|
||
const [inputAddress, setInputAddress] = useState<Address>(); | ||
|
||
console.log("page: Home component rendered, isConnected:", isConnected); | ||
|
||
const address = searchParams.get("address"); | ||
const chain = searchParams.get("chain") || "ethereum"; | ||
|
||
if (!isConnected) { | ||
router.push("/wallet-connection"); | ||
} else { | ||
router.push("/world-id-verification"); | ||
} | ||
const handleAddressSubmit = (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
if (inputAddress) { | ||
router.push(`/?address=${inputAddress}&chain=${chain}`); | ||
} | ||
}; | ||
|
||
return ( | ||
<main className="flex min-h-screen flex-col items-center justify-center p-24"> | ||
<h1 className="text-4xl font-bold mb-8">Welcome to PumpInspector</h1> | ||
<p>Loading...</p> | ||
{isConnected ? ( | ||
address ? ( | ||
<ReviewPage address={address} chain={chain} /> | ||
) : ( | ||
<div className="text-center w-full max-w-2xl"> | ||
<h1 className="text-4xl font-bold mb-8">Review a Contract</h1> | ||
<form onSubmit={handleAddressSubmit} className="space-y-4"> | ||
<AddressInput | ||
value={inputAddress || ""} | ||
onChange={value => setInputAddress(value as Address)} | ||
placeholder="Enter contract address to review" | ||
/> | ||
<button type="submit" className="btn btn-primary"> | ||
Review Contract | ||
</button> | ||
</form> | ||
</div> | ||
) | ||
) : ( | ||
<div className="text-center"> | ||
<h1 className="text-4xl font-bold mb-4">Welcome to Inspector AI</h1> | ||
<p className="mb-4">Please connect your wallet to continue.</p> | ||
<RainbowKitCustomConnectButton /> | ||
</div> | ||
)} | ||
</main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
packages/nextjs/components/inspectorAiComponents/ReviewPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
"use client"; | ||
|
||
import { useEffect, useState } from "react"; | ||
import { IDKitWidget, ISuccessResult, VerificationLevel } from "@worldcoin/idkit"; | ||
import { useInspectorAI } from "~~/hooks/scaffold-eth/useInspectorAI"; | ||
|
||
interface ReviewPageProps { | ||
address: string; | ||
chain: string; | ||
} | ||
|
||
export default function ReviewPage({ address, chain }: ReviewPageProps) { | ||
console.log("ReviewPage: Rendering with props:", { address, chain }); | ||
|
||
const [isVerified, setIsVerified] = useState(false); | ||
const [rating, setRating] = useState<number>(0); | ||
const [comment, setComment] = useState<string>(""); | ||
const { addReview, loadReviews, reviews, isAddingReview } = useInspectorAI(address); | ||
|
||
console.log("ReviewPage: Hook values:", { reviews, isAddingReview }); | ||
|
||
useEffect(() => { | ||
console.log("ReviewPage: useEffect - Loading reviews"); | ||
loadReviews(); | ||
}, [loadReviews]); | ||
|
||
const handleVerification = () => { | ||
console.log("ReviewPage: Verification successful"); | ||
setIsVerified(true); | ||
}; | ||
|
||
const handleSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
console.log("ReviewPage: Submitting review", { rating, comment }); | ||
await addReview(rating, comment); | ||
setRating(0); | ||
setComment(""); | ||
}; | ||
|
||
const verifyProof = async (proof: ISuccessResult) => { | ||
console.log("ReviewPage: Proof received:", proof); | ||
handleVerification(); | ||
}; | ||
|
||
console.log("ReviewPage: Current state", { isVerified, rating, comment, reviews }); | ||
|
||
return ( | ||
<div className="container mx-auto p-4 bg-background text-textDark"> | ||
<div className="card bg-primary shadow-xl max-w-md mx-auto"> | ||
<div className="card-body bg-card rounded-md"> | ||
<h2 className="card-title text-background">Review Contract</h2> | ||
<p className="text-sm opacity-70 text-background">Chain: {chain}</p> | ||
<p className="text-sm opacity-70 text-background">Address: {address}</p> | ||
<form onSubmit={handleSubmit}> | ||
<div className="form-control"> | ||
<div className="rating rating-lg"> | ||
{[1, 2, 3, 4, 5].map(star => ( | ||
<input | ||
key={star} | ||
type="radio" | ||
name="rating" | ||
className="mask mask-star-2 bg-warningDark" | ||
checked={rating === star} | ||
onChange={() => setRating(star)} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
<div className="form-control mt-5"> | ||
<textarea | ||
className={`textarea textarea-bordered h-24 bg-card text-black border-1 ${ | ||
comment ? "border-primary" : "border-gray-300" | ||
} rounded-md`} | ||
placeholder="Write your review here..." | ||
value={comment} | ||
onChange={e => setComment(e.target.value)} | ||
></textarea> | ||
</div> | ||
<div className="form-control mt-4"> | ||
<IDKitWidget | ||
app_id="app_staging_1b80c195333c350add4fda2d1e29d3f5" | ||
action="verifyidentity" | ||
onSuccess={verifyProof} | ||
verification_level={VerificationLevel.Device} | ||
> | ||
{({ open }) => ( | ||
<button type="button" className="btn bg-primary text-textDark" onClick={open}> | ||
Verify with WorldID (Optional) | ||
</button> | ||
)} | ||
</IDKitWidget> | ||
</div> | ||
<div className="form-control mt-6"> | ||
<button | ||
type="submit" | ||
className={`btn bg-primary text-textDark hover:bg-primary-focus ${ | ||
isAddingReview || rating === 0 || comment.trim() === "" ? "bg-gray-600" : "" | ||
}`} | ||
disabled={isAddingReview || rating === 0 || comment.trim() === ""} | ||
> | ||
{isAddingReview ? "Submitting..." : "Submit Review"} | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
<div className="mt-8"> | ||
<h3 className="text-2xl font-bold mb-4 text-textDark">Reviews</h3> | ||
{reviews.length > 0 ? ( | ||
<ul className="space-y-4"> | ||
{reviews.map((review, index) => ( | ||
<li key={index} className="bg-primary p-4 rounded-lg"> | ||
<div className="flex items-center mb-2"> | ||
<div className="rating rating-sm"> | ||
{[1, 2, 3, 4, 5].map(star => ( | ||
<input | ||
key={star} | ||
type="radio" | ||
className="mask mask-star-2 bg-warningDark" | ||
checked={review.rating === star} | ||
readOnly | ||
/> | ||
))} | ||
</div> | ||
<span className="ml-2 text-sm opacity-70 text-textDark">by {review.reviewer}</span> | ||
</div> | ||
<p className="text-textDark">{review.comment}</p> | ||
</li> | ||
))} | ||
</ul> | ||
) : ( | ||
<p className="text-textDark">No reviews yet.</p> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.