lighting-app/client/src/App.js
2022-06-03 11:13:06 +03:00

206 lines
4.9 KiB
JavaScript

import React, { useState } from 'react';
import './App.css';
var Buffer = require('buffer/').Buffer;
const media = [
{
name: 'Succulent (photo)',
price: 200,
source: '01.png',
invoice: '',
paymentHash: '',
buyButton: false,
checkButton: true,
fileDownloadUrl: '',
},
{
name: 'Melbourne (photo)',
price: 200,
source: '02.png',
invoice: '',
paymentHash: '',
buyButton: false,
checkButton: true,
fileDownloadUrl: '',
},
{
name: 'Madayaka (photo)',
price: 1000,
source: '03.png',
invoice: '',
paymentHash: '',
buyButton: false,
checkButton: true,
fileDownloadUrl: '',
},
];
function Media(props) {
const [mediaList, setMedia] = useState(media);
function generateInvoice(source, price) {
fetch(`/generate-invoice/${source}/${price}`)
.then((res) => res.json())
.then((data) => {
const updateMedia = mediaList.map((m) => {
if (m.source === source) {
const updatedMedia = {
...m,
invoice: data.payment_request,
paymentHash: Buffer.from(data.r_hash).toString('hex'),
buyButton: true,
checkButton: false,
};
return updatedMedia;
}
return m;
});
setMedia(updateMedia);
});
}
function checkInvoice(paymentHash) {
fetch(`/check-invoice/${paymentHash}`)
.then((res) => res.json())
.then((data) => {
if (data.settled === true) {
getContent(data.memo).then((res) => {
const updateMedia = mediaList.map((m) => {
if (m.source === data.memo) {
return {
...m,
invoice: 'THANK YOU',
checkButton: true,
fileDownloadUrl: res,
};
}
return m;
});
setMedia(updateMedia);
});
} else {
alert('Payment not yet received');
}
});
}
async function getContent(source) {
return await fetch(`/file/${source}`)
.then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob));
}
return (
<div>
{mediaList.map((m) => {
return (
<div
key={m.source}
style={{
border: '3px solid gray',
borderRadius: '5px',
margin: '10px',
padding: '10px',
width: '350px',
display: 'inline-block',
height: '550px',
whiteSpace: 'nowrap',
}}
>
<div style={{ margin: 'auto', width: '80%' }}>
<p>{m.name}</p>
<p>Price: {m.price} sats</p>
<img src={'assets/' + m.source} height='220px' alt={m.name} />
<br />
<button
disabled={m.buyButton}
style={{ padding: '10px', margin: '10px' }}
type='button'
onClick={() => {
generateInvoice(m.source, m.price);
}}
>
Buy
</button>
<button
disabled={m.checkButton}
style={{ padding: '10px', margin: '10px' }}
type='button'
onClick={() => {
checkInvoice(m.paymentHash);
}}
>
Check Payment
</button>
<br></br>
<textarea
style={{ resize: 'none' }}
rows='9'
cols='32'
value={m.invoice}
readOnly
></textarea>
<br></br>
<a
style={{
visibility:
!m.checkButton || !m.buyButton ? 'hidden' : 'visible',
}}
href={m.fileDownloadUrl}
rel='noreferrer'
target='_blank'
>
View
</a>
<br></br>
<a
style={{
visibility:
!m.checkButton || !m.buyButton ? 'hidden' : 'visible',
}}
href={m.fileDownloadUrl}
rel='noreferrer'
target='_blank'
download
>
Download
</a>
</div>
</div>
);
})}
</div>
);
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
alias: '',
};
}
componentDidMount() {
const getInfo = async () => {
const response = await fetch('/getinfo');
const { alias } = await response.json();
this.setState({
alias,
});
};
getInfo();
}
render() {
return (
<div>
<p>{this.state.alias}</p>
<Media />
</div>
);
}
}
export default App;