Skip to content

Commit

Permalink
feat(cereony): add code to waitlist, insert wallet address
Browse files Browse the repository at this point in the history
  • Loading branch information
Swepool committed Sep 19, 2024
1 parent 8589736 commit c40b7e6
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 69 deletions.
10 changes: 5 additions & 5 deletions ceremony/src/lib/components/Ceremony.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ let addressValidState: ValidState = $state("PENDING")
<H2>Queue length: <span class="text-union-accent-500">{contributor.queueState.count}</span></H2>
<H3>Waiting time: <span class="text-union-accent-500">{contributor.queueState.estimatedTime} minutes</span> (est.).
</H3>


<H2>Get your nft</H2>
<AddressForm class="" onValidation={result => (addressValidState = result)}/>

{#if contributor.clientState === 'offline'}
<Install/>
{/if}
Expand All @@ -55,12 +58,9 @@ let addressValidState: ValidState = $state("PENDING")

<div class="flex flex-col justify-center items-center gap-4">
<H1>Thank you! Your contribution is completed.</H1>
<H2>Get your nft</H2>
<AddressForm class="" onValidation={result => (addressValidState = result)}/>
<Tweet tweetText="0____0"/>
<Tweet url="https://union.build"/>
</div>

<!--Your turn but no client-->
{:else if contributor.state === 'noClient'}
<H1>No client. Cannot start contribution.</H1>
<Install/>
Expand Down
68 changes: 68 additions & 0 deletions ceremony/src/lib/components/Code.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script lang="ts">
import { callJoinQueue } from "$lib/supabase"
import { toast } from "svelte-sonner"
import type { ContributorState } from "$lib/stores/state.svelte.ts"
import Button from "$lib/components/Button.svelte"
type Props = {
contributor: ContributorState
}
let { contributor }: Props = $props()
let words: Array<string> = $state(new Array(6).fill(""))
let code = $derived(normalizeString(words))
let codeLoading = $state(false)
function handlePaste(e: ClipboardEvent): void {
e.preventDefault()
const pastedText: string = e.clipboardData?.getData("text") || ""
const pastedWords: Array<string> = pastedText.split(/\s+/).slice(0, 6)
words = [...pastedWords, ...new Array(6 - pastedWords.length).fill("")]
}
function normalizeString(words: Array<string>): string {
return words
.map(word => word.trim().toLowerCase())
.join("")
.replace(/[^a-z0-9]/gi, "")
}
async function handleCodeJoin() {
codeLoading = true
try {
console.log(code)
const codeOk = await callJoinQueue(code)
if (codeOk) {
contributor.setAllowanceState("hasRedeemed")
toast.success("Code successfully redeemed")
} else {
toast.error("The code is not valid")
}
} catch (error) {
console.error("Error redeeming code:", error)
toast.error("An error occurred while redeeming the code")
} finally {
codeLoading = false
words = new Array(6).fill("")
}
}
</script>


<div class="flex gap-2 max-w-4xl flex-wrap justify-center mb-8">
{#each words as word, index}
<input
bind:value={words[index]}
onpaste={handlePaste}
class="bg-transparent border-b border-white w-20 text-center text-union-accent-500 outline-none focus:ring-0 focus:border-union-accent-500"
style="--tw-ring-color: transparent;"
/>
{#if index !== words.length - 1}
<div class="text-union-accent-500"><p>-</p></div>
{/if}
{/each}
</div>
<Button loading={codeLoading} type="button" onclick={handleCodeJoin}>
USE CODE
</Button>
3 changes: 3 additions & 0 deletions ceremony/src/lib/components/Install.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import H1 from "$lib/components/typography/H1.svelte"
import Button from "$lib/components/Button.svelte"
let command = "docker run -p 4919:4919 -it haitlahcen/union-mpc-cli:latest"
const copy = () => {
navigator.clipboard.writeText(command)
toast.success("Copied to clipboard", { position: "bottom-right" })
}
</script>



<code class="text-sm sm:text-base inline-flex text-left items-center space-x-4 bg-black text-white p-4 pl-6 font-mono">
<span class="flex gap-4">
<span class="shrink-0 text-union-accent-500">
Expand Down
67 changes: 6 additions & 61 deletions ceremony/src/lib/components/Join.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Text from "$lib/components/typography/Text.svelte"
import { callJoinQueue, checkIfOpen } from "$lib/supabase"
import type { ContributorState } from "$lib/stores/state.svelte.ts"
import { toast } from "svelte-sonner"
import Code from "$lib/components/Code.svelte"
type Props = {
contributor: ContributorState
Expand All @@ -13,46 +14,8 @@ type Props = {
let { contributor }: Props = $props()
let isOpenToPublic = $state(false)
let codeLoading = $state(false)
let waitlistLoading = $state(false)
let words: Array<string> = $state(new Array(6).fill(""))
let code = $derived(normalizeString(words))
function handlePaste(e: ClipboardEvent): void {
e.preventDefault()
const pastedText: string = e.clipboardData?.getData("text") || ""
const pastedWords: Array<string> = pastedText.split(/\s+/).slice(0, 6)
words = [...pastedWords, ...new Array(6 - pastedWords.length).fill("")]
}
function normalizeString(words: Array<string>): string {
return words
.map(word => word.trim().toLowerCase())
.join("")
.replace(/[^a-z0-9]/gi, "")
}
async function handleCodeJoin() {
codeLoading = true
try {
console.log(code)
const codeOk = await callJoinQueue(code)
if (codeOk) {
contributor.setAllowanceState("hasRedeemed")
toast.success("Code successfully redeemed")
} else {
toast.error("The code is not valid")
}
} catch (error) {
console.error("Error redeeming code:", error)
toast.error("An error occurred while redeeming the code")
} finally {
codeLoading = false
words = new Array(6).fill("")
}
}
async function handleWaitlistJoin() {
waitlistLoading = true
try {
Expand Down Expand Up @@ -83,30 +46,12 @@ $effect(() => {

<div class="text-center flex flex-col gap-4 items-center">
<H1>Join the ceremony</H1>

<form class="flex flex-col items-center">
<div class="flex gap-2 max-w-4xl flex-wrap justify-center mb-4">
{#each words as word, index}
<input
bind:value={words[index]}
onpaste={handlePaste}
class="bg-transparent border-b border-white w-20 text-center text-union-accent-500 outline-none focus:ring-0 focus:border-union-accent-500"
style="--tw-ring-color: transparent;"
/>
{#if index !== words.length - 1}
<div class="text-union-accent-500"><p>-</p></div>
{/if}
{/each}
</div>
<Code {contributor}/>
</form>
<Text>Or</Text>
<Button loading={waitlistLoading} onclick={handleWaitlistJoin} type="button">
{isOpenToPublic ? "Join the queue" : "Join the waitlist"}
</Button>

<div class="flex items-center gap-4">
<Button loading={codeLoading} type="button" onclick={handleCodeJoin}>
USE CODE
</Button>
<Text>Or</Text>
<Button loading={waitlistLoading} onclick={handleWaitlistJoin} type="button">
{isOpenToPublic ? "Join the queue" : "Join the waitlist"}
</Button>
</div>
</div>
3 changes: 2 additions & 1 deletion ceremony/src/lib/components/Tweet.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import Button from "$lib/components/Button.svelte"
type Props = {
tweetText: string
tweetText?: string
url?: string
}
let { tweetText, url }: Props = $props()
function shareOnTwitter() {
const tweetText = "I've contributed to Union Ceremony\n\n"
const twitterIntentUrl = new URL("https://twitter.com/intent/tweet")
twitterIntentUrl.searchParams.append("text", tweetText)
if (url) twitterIntentUrl.searchParams.append("url", url)
Expand Down
23 changes: 22 additions & 1 deletion ceremony/src/lib/components/address/AddressForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { watch, Debounced } from "runed"
import type { ValidState } from "./index.ts"
import { isValidBech32Address } from "./validator.ts"
import type { HTMLInputAttributes } from "svelte/elements"
import { insertWalletData } from "$lib/supabase"
import { user } from "$lib/stores/user.svelte.ts"
interface Props extends HTMLInputAttributes {
class?: string
Expand All @@ -28,12 +30,31 @@ $effect(() => {
if (validState === "INVALID") toast.error(`Address is not valid`)
})
const onAddressSubmit = (event: Event) => {
const onAddressSubmit = async (event: Event) => {
event.preventDefault()
if (!debouncedInputText.current) return
const addressValidation = isValidBech32Address(debouncedInputText.current)
validState = addressValidation ? "VALID" : "INVALID"
onValidation(validState)
const userId = user.session?.user.id
if (validState === "VALID") {
try {
if (!userId) return
const result = await insertWalletData({
id: userId,
wallet: debouncedInputText.current
})
if (result) {
toast.success("Wallet address saved successfully")
} else {
toast.error("Failed to save wallet address")
}
} catch (error) {
console.error("Error saving wallet address:", error)
toast.error("An error occurred while saving the wallet address")
}
}
}
</script>

Expand Down
24 changes: 24 additions & 0 deletions ceremony/src/lib/supabase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,27 @@ export const getUserContribution = async (hash: string) => {

return data
}

interface WalletData {
id: string
wallet: string
}

export const insertWalletData = async (data: WalletData) => {
const { data: insertedData, error } = await supabase
.from("wallet_address")
.insert([
{
id: data.id,
wallet: data.wallet
}
])
.select()

if (error) {
console.error("Error inserting data:", error)
return null
}

return insertedData
}
6 changes: 5 additions & 1 deletion ceremony/src/routes/0____0/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Spinner from "$lib/components/Spinner.svelte"
import Ceremony from "$lib/components/Ceremony.svelte"
import H1 from "$lib/components/typography/H1.svelte"
import Join from "$lib/components/Join.svelte"
import Code from "$lib/components/Code.svelte"
const contributor: ContributorState = getContributorState()
</script>
Expand All @@ -14,7 +15,10 @@ const contributor: ContributorState = getContributorState()
{:else if contributor.allowanceState === "hasRedeemed" || contributor.allowanceState === "inQueue"}
<Ceremony {contributor}/>
{:else if contributor.allowanceState === "inWaitlist"}
<H1>You're on the list</H1>
<H1 class="mb-4">You're on the waitlist</H1>
<form class="flex flex-col items-center">
<Code {contributor} />
</form>
{:else if contributor.allowanceState === "join"}
<Join {contributor}/>
{/if}
Expand Down

0 comments on commit c40b7e6

Please sign in to comment.