Skip to content

Commit

Permalink
Merge pull request #5 from ardriveapp/PE-5162_redeem
Browse files Browse the repository at this point in the history
feat: add a redeem page PE-5162
  • Loading branch information
fedellen authored Dec 11, 2023
2 parents db64361 + 3486930 commit 2e6dbe3
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 71 deletions.
4 changes: 2 additions & 2 deletions src/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { GiftPage } from "./pages/GiftPage";
import { Page } from "./pages/Page";
import { RedeemPage } from "./pages/RedeemPage";

export function Router() {
return (
<BrowserRouter basename={`${import.meta.env.BASE_URL}`}>
<Routes>
<Route path="/gift" element={<GiftPage />} />
<Route path="/redeem" element={<Page page={() => <p>TODO</p>} />} />
<Route path="/redeem" element={<RedeemPage />} />
<Route
path="/"
element={
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export const turboConfig = {
};
export const wincPerCredit = 1_000_000_000_000;
export const defaultDebounceMs = 500;
export const ardriveAppUrl = "https://app.ardrive.io";
6 changes: 6 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ input[type="number"] {
font-family: Wavehaus-Extra;
color: var(--ardrive-red);
}

h1 {
font-family: Wavehaus-Extra;
font-size: 2.15rem;
margin: 3rem 2rem;
}
65 changes: 0 additions & 65 deletions src/pages/GiftPage.css
Original file line number Diff line number Diff line change
@@ -1,47 +1,3 @@
.gift-form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0rem 2rem;
width: 100%;
max-width: 28rem;
}

.gift-form h1 {
font-family: Wavehaus-Extra;
font-size: 2.15rem;
margin: 3rem 2rem;
}

.form-section {
display: flex;
flex-direction: column;
align-items: left;
margin: 0.5rem 1rem;
width: 100%;
}

.form-label {
margin: 0.5rem 0.5rem 0.25rem 0.1rem;
font-size: 1.25rem;
font-weight: bold;
font-family: Wavehaus-Bold;
text-align: left;
font-size: 1rem;
}

.form-input {
width: 100%;
padding: 0.5rem 1rem;
border: 1px solid var(--off-gray);
border-radius: 0.5rem;
font-size: 1.2rem;
font-family: Wavehaus-Semi;
box-sizing: border-box;
background-color: var(--dark-gray);
}

/*
If the input is not focused, and the placeholder is not shown, and the input is invalid,
then change the border color to red to indicate invalid email address.
Expand Down Expand Up @@ -200,27 +156,6 @@ input[type="checkbox"]:checked::before {
margin: 0 0.75rem;
}

#gift-form-submit-button {
margin: 2rem;
padding: 1rem 1.25rem;
border: none;
border-radius: 3rem;
background-color: var(--ardrive-red);
color: var(--white);
font-size: 1.25rem;
font-family: Wavehaus-Bold;
cursor: pointer;
}

#gift-form-submit-button:hover {
background-color: var(--ardrive-red);
}

#gift-form-submit-button:disabled {
background-color: var(--off-gray);
cursor: not-allowed;
}

@media (prefers-color-scheme: light) {
.form-input,
#usd-input,
Expand Down
4 changes: 2 additions & 2 deletions src/pages/GiftPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function GiftForm({ errorCallback }: ErrMsgCallbackAsProps) {
};

return (
<form className="gift-form">
<form className="form">
<h1>Gift Credits to a friend.</h1>

<div className="form-section">
Expand Down Expand Up @@ -195,7 +195,7 @@ function GiftForm({ errorCallback }: ErrMsgCallbackAsProps) {

<button
type="submit"
id="gift-form-submit-button"
className="proceed-button"
onClick={(e) => handleSubmit(e)}
disabled={!canSubmitForm}
>
Expand Down
59 changes: 59 additions & 0 deletions src/pages/Page.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,62 @@
align-self: flex-end;
text-align: right;
}

.form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0rem 2rem;
width: 100%;
max-width: 28rem;
}

.form-section {
display: flex;
flex-direction: column;
align-items: left;
margin: 0.5rem 1rem;
width: 100%;
}

.form-label {
margin: 0.5rem 0.5rem 0.25rem 0.1rem;
font-size: 1.25rem;
font-weight: bold;
font-family: Wavehaus-Bold;
text-align: left;
font-size: 1rem;
}

.form-input {
width: 100%;
padding: 0.5rem 1rem;
border: 1px solid var(--off-gray);
border-radius: 0.5rem;
font-size: 1.2rem;
font-family: Wavehaus-Semi;
box-sizing: border-box;
background-color: var(--dark-gray);
}

.proceed-button {
margin: 2rem;
padding: 1rem 1.25rem;
border: none;
border-radius: 3rem;
background-color: var(--ardrive-red);
color: var(--white);
font-size: 1.25rem;
font-family: Wavehaus-Bold;
cursor: pointer;
}

.proceed-button:hover {
background-color: var(--ardrive-red);
}

.proceed-button:disabled {
background-color: var(--off-gray);
cursor: not-allowed;
}
128 changes: 126 additions & 2 deletions src/pages/RedeemPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,131 @@
export function RedeemPage() {
import { useEffect, useState } from "react";
import { ErrMsgCallbackAsProps } from "../types";
import { redeemGift } from "../utils/redeemGift";
import { ardriveAppUrl } from "../constants";
import { Page } from "./Page";
import { useLocation } from "react-router-dom";

function RedeemForm({ errorCallback }: ErrMsgCallbackAsProps) {
const [destinationAddress, setDestinationAddress] = useState("");
const [recipientEmail, setRecipientEmail] = useState("");
const [redemptionCode, setRedemptionCode] = useState("");

const location = useLocation();

useEffect(() => {
const urlParams = new URLSearchParams(location.search);

const redemptionCodeParam = urlParams.get("id");
const recipientEmailParam = urlParams.get("email");
const destinationAddressParam = urlParams.get("destinationAddress");

if (redemptionCodeParam) {
setRedemptionCode(redemptionCodeParam);
}
if (recipientEmailParam) {
setRecipientEmail(recipientEmailParam);
}
if (destinationAddressParam) {
setDestinationAddress(destinationAddressParam);
}
}, [location.search]);

const canSubmitForm =
!!destinationAddress && !!recipientEmail && !!redemptionCode;

const handleSubmit = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();

if (!canSubmitForm) {
return;
}

redeemGift({ redemptionCode, destinationAddress, recipientEmail })
.then(() => {
// TODO: Success Modal or Page
console.log("Gift redeemed!");
alert("Gift redeemed, redirecting to ArDrive App!");

setTimeout(() => {
console.log("Redirecting to ArDrive app...");
window.location.href = ardriveAppUrl;
}, 2000);
})
.catch((err) => {
errorCallback(`Error redeeming gift: ${err.message}`);
});
};

return (
<>
<p>TODO</p>
<h1>Redeem Turbo Credits</h1>
<p>
Enter the address of the Arweave wallet you would like to redeem your
Turbo Credits to.
</p>
<form className="form">
<div className="form-section">
<label className="form-label">Destination Address*</label>
<input
type="text"
className="form-input"
id="destination-address"
placeholder="Enter the destination address here"
value={destinationAddress}
onChange={(e) => {
setDestinationAddress(e.target.value);
}}
/>
</div>

<div className="form-section">
<label className="form-label">Redemption Code*</label>
<input
type="text"
className="form-input"
id="redemption-code"
placeholder="Enter the redemption code here"
value={redemptionCode}
onChange={(e) => {
setRedemptionCode(e.target.value);
}}
/>
</div>

<div className="form-section">
<label className="form-label">Recipient email address*</label>
<input
type="email"
className="form-input"
id="recipient-email"
placeholder="Confirm your email address here"
value={recipientEmail}
onChange={(e) => {
setRecipientEmail(e.target.value);
}}
/>
</div>
<button
type="submit"
className="proceed-button"
onClick={(e) => handleSubmit(e)}
disabled={!canSubmitForm}
>
Redeem
</button>
</form>

<div>
<br></br>
<span>
If you do not have an Arweave wallet, you can create one in{" "}
<a href={ardriveAppUrl}>ArDrive App</a>.
</span>
</div>
</>
);
}

export const RedeemPage = () => (
<Page page={(e) => <RedeemForm errorCallback={e} />} />
);
19 changes: 19 additions & 0 deletions src/utils/redeemGift.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { paymentServiceUrl } from "../constants";

export async function redeemGift({
destinationAddress,
recipientEmail,
redemptionCode,
}: {
redemptionCode: string;
recipientEmail: string;
destinationAddress: string;
}): Promise<void> {
// TODO: Support redeeming gifts on turbo sdk
// return TurboFactory.unauthenticated(turboConfig)
// .redeemGift(redemptionCode, recipientEmail, destinationAddress)
const response = await fetch(
`${paymentServiceUrl}/v1/redeem/?email=${recipientEmail}&id=${redemptionCode}&destinationAddress=${destinationAddress}`,
);
if (!response.ok) throw new Error("Failed to redeem gift");
}

0 comments on commit 2e6dbe3

Please sign in to comment.