Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add descriptive error messages, fix null numbers on owned land , add metadata and update favicon + update demo app landing #232

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ While initially built on Starknet, LandVer is designed to be cross-chain compati

The project is divided into the following components:

- `backend/`: Node.js and Express-based API server
- `land-registry-backend/`: Node.js and Express-based API server
- `docs/`: Documentation for the project, including setup guides and API references
- `examples/`: React-based web application
- `land_registry/`: Land registry contract
Expand Down
1 change: 1 addition & 0 deletions app/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"react-dom": "^18",
"react-icons": "^5.3.0",
"react-spinners": "^0.14.1",
"react-toastify": "^10.0.6",
"starknet": "^6.11.0",
"starknetkit": "^2.3.3",
"tailwind-merge": "^2.5.5",
Expand Down
21 changes: 18 additions & 3 deletions app/client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

318 changes: 318 additions & 0 deletions app/client/public/images/LANDVER_BLACK.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 34 additions & 3 deletions app/client/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Metadata } from "next";
//import localFont from "next/font/local";
import "./globals.css";
import { Providers } from "./Providers";

Expand All @@ -9,17 +8,49 @@ const manrope = Manrope({
});

export const metadata: Metadata = {
title: "Landver Application",
description: "Onchain Land Management",
title: "Landver Application | Onchain Land Management",
description:
"Landver is a blockchain-powered land management platform offering secure and transparent land registration and ownership verification.",
icons: {
icon: "/images/LANDVER_BLACK.svg",
apple: "/images/LANDVER_BLACK.svg",
},
openGraph: {
title: "Landver Application",
description:
"Experience next-generation on-chain land registration with Landver. Ensure secure, immutable, and transparent land records.",
url: "https://www.demo.landver.net",
type: "website",
images: [
{
url: "/images/landver-og-image.jpg", // Replace with our Open Graph image URL
width: 1200,
height: 630,
alt: "Landver - Onchain Land Management",
},
],
},
twitter: {
card: "summary_large_image",
site: "@landver0",
title: "Landver Application",
description:
"Discover Landver, the ultimate blockchain solution for land registration and ownership verification.",
images: ["/images/landver-og-image.jpg"], // Replace with our image URL
},
};


export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
<link rel="icon" href="/logo.jpeg" type="image/jpeg" />
</head>
<body
className={`${manrope.className} antialiased overflow-hidden text-black`}
>
Expand Down
199 changes: 133 additions & 66 deletions app/client/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"use client";

'use client'
import React, { useState } from "react";
import { useRouter } from "next/navigation";
import { useAccount } from "@starknet-react/core";
import WalletConnector from "@/components/Connector";
import Modal from "@/components/Modal/Modal";
import {Button} from "@/components/Button/Button";
import Image from 'next/image'
import { Button } from "@/components/Button/Button";
import Image from "next/image";
import { useLoginStore } from "@/store/loginStore";
import { LandPlot, ShieldCheck, Wallet, ArrowRight } from "lucide-react";

