Skip to content

Commit

Permalink
Merge pull request #232 from NoshonNetworks/solomon
Browse files Browse the repository at this point in the history
Feat: Add descriptive error messages, fix null numbers on owned land , add metadata and update favicon + update demo app landing
  • Loading branch information
Solomonsolomonsolomon authored Dec 13, 2024
2 parents 3429cad + 83fc762 commit 8a3ca13
Show file tree
Hide file tree
Showing 8 changed files with 526 additions and 78 deletions.
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

0 comments on commit 8a3ca13

Please sign in to comment.