Skip to content

Commit

Permalink
brand new client
Browse files Browse the repository at this point in the history
  • Loading branch information
scobru committed Dec 3, 2023
1 parent 046390c commit 16c828a
Show file tree
Hide file tree
Showing 23 changed files with 2,214 additions and 22 deletions.
16 changes: 11 additions & 5 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import React, { useCallback, useRef, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import { Bars3Icon } from "@heroicons/react/24/outline";
import { ArchiveBoxIcon, Bars3Icon, BugAntIcon, HomeIcon } from "@heroicons/react/24/outline";
import { FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
import { useOutsideClick } from "~~/hooks/scaffold-eth";


interface HeaderMenuLink {
label: string;
href: string;
icon?: React.ReactNode;
}
export const menuLinks: HeaderMenuLink[] = [
/*{
{
label: "Home",
href: "/",
icon: <HomeIcon className="h-4 w-4" />,
},
{
{
label: "Client",
href: "/client",
icon: <ArchiveBoxIcon className="h-4 w-4" />,
},
{
label: "Debug Contracts",
href: "/debug",
icon: <BugAntIcon className="h-4 w-4" />,
}, */
},
];

export const HeaderMenuLinks = () => {
Expand Down Expand Up @@ -104,4 +110,4 @@ export const Header = () => {
</div>
</div>
);
};
};
97 changes: 97 additions & 0 deletions packages/nextjs/components/client/authCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Dispatch, SetStateAction, useRef } from "react";
import { UnsignedEvent, generatePrivateKey, getPublicKey } from "nostr-tools";
import { GiSkeletonKey } from "react-icons/gi";
import { HiPencilSquare, HiUserCircle } from "react-icons/hi2";

interface AuthCardProps {
setSk: Dispatch<SetStateAction<string | null>>;
publishEvent: (event: UnsignedEvent, sk?: string) => void;
setShowKeysModal: Dispatch<SetStateAction<boolean>>;
privateKey: string | null;
}

export default function AuthCard(props: AuthCardProps) {
const skField = useRef<HTMLInputElement | null>(null);
const displayNameField = useRef<HTMLInputElement | null>(null);
const profilePicField = useRef<HTMLInputElement | null>(null);

if (props.privateKey) props.setSk(props.privateKey);

return (
<div className="flex flex-col space-y-5">
<div className="rounded-lgshadow p-5 border border-dashed ">
<div>
<div className="mt-2 relative rounded-md shadow-sm">
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<GiSkeletonKey className="text-green-700 dark:text-green-300 h-6 w-6" />
</div>
<input
className="block w-full bg-black/25 dark:bg-white/25 rounded-md border border-green-300 py-1.5 pl-12 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-green-900 placeholder:dark:text-green-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="Your Private Key..."
ref={skField}
/>
</div>
</div>

<button
className="mt-5 bg-base-100 text-green-700"
onClick={() => {
const sk = skField?.current?.value;
if (sk && sk?.length !== 64) return;

props.setSk(sk as string);
}}
>
Sign In
</button>
</div>

<div className="rounded-lg bg-gray-200 shadow p-5 dark:bg-[#1a1a1a] border border-dashed border-green-300">
<div className="relative rounded-md shadow-sm">
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<HiPencilSquare className="text-green-700 dark:text-green-300 h-6 w-6" />
</div>
<input
className="block w-full rounded-md bg-black/25 dark:bg-white/25 border border-green-300 py-1.5 pl-12 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-green-900 placeholder:dark:text-green-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="Your Display Name..."
ref={displayNameField}
/>
</div>
<div className="mt-2 relative rounded-md shadow-sm">
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<HiUserCircle className="text-green-700 dark:text-green-300 h-6 w-6" />
</div>
<input
className="block w-full rounded-md bg-black/25 dark:bg-white/25 border border-green-300 py-1.5 pl-12 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-green-900 placeholder:dark:text-green-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
placeholder="Profile Pic URL..."
ref={profilePicField}
/>
</div>

<button
className="mt-5 bg-base-100 text-green-700"
onClick={() => {
const sk: string = generatePrivateKey();
props.setSk(sk);
props.publishEvent(
{
kind: 0,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: JSON.stringify({
name: displayNameField?.current?.value,
picture: profilePicField?.current?.value,
}),
pubkey: getPublicKey(sk),
},
sk,
);
props.setShowKeysModal(true);
}}
>
Sign Up
</button>
</div>
</div>
);
}
84 changes: 84 additions & 0 deletions packages/nextjs/components/client/createPostCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { useRef } from "react";
import { useProfile } from "../../hooks/scaffold-eth/useProfile";
import { Filter, Relay, UnsignedEvent } from "nostr-tools";
import { LazyLoadImage } from "react-lazy-load-image-component";