const Home = () => {
const loginStore = useLoginStore();
Expand All @@ -27,84 +27,151 @@ const Home = () => {
return;
}

const allowedUserTypes = ["owner", "inspector"]
// this is just in case of mispellings on select options value, to help future devs when make changes here on the userType select
if (!allowedUserTypes.includes(userType)) {
setError("Not allowed user type.");
const allowedUserTypes = ["owner", "inspector"];
if (!allowedUserTypes.includes(userType)) {
setError("Not allowed user type.");
return;
}
window.localStorage.setItem("user-type", userType)
window.localStorage.setItem("user-type", userType);
loginStore.setUserType(userType);
router.push("/dashboard");
};

return (

<div className="min-h-screen flex flex-col items-center justify-center bg-gray-50">
<Image src="/images/logo.svg" alt="landver logo" height={200} width={200}/>
<h1 className="text-4xl font-bold mb-6">Land Registry</h1>
const UserTypeCard = ({
type,
icon: Icon,
title,
description,
}: {
type: "owner" | "inspector";
icon: React.ElementType;
title: string;
description: string;
}) => (
<div
onClick={() => setUserType(type)}
className={`
border-2 p-4 rounded-lg cursor-pointer transition-all duration-300
${
userType === type
? "border-purple-600 bg-purple-50 scale-105"
: "border-gray-200 hover:border-purple-300"
}
`}
>
<div className="flex items-center mb-3">
<Icon
className={`mr-3 ${
userType === type ? "text-purple-600" : "text-gray-500"
}`}
/>
<h3 className="text-lg font-semibold">{title}</h3>
</div>
<p className="text-gray-600">{description}</p>
</div>
);

{status === "connected" ? (
<div className="text-center">
<p className="text-xl font-medium text-gray-700 mb-4">
Connected as:{" "}
<span className="font-bold">
{address?.slice(0, 6)}...{address?.slice(-4)}
</span>
return (
<div className="min-h-screen bg-gray-50 py-8 px-4 overflow-y-auto flex justify-center items-center">
<div className="max-w-4xl w-full mx-auto grid md:grid-cols-2 gap-8 bg-white rounded-2xl shadow-2xl">
{/* Left Side - Descriptive Section */}
<div className="bg-gradient-to-br from-purple-600 to-indigo-700 p-8 md:flex flex-col justify-center text-white hidden ">
<Image
src="/images/logo.svg"
alt="landver logo"
height={100}
width={100}
className="mb-6"
/>
<h1 className="text-3xl font-bold mb-4">Land Registry Protocol</h1>
<p className="text-lg mb-6 opacity-80">
Secure, transparent, and efficient land registration powered by
blockchain technology.
</p>
<form
onSubmit={handleFormSubmit}
className="bg-white p-6 rounded-lg shadow-md w-80"
>
<h2 className="text-lg font-semibold mb-4">Select User Type</h2>

<div className="mb-4">
<label className="block mb-2 font-medium">User Type</label>
<select
className="w-full border border-gray-300 rounded-lg p-2"
value={userType || ""}
onChange={(e) => setUserType(e.target.value as "owner"|"inspector")}
>
<option value="" disabled>
Select an option
</option>
<option value="owner">Land Owner</option>
<option value="inspector">Land Inspector</option>
</select>
<div className="space-y-4">
<div className="flex items-center">
<LandPlot className="mr-3 text-yellow-300" />
<span>Immutable Land Records</span>
</div>
<div className="flex items-center">
<ShieldCheck className="mr-3 text-green-300" />
<span>Verified Ownership Verification</span>
</div>
</div>
</div>

{error && <p className="text-red-500 text-sm mb-4">{error}</p>}
{/* Right Side - Connection & User Type */}
<div className="p-8 flex flex-col justify-center">
{status !== "connected" ? (
<div className="text-center">
<Wallet className="mx-auto text-purple-600 mb-4" size={64} />
<h2 className="text-2xl font-bold mb-4">Connect Your Wallet</h2>
<p className="text-gray-600 mb-6">
Connect a supported wallet to access Land Registry
</p>
<Button
onClick={toggleModal}
classname="mx-auto flex items-center gap-2 bg-purple-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-purple-700"
>
Connect Wallet <ArrowRight size={20} />
</Button>

<Button
type="submit"
// onClick={myUndefinedFunction}
classname="w-full bg-purple-600 text-white py-2 rounded-lg hover:bg-purple-700"
>
Proceed
</Button>
</form>
</div>
) : (
<>
<Button
onClick={toggleModal}
classname="bg-purple-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-purple-700"
>
Connect Wallet
</Button>
{isModalOpen && (
<Modal onClose={toggleModal} isOpen={isModalOpen}>
<div className="text-center p-6">
<h2 className="text-2xl font-bold mb-4">
Connect Your Wallet
</h2>
<WalletConnector />
</div>
</Modal>
)}
</div>
) : (
<form onSubmit={handleFormSubmit}>
<div className="text-center mb-6">
<p className="text-gray-600">Connected Wallet:</p>
<p className="font-bold text-purple-600">
{address?.slice(0, 6)}...{address?.slice(-4)}
</p>
</div>

<h2 className="text-2xl font-bold mb-4 text-center">
Select Your Role
</h2>

{isModalOpen && (
<Modal onClose={toggleModal} isOpen={isModalOpen}>
<div className="text-center p-6">
<h2 className="text-2xl font-bold mb-4">Connect Your Wallet</h2>
<WalletConnector />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<UserTypeCard
type="owner"
icon={LandPlot}
title="Land Owner"
description="Manage and verify your land ownership"
/>
<UserTypeCard
type="inspector"
icon={ShieldCheck}
title="Land Inspector"
description="Verify and validate land records"
/>
</div>
</Modal>

{error && (
<p className="text-red-500 text-sm mb-4 text-center">{error}</p>
)}

<Button
type="submit"
classname="w-full bg-purple-600 text-white py-3 rounded-lg hover:bg-purple-700 flex items-center justify-center gap-2"
>
Proceed to Dashboard <ArrowRight size={20} />
</Button>
</form>
)}
</>
)}
</div>
</div>
</div>
);
};

export default Home;
export default Home;
Loading
Loading