Skip to content

Commit 60a4feb

Browse files
authored
Merge pull request #76 from VoiceDeck/dev
Patch 1.0.5 - Layout & ETH
2 parents 082f172 + ea79db4 commit 60a4feb

21 files changed

+263
-213
lines changed

app/api/reports/update/route.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { fetchNewReports } from "@/lib/impact-reports";
2+
import { NextResponse } from "next/server";
3+
4+
export async function GET() {
5+
try {
6+
await fetchNewReports();
7+
return NextResponse.json({ status: 200 });
8+
} catch (error) {
9+
let errorMessage = "An unknown error occurred";
10+
if (typeof error === "object" && error !== null) {
11+
errorMessage = (error as { message?: string }).message ?? errorMessage;
12+
} else if (typeof error === "string") {
13+
errorMessage = error;
14+
}
15+
return NextResponse.json({ error: errorMessage }, { status: 500 });
16+
}
17+
}

app/page.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { redirect } from "next/navigation";
2+
export default async function Home() {
3+
redirect("/reports");
4+
}

app/profile/[address]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default async function ProfilePage({
7474
reportCount = 0,
7575
} = await getContributionsHistoryData(address);
7676
return (
77-
<main className="container grid grid-cols-1 md:grid-cols-3 auto-rows-auto md:gap-4 gap-4 text-vd-blue-900 mb-6 max-w-6xl pb-16 md:pb-0">
77+
<main className="p-4 md:px-6 xl:px-0 md:py-8 md:max-w-[1200px] mx-auto grid grid-cols-1 md:grid-cols-3 auto-rows-auto md:gap-4 gap-4 text-vd-blue-900 mb-6 max-w-6xl pb-16 md:pb-0">
7878
<header className="md:col-span-3 flex justify-between my-4">
7979
<h1 className="text-xl md:text-3xl font-semibold">My Actions</h1>
8080
<Link

app/profile/[address]/settings/page.tsx

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
import { UserInfo } from "@/components/settings/user-info";
22
import { VerifiedCitizen } from "@/components/settings/verified-citizen";
3+
import { ChevronLeft } from "lucide-react";
4+
import Link from "next/link";
35

46
export default function SettingsPage({
57
params: { address },
68
}: {
79
params: { address: `0x${string}` };
810
}) {
911
return (
10-
<main className="container mx-auto flex flex-col gap-4 text-vd-blue-900 mb-6 max-w-3xl pb-16 md:pb-0">
11-
<header className="md:col-span-3 flex justify-between pt-4">
12+
<main className="p-4 md:p-8 md:max-w-screen-xl mx-auto flex flex-col gap-4 text-vd-blue-900 mb-6 max-w-3xl pb-16 md:pb-0">
13+
<header className="md:col-span-3 pt-4">
14+
<Link
15+
href={`/profile/${address}`}
16+
className="group flex space-x-1 items-center"
17+
>
18+
<ChevronLeft
19+
size={24}
20+
className="text-vd-blue-400 group-hover:-translate-x-2 transition-transform duration-300 ease-in-out"
21+
/>
22+
<p className="font-semibold text-sm uppercase text-vd-blue-500 tracking-wider">
23+
Profile
24+
</p>
25+
</Link>
26+
<div className="p-2" />
1227
<h1 className="text-3xl md:text-4xl font-semibold">Settings</h1>
1328
</header>
1429
<UserInfo />

app/reports/[slug]/page.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ export default async function ReportPage({ params }: ReportPageProps) {
9393
<div className="fixed bottom-[96px] -mx-4 -my-4 md:relative md:bottom-auto md:mx-0 md:my-0 w-full">
9494
<FundingDataWrapper
9595
hypercertId={report.hypercertId}
96-
totalReportCost={report.totalCost}
96+
totalAmount={report.totalCost}
97+
fundedAmount={report.fundedSoFar}
9798
>
9899
<FundingProgress
99100
totalAmount={report.totalCost}

components/report-details/funding-data-wrapper.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ import { Loader2 } from "lucide-react";
77
interface FundingDataWrapperProps {
88
hypercertId: Partial<Report>["hypercertId"];
99
children: React.ReactNode;
10-
totalReportCost: Partial<Report>["totalCost"];
10+
totalAmount: Partial<Report>["totalCost"];
11+
fundedAmount: Partial<Report>["fundedSoFar"];
1112
}
1213

1314
const FundingDataWrapper: React.FC<FundingDataWrapperProps> = ({
14-
totalReportCost,
1515
hypercertId,
16+
totalAmount,
17+
fundedAmount,
1618
children,
1719
}: FundingDataWrapperProps) => {
1820
if (!hypercertId) {
1921
return <div>No hypercertId found </div>;
2022
}
21-
if (!totalReportCost) {
23+
if (!totalAmount) {
2224
return <div>No total cost found</div>;
2325
}
2426

@@ -49,12 +51,12 @@ const FundingDataWrapper: React.FC<FundingDataWrapperProps> = ({
4951
}
5052

5153
const totalUnits = hypercertClaim.totalUnits;
52-
const pricePerUnit = totalReportCost / Number(totalUnits);
54+
const pricePerUnit = totalAmount / Number(totalUnits);
5355
const unitsRemaining = genesisFraction.units;
5456
const percentProgress =
5557
((totalUnits - genesisFraction.units) / totalUnits) * 100;
5658
const minUnitAmount = 1 / pricePerUnit;
57-
const dollarAmountNeeded = (pricePerUnit * genesisFraction.units).toFixed(2);
59+
const dollarAmountNeeded = (totalAmount - (fundedAmount || 0)).toFixed(2);
5860

5961
return (
6062
<FundingProvider
@@ -63,7 +65,7 @@ const FundingDataWrapper: React.FC<FundingDataWrapperProps> = ({
6365
hypercertClaim,
6466
pricePerUnit,
6567
totalUnits,
66-
totalReportCost,
68+
totalAmount,
6769
unitsRemaining,
6870
percentProgress,
6971
minUnitAmount,

components/report-details/support/dialog.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const SupportContent = ({
4343
);
4444
}
4545
// TODO: remove this when we don't need dummy order
46-
if (process.env.DEPLOY_ENV === "production") {
46+
if (process.env.NEXT_PUBLIC_DEPLOY_ENV === "production") {
4747
return <SupportReportForm hypercertId={hypercertId} />;
4848
}
4949
return (

components/report-details/support/form.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ const SupportReportForm = ({ hypercertId }: SupportReportFormProps) => {
152152
Number(dollarAmountNeeded),
153153
pricePerUnit,
154154
// TODO: remove this when we don't need dummy order
155-
process.env.DEPLOY_ENV === "production" ? orders?.[0] : orders?.[5],
155+
process.env.NEXT_PUBLIC_DEPLOY_ENV === "production"
156+
? orders?.[0]
157+
: orders?.[5],
156158
handleBuyFraction,
157159
address,
158160
hypercertId,

components/reports/reports-view.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export function ReportsView({ reports }: IPageData) {
9393

9494
return (
9595
<section
96-
className="flex border-t border-t-stone-300 min-[2560px]:w-screen-2xl min-[2560px]:mx-auto"
96+
className="flex border-t border-t-stone-300 min-[2560px]:w-[64vw] min-[2560px]:grid min-[2560px]:mx-auto min-[2560px]:grid-cols-[380px_1fr]"
9797
id="discover"
9898
>
9999
<div className="hidden md:block">

components/reports/voicedeck-stats.tsx

+17-10
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,26 @@ const VoicedeckStats: React.FC<VoicedeckStatsProps> = ({
4242
reports,
4343
}) => {
4444
const contributionAmounts = useMemo(() => {
45-
const allAmounts = reports.map(
46-
(report: Report, index: number) => report.fundedSoFar || 0,
45+
const totalContributions = reports.reduce(
46+
(total: number, report: Report) => total + (report.fundedSoFar || 0),
47+
0,
48+
);
49+
const reportsFullyFunded = reports.reduce(
50+
(acc: Report[], report: Report) => {
51+
if (report.fundedSoFar === report.totalCost) {
52+
acc.push(report);
53+
}
54+
return acc;
55+
},
56+
[] as Report[],
4757
);
48-
const sumOfAmounts = allAmounts.reduce((a: number, b: number) => a + b, 0);
49-
const fullyFunded = allAmounts.filter((amount: number) => amount === 1000);
5058
return {
51-
amounts: allAmounts,
52-
sumOfContributions: sumOfAmounts,
53-
numOfContributions: fullyFunded.length || 0,
59+
totalContributions,
60+
fundedReports: reportsFullyFunded.length || 0,
5461
};
5562
}, [reports]);
5663

57-
const { sumOfContributions, numOfContributions } = contributionAmounts;
64+
const { totalContributions, fundedReports } = contributionAmounts;
5865

5966
return (
6067
<section className="flex flex-col lg:flex-row w-full gap-3 max-w-screen-xl">
@@ -68,14 +75,14 @@ const VoicedeckStats: React.FC<VoicedeckStatsProps> = ({
6875
key="elephant"
6976
icon="elephant"
7077
heading="Total support received"
71-
data={sumOfContributions}
78+
data={totalContributions}
7279
currency="USD"
7380
/>
7481
<StatContainer
7582
key="candle"
7683
icon="candle"
7784
heading="# of reports fully funded"
78-
data={numOfContributions}
85+
data={fundedReports}
7986
/>
8087
</section>
8188
);

components/settings/user-info.tsx

+20-33
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@ import { useRouter } from "next/navigation";
44
import { useAccount, useEnsName } from "wagmi";
55
import { mainnet } from "wagmi/chains";
66

7-
import { Input } from "@/components/ui/input";
87
import { Label } from "@/components/ui/label";
98

9+
import { Alert, AlertDescription } from "@/components/ui/alert";
1010
import { Separator } from "@/components/ui/separator";
11-
import { useWeb3Modal } from "@web3modal/wagmi/react";
1211
import { useEffect } from "react";
1312

1413
const UserInfo = () => {
15-
const { open } = useWeb3Modal();
16-
const { address, isConnected, isConnecting, isDisconnected } = useAccount();
14+
const { address, isConnected } = useAccount();
1715
const router = useRouter();
1816
const { data: ensName } = useEnsName({
1917
chainId: mainnet.id,
@@ -27,44 +25,33 @@ const UserInfo = () => {
2725
}
2826
}, [isConnected, router]);
2927

30-
// * Commented out the code to add the ability to connect wallet from this page
31-
// if (isConnecting) return <div>Connecting…</div>;
32-
// if (isDisconnected)
33-
// return (
34-
// <section className="h-40 w-full flex justify-center items-center">
35-
// <Button onClick={() => open()}>Connect Wallet</Button>
36-
// </section>
37-
// );
3828
return (
3929
<>
4030
<section className="flex flex-col gap-4 md:gap-0">
41-
<h2 className="text-xl md:text-2xl font-semibold md:py-6">Profile</h2>
31+
<h2 className="text-xl md:text-2xl font-semibold md:py-6">Account</h2>
4232
<div className="flex flex-col gap-2 md:col-start-1 md:col-span-2 md:mt-2">
4333
<Label htmlFor="displayName">Display Name</Label>
44-
<Input
45-
className="mb-0"
46-
type="displayName"
47-
placeholder={ensName ? ensName : "Voice Deck"}
48-
// disabled={ensName ? true : false}
49-
disabled={true}
50-
/>
51-
<small className="text-xs">
52-
We'll use your ENS name if you have one or you can set your own in
53-
the future.
34+
35+
<Alert className="bg-vd-beige-300 max-w-md">
36+
<AlertDescription className="truncate">
37+
{ensName ? ensName : "No ENS name found"}
38+
</AlertDescription>
39+
</Alert>
40+
<small className="text-sm">
41+
We'll use your ENS name if you have one.
5442
</small>
5543
</div>
56-
<h2 className="text-xl md:text-2xl font-semibold md:py-6">Account</h2>
44+
<div className="py-4" />
5745
<div className="flex flex-col gap-2 md:col-start-1 md:col-span-2 md:mt-2">
5846
<Label htmlFor="address">Wallet Address</Label>
59-
<Input
60-
className="disabled:bg-vd-blue-300"
61-
type="address"
62-
placeholder="Address"
63-
value={address}
64-
disabled
65-
/>
66-
<small className="text-xs">
67-
Where you fund will be store on the blockchain.
47+
<Alert className="bg-vd-beige-300 max-w-md">
48+
<AlertDescription className="truncate">
49+
{address ? address : "No address found"}
50+
</AlertDescription>
51+
</Alert>
52+
53+
<small className="text-sm">
54+
Your funds are stored on the blockchain here.
6855
</small>
6956
</div>
7057
</section>

components/settings/verified-citizen.tsx

+25-31
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,33 @@
11
import { HelpCircleIcon } from "lucide-react";
22

3-
import { cn } from "@/lib/utils";
4-
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
5-
import { Separator } from "@/components/ui/separator";
63
import { VerifiedStatus } from "@/components/settings/verified-status";
4+
import { Button } from "@/components/ui/button";
5+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
6+
import { cn } from "@/lib/utils";
77

88
const VerifiedCitizen = () => {
9-
return (
10-
<section className="flex flex-col gap-4">
11-
<h2 className="text-xl md:text-2xl font-semibold md:py-2">
12-
Verified Citizen
13-
</h2>
14-
<Card className="bg-vd-blue-200 rounded-3xl flex-1 shadow-none border-none">
15-
<CardHeader>
16-
<CardTitle className={cn("flex gap-1 items-center pb-0")}>
17-
<HelpCircleIcon size={16} strokeWidth={2} />
18-
Why does this matter?
19-
</CardTitle>
20-
</CardHeader>
21-
<CardContent>
22-
<p className="text-sm">
23-
We prioritize the authenticity of each report. Recognizing that
24-
local residents have the most accurate insights into matters
25-
affecting their own region, we want to give the power back to them.
26-
Using an advanced cryptographic developer tool known as Anon
27-
Aadhaar, we use Aadhaar’s QR code to verify an individual's
28-
citizenship without revealing any information about them. For
29-
further details, you can read more here.
30-
</p>
31-
</CardContent>
32-
</Card>
33-
<Separator />
34-
<VerifiedStatus />
35-
</section>
36-
);
9+
return (
10+
<section className="flex flex-col gap-4 max-w-lg">
11+
<h2 className="text-xl md:text-2xl font-semibold md:py-2">
12+
Citizen Verification
13+
</h2>
14+
<Card className="bg-vd-blue-200 rounded-md flex-1 shadow-none border-none">
15+
<CardHeader>
16+
<CardTitle className={cn("flex gap-1 items-center pb-0")}>
17+
<HelpCircleIcon size={16} strokeWidth={2} />
18+
Why does this matter?
19+
</CardTitle>
20+
</CardHeader>
21+
<CardContent>
22+
Our focus is on report authenticity, empowering local residents with
23+
the most accurate regional insights. Through Anon Aadhaar, a
24+
sophisticated cryptographic tool, we verify citizenship using
25+
Aadhaar’s QR code, ensuring privacy. For more information, read here.
26+
</CardContent>
27+
</Card>
28+
<VerifiedStatus />
29+
</section>
30+
);
3731
};
3832

3933
VerifiedCitizen.displayName = "VerifiedCitizen";

components/settings/verified-status.tsx

+3-19
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,13 @@
11
"use client";
22
import { Button } from "@/components/ui/button";
3-
import { Separator } from "@radix-ui/react-dropdown-menu";
43
import React from "react";
54

6-
import { useDisconnect } from "wagmi";
7-
85
const VerifiedStatus = () => {
9-
const { disconnect } = useDisconnect();
106
return (
117
<>
12-
<div className="flex justify-between">
13-
<p>
14-
Status: <span>Not yet verified.</span>
15-
</p>
16-
<Button className="md:min-w-48">Verify Now</Button>
17-
</div>
18-
<Separator />
19-
<div className="flex md:block">
20-
<Button
21-
className="md:min-w-40"
22-
size="lg"
23-
variant="outline"
24-
onClick={() => disconnect()}
25-
>
26-
Log out
8+
<div className="flex flex-col md:flex-row justify-between md:items-center">
9+
<Button className="md:min-w-48" disabled>
10+
Verification coming soon...
2711
</Button>
2812
</div>
2913
</>

config/endpoint.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ const development = "https://app.vd-dev.org"
33
const localhost = "http://localhost:3000"
44

55
export const getVoiceDeckUrl = () => {
6-
if (process.env.DEPLOY_ENV === "production") {
6+
if (process.env.NEXT_PUBLIC_DEPLOY_ENV === "production") {
77
return production
8-
} else if (process.env.DEPLOY_ENV === "development") {
8+
} else if (process.env.NEXT_PUBLIC_DEPLOY_ENV === "development") {
99
return development
1010
} else {
1111
return localhost

0 commit comments

Comments
 (0)