interface CreatePostCardProps {
posterPK: string;
posterSK: string;
relay: Relay;
publishEvent: (event: UnsignedEvent) => void;
getEvents: (filters: Filter[]) => void;
setEthTipAmount: (amount: string) => void;
}

export default function CreatePostCard(props: CreatePostCardProps) {
const { data: userData } = useProfile({ pubkey: props.posterPK, relay: props.relay });

const textArea = useRef<HTMLTextAreaElement | null>(null);

return (
<div className="divide-y divide-white overflow-hidden rounded-lgshadow border border-dashed">
<div
className="px-4 py-5 sm:px-6 text-lg hover:dark:bg-base-300/25 hover:!text-xl hover:cursor-pointer hover:underline hover:decoration-green-300"
onClick={() => {
const filter: Filter[] = [
{
kinds: [1, 6],
authors: [props.posterPK],
},
];
props.getEvents(filter);
}}
>
<div className="flex flex-row justify-between">
<LazyLoadImage className="inline-block h-8 w-8 rounded-full" src={userData?.picture} alt="" />
<span className="font-bold text-gray-800 dark:text-gray-200">{userData?.name}</span>
<span className="inline-flex items-center gap-x-1.5 rounded-md bg-base-100 px-1.5 py-0.5 text-xs font-medium text-green-700">
<svg className="h-1.5 w-1.5 fill-green-500" viewBox="0 0 6 6" aria-hidden="true">
<circle cx="3" cy="3" r="3" />
</svg>
{props.posterPK?.slice(props.posterPK?.length - 6)}
</span>
</div>
</div>
<div className="px-4 py-5 sm:p-6">
<div className="mt-2">
<textarea
name="post"
id="post"
className="block w-full h-32 bg-gray-900/25 dark:bg-white/25 rounded-lg p-1.5 text-gray-900 text-xl shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-green-300 sm:leading-6 dark:text-white placeholder:text-gray-800 dark:placeholder:text-gray-200"
placeholder="Type your post..."
ref={textArea}
></textarea>
<button
className="mt-5 btn btn-ghost"
onClick={() => {
const newEvent = {
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: textArea?.current?.value,
pubkey: props.posterPK,
};

props.publishEvent(newEvent as UnsignedEvent);
}}
>
Publish
</button>
</div>
<div className="my-5">
<span className="text-gray-800 dark:text-gray-200">Tip with ETH</span>
<input
className="input input-ghost w-full my-2"
placeholder="Amount to tip"
onChange={e => {
props.setEthTipAmount(e.target.value);
}}
/>
</div>
</div>
</div>
);
}
73 changes: 73 additions & 0 deletions packages/nextjs/components/client/createdAccModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Dispatch, SetStateAction } from "react";
import { Notyf } from "notyf";
import "notyf/notyf.min.css";
import { FaExclamationCircle } from "react-icons/fa";

interface CreatedAccModalProps {
sk: string;
pk: string;
setShowKeysModal: Dispatch<SetStateAction<boolean>>;
}

export default function CreatedAccModal(props: CreatedAccModalProps) {
const notyf = new Notyf({
duration: 1000,
position: {
x: "center",
y: "center",
},
});

return (
<div className="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div className="fixed inset-0 bg-gray-900 bg-opacity-75 dark:bg-opacity-50 transition-opacity"></div>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div className="relative transform rounded-lg bg-gray-200 dark:bg-[#1a1a1a] px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-xl sm:p-6 border border-dashed border-green-300">
<div className="sm:flex sm:items-start">
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-200 sm:mx-0 sm:h-10 sm:w-10">
<FaExclamationCircle className="text-red-500" />
</div>
<div className="mt-3 w-full h-full text-center sm:ml-4 sm:mt-0 sm:text-left">
<h3 className="font-semibold text-gray-800 dark:text-gray-200" id="modal-title">
Store Your Keys Somewhere Safe Fren <span className="ml-2 text-lg font-bold text-green-700">:)</span>
</h3>
<div className="mt-10 w-full h-50 flex flex-row justify-center space-x-5">
<button
className="w-2/4 mx-auto bg-base-100 text-green-700"
onClick={() => {
navigator.clipboard.writeText(props.sk);
notyf.success("Copied Private Key!");
}}
>
Copy Private Key !
</button>
<button
className="w-2/4 mx-auto bg-base-100 text-green-700"
onClick={() => {
navigator.clipboard.writeText(props.pk);
notyf.success("Copied Public Key!");
}}
>
Copy Public Key !
</button>
</div>
</div>
</div>
<div className="mt-10 flex justify-center">
<button
type="button"
className="inline-flex w-full justify-center rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 sm:ml-3 sm:w-auto"
onClick={() => {
props.setShowKeysModal(false);
}}
>
Ive Stored My Keys !
</button>
</div>
</div>
</div>
</div>
</div>
);
}
Loading

0 comments on commit 16c828a

Please sign in to comment.