-
Notifications
You must be signed in to change notification settings - Fork 1
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
Showing
23 changed files
with
2,214 additions
and
22 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
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,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> | ||
); | ||
} |
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,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> | ||
); | ||
} |
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,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> | ||
); | ||
} |
Oops, something went wrong.