@chakra-ui/react#Spinner JavaScript Examples
The following examples show how to use
@chakra-ui/react#Spinner.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: invite.js From idena-web with MIT License | 6 votes |
export default function DnaInvitePage() {
useDnaInviteRedirect()
return (
<Layout canRedirect={false}>
<Spinner />
</Layout>
)
}
Example #2
Source File: vote.js From idena-web with MIT License | 6 votes |
export default function DnaVotePage() {
useDnaVoteRedirect()
return (
<Layout canRedirect={false}>
<Spinner />
</Layout>
)
}
Example #3
Source File: Messages.jsx From realtime-chat-supabase-react with Apache License 2.0 | 6 votes |
export default function Messages() {
const { username, loadingInitial, error, getMessagesAndSubscribe, messages } =
useAppContext();
const reversed = [...messages].reverse();
if (loadingInitial)
return (
<Box textAlign="center">
<Spinner />
</Box>
);
if (error)
return (
<Alert status="error" mt="20px">
{error}
<Button
ml="5px"
onClick={getMessagesAndSubscribe}
colorScheme="red"
variant="link"
>
try to reconnect
</Button>
</Alert>
);
if (!messages.length)
return (
<Box as="h3" textAlign="center">
No messages ?
</Box>
);
return reversed.map((message) => {
const isYou = message.username === username;
return <Message key={message.id} message={message} isYou={isYou} />;
});
}
Example #4
Source File: signin.js From idena-web with MIT License | 5 votes |
export default function SigninPage() {
const {t} = useTranslation()
const failToast = useFailToast()
const {onOpen, ...dnaSignInDisclosure} = useDisclosure()
const {
params: {
nonce_endpoint: nonceEndpoint,
authentication_endpoint: authenticationEndpoint,
favicon_url: faviconUrl,
...dnaSignInParams
},
} = useDnaLinkMethod(DnaLinkMethod.SignIn, {
onReceive: onOpen,
})
const [, {dismiss: dimissDnaAppLink}] = useDnaAppLink()
return (
<Layout canRedirect={false}>
<Page>
<PageTitle>{t('Sign in with Idena')}</PageTitle>
<Box>
<Spinner />
{Boolean(authenticationEndpoint) && (
<DnaSignInDialog
authenticationEndpoint={authenticationEndpoint}
nonceEndpoint={nonceEndpoint}
faviconUrl={faviconUrl}
{...dnaSignInParams}
{...dnaSignInDisclosure}
onCompleteSignIn={dimissDnaAppLink}
onSignInError={failToast}
/>
)}
</Box>
</Page>
</Layout>
)
}
Example #5
Source File: Loading.js From web-client with Apache License 2.0 | 5 votes |
export default function Loading() {
return <figure className='message__container'>
<Spinner />
Loading...
</figure>
}
Example #6
Source File: InformationCards.js From DAOInsure with MIT License | 4 votes |
function InformationCards({
author,
loadingClaim,
dateOfIncident,
ipfsHash,
yesVotes,
noVotes,
rainData,
memberData,
}) {
const voters = [""];
const [openWeatherStats, setOpenWeatherStats] = useState();
useEffect(() => {
async function init() {
let response = await axios.get(
"https://api.openweathermap.org/data/2.5/onecall/timemachine?lat=32.21&lon=76.32&exclude=minutely,hourly&appid=162ac7d2a16586444f5b2e968f020e4c&dt=1628319601"
);
setOpenWeatherStats(response.data.hourly);
}
init();
}, []);
return (
<VStack spacing={5}>
<Card cardTitle='Information'>
<HStack width='100%'>
<Text fontWeight='600'>Author</Text>
<Spacer />
{loadingClaim ? (
<Skeleton isLoaded={!loadingClaim}>Author</Skeleton>
) : (
<Text>{`${author.substr(0, 7)}...${author.substr(
-7
)}`}</Text>
)}
</HStack>
<HStack width='100%'>
<Text fontWeight='600'>IPFS</Text>
<Spacer />
{loadingClaim ? (
<Skeleton isLoaded={!loadingClaim}>IPFS hash</Skeleton>
) : (
<HStack>
<a
href={`https://ipfs.io/ipfs/` + ipfsHash}
target='_blank'>
<Text>
{" "}
{`${ipfsHash.substr(
0,
7
)}...${ipfsHash.substr(-7)}`}{" "}
</Text>
<FaExternalLinkAlt size='10px' />
</a>
</HStack>
)}
</HStack>
<HStack width='100%'>
<Text fontWeight='600'>Member location</Text>
<Spacer />
{loadingClaim ? (
<Skeleton isLoaded={!loadingClaim}>Author</Skeleton>
) : (
<a
target='_blank'
href={
`https://www.google.co.in/maps/@` +
memberData.lat +
`,` +
memberData.long
}>
Map
</a>
)}
</HStack>
</Card>
<Card cardTitle='Time'>
<VStack width='100%'>
<HStack width='100%'>
<Text fontWeight='600'>Date Of Incident</Text>
<Spacer />
{loadingClaim ? (
<Skeleton isLoaded={!loadingClaim}>
Date Of Incident
</Skeleton>
) : (
<HStack>
<Text>{dateOfIncident}</Text>
</HStack>
)}
</HStack>
</VStack>
</Card>
<ChainlinkCard cardTitle=''>
<VStack width='100%'>
<HStack width='100%'>
<Text fontWeight='600'>Rain data : </Text>
<Text fontWeight='600'>{rainData} mm</Text>
<Spacer />
</HStack>
</VStack>
</ChainlinkCard>
<Card cardTitle='Current Results'>
<VStack width='100%'>
<HStack width='100%'>
<Text fontWeight='600'>Yes</Text>
<Spacer />
{loadingClaim ? (
<Skeleton>vote percent</Skeleton>
) : (
<Text fontWeight='600'>
{(yesVotes / (yesVotes + noVotes)) * 100
? (yesVotes / (yesVotes + noVotes)) * 100
: "0"}
%
</Text>
)}
</HStack>
<Progress
width='100%'
borderRadius='20px'
background='gray.300'
height='10px'
value={
loadingClaim
? 0
: (yesVotes / (yesVotes + noVotes)) * 100
}
colorScheme='green'
size='lg'
/>
<HStack width='100%'>
<Text fontWeight='600'>No</Text>
<Spacer />
{loadingClaim ? (
<Skeleton>vote percent</Skeleton>
) : (
<Text fontWeight='600'>
{(noVotes / (yesVotes + noVotes)) * 100
? (noVotes / (yesVotes + noVotes)) * 100
: "0"}
%
</Text>
)}
</HStack>
<Progress
width='100%'
borderRadius='20px'
background='gray.300'
height='10px'
value={
loadingClaim ? 0 : noVotes / (yesVotes + noVotes)
}
colorScheme='green'
size='lg'
/>
</VStack>
</Card>
<Card cardTitle='OpenWeather Analysis'>
{openWeatherStats ? (
<>
{openWeatherStats.map((stat) => {
return (
<HStack width='100%'>
<Text>
{new Date(parseInt(stat.dt) * 1000)
.toTimeString()
.substr(0, 5)}
</Text>
<Text>
{stat.weather[0].description[0].toUpperCase() +
stat.weather[0].description.substr(
1
)}
</Text>
<Spacer />
<Image
src={`http://openweathermap.org/img/wn/${stat.weather[0].icon}.png`}
/>
</HStack>
);
})}
</>
) : (
<Spinner margin='auto' />
)}
</Card>
<Card cardTitle='Votes'>
<VStack width='100%' alignItems='flex-start'>
{loadingClaim ? (
<HStack justifyContent='space-between' width='100%'>
<HStack>
<SkeletonCircle />
<Skeleton>Address that voted</Skeleton>
</HStack>
<Skeleton>Vote</Skeleton>
<Skeleton>Voting Power</Skeleton>
</HStack>
) : (
<>
{voters.map((voter) => {
return (
<HStack
justifyContent='space-between'
width='100%'
key={0}>
<HStack>
<Avatar
size='xs'
icon={
<Jazzicon
diameter='24'
address='0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69'
/>
}
/>
<Tag>{`${"0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69".substr(
0,
6
)}...${"0x8Cf24E66d1DC40345B1bf97219856C8140Ce6c69".substr(
-5
)}`}</Tag>
</HStack>
<Tag colorScheme='whatsapp'>Yes</Tag>
<Text>300 DIx</Text>
</HStack>
);
})}
</>
)}
</VStack>
</Card>
</VStack>
);
}
Example #7
Source File: ActivityPage.js From DAOInsure with MIT License | 4 votes |
function ActivityPage() {
const [data, setData] = useState();
const [loadingData, setLoadingData] = useState();
useEffect(() => {
async function init() {
setLoadingData(true);
// querying superfluid subgraph to create pie diagram of flow towards DAO Contract
const response = await axios.post(
"https://api.thegraph.com/subgraphs/name/superfluid-finance/superfluid-mumbai",
{
query: `
{
flows(where:{ recipient: "0xb77963bfd55f5246068c09a2048fa3ab310e4a17" }) {
id
flowRate
lastUpdate
owner {
id
}
}
}
`,
}
);
let datas = [];
response.data.data.flows.map((flow) => {
let secondsElapsed =
Math.floor(Date.now() / 1000) - parseInt(flow.lastUpdate);
let outFlowed = web3.utils.fromWei(
web3.utils
.toBN(flow.flowRate)
.mul(web3.utils.toBN(secondsElapsed))
.toString(),
"ether"
);
let obj = {
id: flow.owner.id,
label: flow.owner.id,
value: outFlowed,
flowRate: web3.utils.toBN(flow.flowRate),
sumInWei: web3.utils
.toBN(flow.flowRate)
.mul(web3.utils.toBN(secondsElapsed)),
};
datas.push(obj);
});
setData(datas);
setLoadingData(false);
}
init();
}, [data]);
useEffect(() => {
if (data != undefined) {
setTimeout(() => {
for (let i = 0; i < data.length; i++) {
data[i].value = web3.utils
.fromWei(data[i].sumInWei.add(data[i].flowRate))
.toString();
data[i].sumInWei = data[i].sumInWei.add(data[i].flowRate);
}
setData(data);
}, 1000);
}
}, [data]);
return (
<Grid px='250px' gridGap='10px' py='20px'>
<Heading fontSize='24px' color='whatsapp.500'>
Members
</Heading>
<Box height='400px'>
{loadingData ? <Spinner /> : <MyResponsivePie data={data} />}
</Box>
<Table>
<Thead>
<Tr>
<Th>Address</Th>
<Th>outFlowed</Th>
</Tr>
</Thead>
<Tbody>
{data == undefined ? (
<Spinner />
) : (
<>
{data.map((data, index) => {
return (
<Tr>
<Td>
<GreenTag>{data.id}</GreenTag>
</Td>
<Td>{data.value}</Td>
</Tr>
);
})}
</>
)}
</Tbody>
</Table>
</Grid>
);
}
Example #8
Source File: MakeClaim.js From DAOInsure with MIT License | 4 votes |
function MakeClaim() {
const [currentImage, setCurrentImage] = useState(undefined);
const [images, setImages] = useState([]);
const [isPageLoading, setIsPageLoading] = useState(false);
const { textileClient } = useContext(AppContext);
const [claimTitle, setClaimTitle] = useState();
const [claimSummary, setClaimSummary] = useState();
const [dateOfIncident, setDateOfIncident] = useState();
const [startTime, setStartTime] = useState();
const web3Context = useContext(Web3Context);
const {
createProposal,
signerAddress,
claimableAmount,
getClaimableAmount,
} = web3Context;
useEffect(() => {
getClaimableAmount();
}, []);
const handleImage = async (e) => {
console.log("uploading");
let file = e.target.files[0];
try {
let result = await uploadToSlate(file);
setImages([
...images,
{
isUploading: false,
url: `https://slate.textile.io/ipfs/${result.data.cid}`,
},
]);
setCurrentImage(`https://slate.textile.io/ipfs/${result.data.cid}`);
console.log("uploaded");
} catch (e) {
console.log(e);
}
};
const handleCurrentImage = (e) => {
e.preventDefault();
setCurrentImage(e.target.src);
};
const handleInputChange = (e, setter) => {
e.preventDefault();
setter(e.target.value);
};
const handleClaimSubmit = async (e) => {
e.preventDefault();
let imageUrls = images.map((image) => {
return image.url;
});
let claimObj = {
images: imageUrls,
claimTitle,
claimSummary,
dateOfIncident,
claimAmount: claimableAmount,
author: signerAddress,
};
console.log(claimObj);
// tried using fleek instead of threadDB.
// let response = await fleekStorage.upload({
// apiKey: "3aFyv9UlnpyVvuhdoy+WMA==",
// apiSecret: "vUREhYRSH5DP8WehKP+N8jTLoOJUBw+RA9TPLUKneK8=",
// key: uuidv4(),
// data: JSON.stringify(claimObj),
// });
// adding claim data to threadDB.
let response = await addToThread(
textileClient,
"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q",
"claimsData",
claimObj
);
// create proposal on contract basically store the hash.
createProposal(
claimTitle,
(new Date(dateOfIncident).getTime() / 1000).toString(),
response.hash
);
};
return (
<Grid
paddingBottom='20px'
pt='20px'
height='100%'
px='250px'
width='100%'
templateColumns='2fr 1fr'
gridGap={5}
alignItems='flex-start'>
<VStack width='100%' alignItems='flex-start'>
<Skeleton isLoaded={!isPageLoading}>
<Heading as='h4' fontSize='28px'>
Make a Claim
</Heading>
</Skeleton>
<form style={{ width: "100%" }}>
<VStack width='100%' spacing={5} alignItems='flex-start'>
<input
multiple
onChange={(e) => handleImage(e)}
type='file'
style={{ display: "none" }}
id='image-input'
accept='image/*'
/>
{images.length == 0 ? (
isPageLoading ? (
<Spinner
colorScheme='whatsapp'
color='whatsapp.500'
alignSelf='center'
/>
) : (
<Box
cursor='pointer'
as='label'
htmlFor='image-input'
px='35px'
width='100%'
borderRadius='10px'
height='70px'
borderWidth='1px'
borderStyle='solid'
borderColor='whatsapp.500'>
<VStack
height='100%'
width='100%'
justifyContent='center'>
<TiPlus style={{ fill: "#22C35E" }} />
<Text fontWeight='600' color='#22C35E'>
Image
</Text>
</VStack>
</Box>
)
) : (
<>
<Box
mt='10px !important'
boxShadow='lg'
borderRadius='10px'>
<Image
borderRadius='10px'
src={currentImage}
/>
</Box>
<HStack width='100%' overflowX='scroll'>
{images.map((image, index) => {
return image.isUploading ? (
<Spinner key={index} />
) : (
<Image
key={image.url}
onClick={(e) => {
handleCurrentImage(e);
}}
borderRadius='10px'
height='70px'
src={image.url}
/>
);
})}
<Box
cursor='pointer'
as='label'
htmlFor='image-input'
px='35px'
borderRadius='10px'
height='70px'
borderWidth='1px'
borderStyle='solid'
borderColor='whatsapp.500'>
<VStack
height='100%'
width='100%'
justifyContent='center'>
<TiPlus
style={{ fill: "#22C35E" }}
/>
<Text
fontWeight='600'
color='#22C35E'>
Image
</Text>
</VStack>
</Box>
</HStack>
</>
)}
<VStack spacing={5} width='100%'>
<FormControl isRequired>
<Skeleton isLoaded={!isPageLoading}>
<FormLabel>Claim Title</FormLabel>
</Skeleton>
<Skeleton isLoaded={!isPageLoading}>
<Input
onChange={(e) =>
handleInputChange(e, setClaimTitle)
}
/>
</Skeleton>
</FormControl>
<FormControl isRequired>
<Skeleton isLoaded={!isPageLoading}>
<FormLabel>Summary of Incident</FormLabel>
</Skeleton>
<Skeleton isLoaded={!isPageLoading}>
<Textarea
onChange={(e) =>
handleInputChange(
e,
setClaimSummary
)
}
row='10'
/>
</Skeleton>
<Skeleton isLoaded={!isPageLoading}>
<FormHelperText>
Try to precise
</FormHelperText>
</Skeleton>
</FormControl>
<VStack width='100%'>
<HStack width='100%'>
<FormControl isRequired>
<Skeleton isLoaded={!isPageLoading}>
<FormLabel>
Date of Incident
</FormLabel>
</Skeleton>
<Skeleton isLoaded={!isPageLoading}>
<Input
onChange={(e) =>
handleInputChange(
e,
setDateOfIncident
)
}
type='date'
/>
</Skeleton>
</FormControl>
</HStack>
</VStack>
<Button
onClick={(e) => handleClaimSubmit(e)}
isLoading={isPageLoading}
mt='30px !important'
width='100%'
textTransform='uppercase'
type='submit'
colorScheme='whatsapp'>
Submit Claim
</Button>
</VStack>
</VStack>
</form>
</VStack>
<VStack width='100%'>
<Card isLoading={isPageLoading} cardTitle='Claimable Amount'>
<Skeleton isLoaded={!isPageLoading}>
<Heading
textColor='whatsapp.500'
fontSize='24px'
as='h3'>
{parseFloat(claimableAmount).toFixed(6)} DAI
</Heading>
</Skeleton>
</Card>
</VStack>
</Grid>
);
}
Example #9
Source File: VotingPage.js From DAOInsure with MIT License | 4 votes |
function VotingPage(props) {
const { textileClient } = useContext(AppContext);
const [state, dispatch] = useReducer(stateReducer, {
currentImage: "",
sendImage: "",
message: "",
messages: [],
claim: "",
loadingClaim: true,
vote: 0,
});
const { id } = useParams();
const {
allProposalsArray,
fetchAllProposals,
voteOnProposal,
signerAddress,
claimProposal,
fetchMemberInfo,
memberData,
} = useContext(Web3Context);
const { getRootProps, getRadioProps } = useRadioGroup({
name: "Vote",
defaultValue: "No",
onChange: (e) => handleRadioChange(e),
});
useEffect(() => {
async function init() {
const proposalId = allProposalsArray[id][9];
const myFile = await queryThread(
textileClient,
"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q",
"claimsData",
{ claimId: proposalId }
);
// const myFile = await fleekStorage.getFileFromHash({
// hash: proposalId,
// });
dispatch({ type: ACTIONS.SET_CLAIM, payload: myFile });
dispatch({ type: ACTIONS.SET_LOADING_CLAIM, payload: false });
// messages from the chat feature are stored in textile. A single collection of all message but can be distinguished using claimId.
let messages = await queryThread(
textileClient,
"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q",
"messagesData",
{ claimId: id }
);
dispatch({ type: ACTIONS.SET_MESSAGES, payload: messages });
console.log("listening");
// listener for new messages that are added to the collection.
let closer = await textileClient.listen(
ThreadID.fromString(
"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q"
),
[{ actionTypes: ["CREATE"], collectionName: "messagesData" }],
(reply, error) => {
dispatch({
type: ACTIONS.SET_MESSAGES,
payload: [reply.instance],
});
}
);
// close listener
return function cleanup() {
closer();
};
}
if (textileClient) {
init();
}
}, [textileClient]);
useEffect(() => {
fetchMemberInfo();
}, []);
const options = ["Yes", "No"];
const group = getRootProps();
const handleImage = ({ target }) => {
dispatch({ type: ACTIONS.SET_CURR_IMAGE, payload: target.src });
};
const handleRadioChange = (e) => {
if (e == "Yes") {
dispatch({ type: ACTIONS.SET_VOTE, payload: 1 });
} else {
dispatch({ type: ACTIONS.SET_VOTE, payload: 0 });
}
};
const handleMessage = ({ target }) => {
dispatch({ type: ACTIONS.SET_MESSAGE, payload: target.value });
};
const handleSendImageChange = ({ target }) => {
dispatch({ type: ACTIONS.SET_SEND_IMAGE, payload: target.files[0] });
};
const handleSendMessage = async () => {
let uploadedImage = "";
// upload image if any in message to slate.
if (state.sendImage) {
let result = await uploadToSlate(state.sendImage);
uploadedImage = `https://slate.textile.io/ipfs/${result.data.cid}`;
}
let messageObj = {
message: state.message,
image: uploadedImage,
address: signerAddress,
claimId: id,
};
let resultFromTextile = await addToThread(
textileClient,
"bafkyspsyykcninhqn4ht6d6jeqmzq4cepy344akmkhjk75dmw36wq4q",
"messagesData",
messageObj
);
dispatch({ type: ACTIONS.SET_MESSAGE, payload: "" });
dispatch({ type: ACTIONS.SET_SEND_IMAGE, payload: "" });
};
return (
<Grid
px='250px'
py='20px'
width='100%'
templateColumns='3fr 2fr'
gridGap={5}
alignItems='flex-start'>
<VStack alignItems='flex-start' width='100%'>
{state.loadingClaim ? (
<>
<HStack width='100%' justifyContent='space-between'>
<Skeleton isLoaded={!state.loadingClaim}>
Loading Claim
</Skeleton>
<Skeleton isLoaded={!state.loadingClaim}>
Claim Status
</Skeleton>
</HStack>
<Skeleton width='100%'>
<Box height='300px' width='100%'>
Image
</Box>
</Skeleton>
</>
) : (
<>
<HStack width='100%' justifyContent='space-between'>
<Heading fontSize='24px'>
{state.claim.claimTitle}
</Heading>
<Tag>Open</Tag>
</HStack>
{state.claim.images.length == 0 ? null : (
<>
<Box
mt='10px !important'
boxShadow='lg'
borderRadius='10px'>
<Image
borderRadius='10px'
src={state.currentImage}
/>
</Box>
<HStack>
{state.claim.images.map((image) => {
return (
<Image
onClick={handleImage}
borderRadius='10px'
height='70px'
src={image}
/>
);
})}
</HStack>
</>
)}
<Text>{state.claim.claimSummary}</Text>
</>
)}
{signerAddress == allProposalsArray[id][1] ? (
<Box
_hover={{ boxShadow: "base", transform: "scale(1.01)" }}
transition='all .3s'
textColor='white'
fontWeight='600'
width='30%'
backgroundColor='whatsapp.500'
borderRadius='20px'
textAlign='center'
py={2}
borderColor='whatsapp.500'
colorScheme='whatsapp'
onClick={() => claimProposal(id)}>
Claim
</Box>
) : (
<span> </span>
)}
<Card cardTitle='Cast Your Vote'>
{state.loadingClaim ? (
<Spinner margin='auto' borderColor='whatsapp.500' />
) : (
<>
<VStack width='100%' {...group}>
{options.map((value) => {
const radio = getRadioProps({ value });
return (
<RadioCard key={value} {...radio}>
{value}
</RadioCard>
);
})}
</VStack>
<Box
_hover={{
boxShadow: "base",
transform: "scale(1.01)",
}}
transition='all .3s'
textColor='white'
fontWeight='600'
width='100%'
backgroundColor='whatsapp.500'
borderRadius='20px'
textAlign='center'
py={2}
borderColor='whatsapp.500'
colorScheme='whatsapp'
onClick={() => voteOnProposal(id, state.vote)}>
Vote
</Box>
</>
)}
</Card>
<Card cardTitle='Chat'>
{state.loadingClaim ? (
<Spinner borderColor='whatsapp.500' margin='auto' />
) : (
<VStack
height='400px'
spacing={5}
justifyContent='flex-end'
width='100%'
alignItems='flex-start'>
<VStack
alignItems='flex-start'
overflowY='scroll'
width='100%'>
{state.messages.map((message) => {
return (
<HStack
key={message._id}
alignItems='flex-end'>
<Tooltip
placement='top'
hasArrow
label={`${message.address.substr(
0,
6
)}...${message.address.substr(
-4
)}`}>
<Box
borderWidth='2px'
padding='2px'
borderColor='whatsapp.500'
borderStyle='solid'
borderRadius='full'>
<Avatar
size='sm'
icon={
<Jazzicon
diameter='32'
address={
message.address
}
/>
}
/>
</Box>
</Tooltip>
<VStack
alignItems='flex-start'
backgroundColor='whatsapp.500'
color='white'
borderWidth='1px'
borderRadius='10px'
borderColor='whatsapp.500'
padding={3}>
{message.image.length > 0 ? (
<Image
borderRadius='10px'
height='200px'
src={message.image}
/>
) : null}
<Text>{message.message}</Text>
</VStack>
</HStack>
);
})}
</VStack>
<HStack>
{state.sendImage ? (
<HStack
borderColor='whatsapp.500'
borderWidth='1px'
padding={2}
borderRadius='10px'
key={state.sendImage.name}>
<MdImage />
<Text>{state.sendImage.name}</Text>
</HStack>
) : null}
</HStack>
<HStack width='100%'>
<InputGroup>
<Input
value={state.message}
onChange={handleMessage}
borderRadius='20px'
focusBorderColor='whatsapp.500'
/>
<InputRightElement>
<IconButton
cursor='pointer'
as='label'
htmlFor='image-input'
colorScheme='whatsapp'
icon={<ImAttachment />}
/>
<input
onChange={(e) =>
handleSendImageChange(e)
}
type='file'
id='image-input'
style={{ display: "none" }}
/>
</InputRightElement>
</InputGroup>
<Button
onClick={handleSendMessage}
colorScheme='whatsapp'>
Send
</Button>
</HStack>
</VStack>
)}
</Card>
</VStack>
{state.loadingClaim ? (
<InformationCards loadingClaim={state.loadingClaim} />
) : (
<InformationCards
author={state.claim.author}
// startDate={state.claim.startTime}
dateOfIncident={state.claim.dateOfIncident}
ipfsHash={allProposalsArray[id].ipfsHash}
yesVotes={allProposalsArray[id].yesVotes}
noVotes={allProposalsArray[id].noVotes}
rainData={allProposalsArray[id].rainData.toNumber()}
memberData={memberData}
/>
)}
</Grid>
);
}
Example #10
Source File: Player.jsx From bottle-radio with MIT License | 4 votes |
Player = () => {
const variables = window._env_ ? window._env_ : { REACT_ICECAST_URL: "" };
const [playing, setPlaying] = useState(false);
const [loading, setLoading] = useState(false);
const [muted, setMuted] = useState(false);
const [firstLoad, setFirstLoad] = useState(true);
const [nowPlaying, setNowPlaying] = useState(["No data", "No data"]);
const [listeners, setListeners] = useState([0, 0]);
const { colorMode } = useColorMode();
const colorHover = { light: "white", dark: "black" };
const { isOpen, onOpen, onClose } = useDisclosure();
const trackLinks = useSaveTrack(
nowPlaying[0],
nowPlaying[1]
);
const audioRef = useRef(null);
const { setPlayer } = useContext(VisualiserContext);
useEffect(() => {
const audio = document.getElementById("player");
if (audio) {
setPlayer(audioRef);
}
}, [setPlayer]);
useEffect(() => {
const updateStats = async () => {
let url = variables.REACT_ICECAST_URL + "status-json.xsl";
let response = await fetch(url);
let json = await response.json();
let track = json.icestats.source.title;
if (track && track !== "") {
let artist = track.split(" - ")[0];
track = track.split(" - ").slice(1).join(" - ");
setNowPlaying([track, artist]);
}
let listeners = json.icestats.source.listeners;
let peakListeners = json.icestats.source.listener_peak;
if (listeners && listeners) {
setListeners([listeners, peakListeners]);
}
};
updateStats();
setInterval(() => {
updateStats();
}, 10000);
}, [variables.REACT_ICECAST_URL]);
const togglePlay = () => {
let player = document.getElementById("player");
if (firstLoad) {
setFirstLoad(false);
}
if (player.paused) {
setPlaying(true);
player.load();
player.play();
} else {
setPlaying(false);
player.pause();
}
};
const changeVolume = (value) => {
let player = document.getElementById("player");
value <= 0 ? setMuted(true) : setMuted(false);
player.volume = value / 100;
};
const TrackModal = (props) => {
const { modal, setModal } = useContext(ModalContext);
useEffect(() => {
if (!modal) {
setModal(trackLinks);
}
}, [modal, setModal]);
return (
<div>
<Modal
isOpen={isOpen}
onClose={() => {
onClose();
setModal();
}}
size="sm"
isCentered
>
<ModalOverlay>
<ModalContent>
<ModalCloseButton />
<ModalBody>
<Grid templateColumns="1fr 1fr" justifyItems="center" gap={0}>
{modal && modal.length > 0 ? (
modal.map((link) => (
<Link key={link.url} href={link.url} isExternal>
<Button variant="ghost">{link.displayName}</Button>
</Link>
))
) : (
<div>
<Spinner size="sm" /> Loading...
</div>
)}
</Grid>
</ModalBody>
</ModalContent>
</ModalOverlay>
</Modal>
</div>
);
};
return (
<div>
<Flex
direction="column"
justify="center"
align="center"
width="100%"
height="100%"
>
<Box>
<Grid
m={2}
p={2}
templateColumns="auto 1fr auto"
alignItems="center"
gap={1}
>
<Box
gridRow="1/4"
w="80px"
h="80px"
aria-label="Play toggle"
as={loading ? FaSpinner : playing ? FaPauseCircle : FaPlayCircle}
onClick={togglePlay}
_hover={{ color: colorHover[colorMode] }}
mr={1}
className={loading ? "icon-spin" : ""}
/>
<Text m={0} align="center">
<strong>{nowPlaying[0]}</strong>
</Text>
<Text m={0} align="center">
{nowPlaying[1]}
</Text>
<Flex direction="row" justify="center" maxWidth={400} p={2}>
<Slider
defaultValue={100}
min={0}
max={100}
step={10}
onChange={changeVolume}
width="80px"
>
<SliderTrack>
<SliderFilledTrack bg="tomato" />
</SliderTrack>
<SliderThumb size={2} />
</Slider>
<Box
w="20px"
h="20px"
as={muted ? FaVolumeMute : FaVolumeUp}
ml={3}
/>
<audio
id="player"
crossOrigin="anonymous"
autoPlay
preload="none"
ref={audioRef}
onPlay={() => setPlaying(true)}
onPause={() => setPlaying(false)}
onLoadStart={() => {
if (!firstLoad) {
setLoading(true);
}
}}
onCanPlay={() => setLoading(false)}
>
<source
src={variables.REACT_ICECAST_URL + "radio.mp3"}
type="audio/mp3"
/>
Your browser does not support the audio element.
</audio>
</Flex>
<Text gridColumn="1/4">
<strong>Listeners: </strong>
{listeners[0]} <strong>Peak: </strong>
{listeners[1]}
</Text>
<Box gridColumn="3" gridRow="1/4" alignItems="center">
<Box
w="25px"
h="25px"
as={FaHeart}
mx={1}
onClick={onOpen}
_hover={{ color: "tomato" }}
/>
{isOpen ? <TrackModal /> : null}
</Box>
</Grid>
</Box>
</Flex>
</div>
);
}
Example #11
Source File: raw.js From idena-web with MIT License | 4 votes |
export default function DnaRawPage() {
const {t} = useTranslation()
const failToast = useFailToast()
const handleInvalidDnaLink = React.useCallback(() => {
failToast({
title: t('Invalid DNA link'),
description: t(`You must provide valid URL including protocol version`),
})
}, [failToast, t])
const dnaRawTxDisclosure = useDisclosure()
const {params: dnaRawTxParams} = useDnaLinkMethod(DnaLinkMethod.RawTx, {
onReceive: dnaRawTxDisclosure.onOpen,
onInvalidLink: handleInvalidDnaLink,
})
const dnaSendSucceededDisclosure = useDisclosure()
const dnaSendFailedDisclosure = useDisclosure()
const [dnaSendResponse, setDnaSendResponse] = React.useState()
const {coinbase} = useAuthState()
const {
data: {balance},
} = useQuery(['get-balance', coinbase], () => fetchBalance(coinbase), {
initialData: {balance: 0},
enabled: !!coinbase,
})
const [, {dismiss: dismissDnaAppLink}] = useDnaAppLink()
return (
<Layout canRedirect={false}>
<Page>
<PageTitle>{t('Send raw transaction')}</PageTitle>
<Box>
<Spinner />
<DnaRawDialog
balance={balance}
{...dnaRawTxParams}
{...dnaRawTxDisclosure}
onSendSuccess={({hash, url}) => {
dnaRawTxDisclosure.onClose()
setDnaSendResponse({hash, url})
dnaSendSucceededDisclosure.onOpen()
}}
onSendError={({error, url}) => {
dnaRawTxDisclosure.onClose()
setDnaSendResponse({error, url})
dnaSendFailedDisclosure.onOpen()
}}
onSendRawTxFailed={failToast}
onCompleteSend={dismissDnaAppLink}
/>
<DnaSendSucceededDialog
{...dnaSendResponse}
{...dnaSendSucceededDisclosure}
onCompleteSend={() => {
dismissDnaAppLink()
dnaSendSucceededDisclosure.onClose()
}}
/>
<DnaSendFailedDialog
onRetrySucceeded={({hash, url}) => {
setDnaSendResponse({hash, url})
dnaSendFailedDisclosure.onClose()
dnaSendSucceededDisclosure.onOpen()
}}
onRetryFailed={({error, url}) => {
setDnaSendResponse({error, url})
}}
{...dnaSendResponse}
{...dnaSendFailedDisclosure}
onOpenFailUrl={() => {
dismissDnaAppLink()
dnaSendFailedDisclosure.onClose()
}}
/>
</Box>
</Page>
</Layout>
)
}
Example #12
Source File: send.js From idena-web with MIT License | 4 votes |
export default function DnaSendPage() {
const {t} = useTranslation()
const failToast = useFailToast()
const handleInvalidDnaLink = React.useCallback(() => {
failToast({
title: t('Invalid DNA link'),
description: t(`You must provide valid URL including protocol version`),
})
}, [failToast, t])
const dnaSendDisclosure = useDisclosure()
const {params: dnaSendParams} = useDnaLinkMethod(DnaLinkMethod.Send, {
onReceive: dnaSendDisclosure.onOpen,
onInvalidLink: handleInvalidDnaLink,
})
const dnaSendSucceededDisclosure = useDisclosure()
const dnaSendFailedDisclosure = useDisclosure()
const [dnaSendResponse, setDnaSendResponse] = React.useState()
const {coinbase} = useAuthState()
const {
data: {balance},
} = useQuery(['get-balance', coinbase], () => fetchBalance(coinbase), {
initialData: {balance: 0},
enabled: !!coinbase,
})
const [, {dismiss: dismissDnaAppLink}] = useDnaAppLink()
return (
<Layout canRedirect={false}>
<Page>
<PageTitle>{t('Send iDNA')}</PageTitle>
<Box>
<Spinner />
<DnaSendDialog
balance={balance}
{...dnaSendParams}
{...dnaSendDisclosure}
onDepositSuccess={({hash, url}) => {
dnaSendDisclosure.onClose()
setDnaSendResponse({hash, url})
dnaSendSucceededDisclosure.onOpen()
}}
onDepositError={({error, url}) => {
dnaSendDisclosure.onClose()
setDnaSendResponse({error, url})
dnaSendFailedDisclosure.onOpen()
}}
onSendTxFailed={failToast}
onCompleteSend={dismissDnaAppLink}
/>
<DnaSendSucceededDialog
{...dnaSendResponse}
{...dnaSendSucceededDisclosure}
onCompleteSend={() => {
dismissDnaAppLink()
dnaSendSucceededDisclosure.onClose()
}}
/>
<DnaSendFailedDialog
onRetrySucceeded={({hash, url}) => {
setDnaSendResponse({hash, url})
dnaSendFailedDisclosure.onClose()
dnaSendSucceededDisclosure.onOpen()
}}
onRetryFailed={({error, url}) => {
setDnaSendResponse({error, url})
}}
{...dnaSendResponse}
{...dnaSendFailedDisclosure}
onOpenFailUrl={() => {
dismissDnaAppLink()
dnaSendFailedDisclosure.onClose()
}}
/>
</Box>
</Page>
</Layout>
)
}
Example #13
Source File: image-search.js From idena-web with MIT License | 4 votes |
export function ImageSearchDialog({onPick, onClose, onError, ...props}) {
const {t} = useTranslation()
const searchInputRef = React.useRef()
const [current, send] = useMachine(
Machine({
context: {
images: [],
},
initial: 'idle',
states: {
idle: {},
searching: {
invoke: {
// eslint-disable-next-line no-shadow
src: (_, {query}) => searchImages(query),
onDone: {
target: 'done',
actions: [
assign({
images: (_, {data}) => data,
}),
log(),
],
},
onError: 'fail',
},
},
done: {
on: {
PICK: {
actions: [
assign({
selectedImage: (_, {image}) => image,
}),
log(),
],
},
},
},
fail: {
entry: [(_, {data: {message}}) => onError(message), log()],
},
},
on: {
SEARCH: 'searching',
},
})
)
const {images, selectedImage} = current.context
const [query, setQuery] = useState()
return (
<Dialog
size="lg"
initialFocusRef={searchInputRef}
onClose={onClose}
{...props}
>
<DialogBody d="flex">
<Stack minH="sm" maxH="sm" spacing={4} flex={1}>
<Stack
isInline
as="form"
onSubmit={e => {
e.preventDefault()
send('SEARCH', {query})
}}
>
<InputGroup w="full">
<InputLeftElement w={5} h={5} top={1.5} left={3}>
<SearchIcon boxSize={3} color="gray.200" />
</InputLeftElement>
<Input
ref={searchInputRef}
type="search"
id="query"
placeholder={t('Search the picture on the web')}
bg="gray.50"
pl={10}
value={query}
onChange={e => setQuery(e.target.value)}
/>
</InputGroup>
<PrimaryButton type="submit">Search</PrimaryButton>
</Stack>
{eitherState(current, 'idle') && (
<Flex direction="column" flex={1} align="center" justify="center">
<Stack spacing={4} align="center" w="3xs">
<Box p={3}>
<SearchIcon boxSize="56px" color="gray.100" />
</Box>
<Text color="muted" textAlign="center" w="full">
{t(
'Type your search in the box above to find images using search box'
)}
</Text>
</Stack>
</Flex>
)}
{eitherState(current, 'done') && (
<SimpleGrid
columns={4}
spacing={2}
overflow="auto"
px={6}
style={{marginLeft: '-24px', marginRight: '-24px'}}
>
{images.map(({thumbnail}) => (
<AspectRatio
ratio={1}
w={28}
minH={28}
bg={thumbnail === selectedImage ? 'blue.032' : 'white'}
borderColor={
thumbnail === selectedImage ? 'blue.500' : 'gray.50'
}
borderWidth={1}
borderRadius="md"
overflow="hidden"
position="relative"
transition="all 0.6s cubic-bezier(0.16, 1, 0.3, 1)"
onClick={() => {
send('PICK', {image: thumbnail})
}}
onDoubleClick={() => {
onPick(selectedImage)
}}
>
<Image
src={thumbnail}
objectFit="contain"
objectPosition="center"
borderColor={
thumbnail === selectedImage ? 'blue.500' : 'transparent'
}
borderWidth={1}
borderRadius="md"
/>
</AspectRatio>
))}
</SimpleGrid>
)}
{eitherState(current, 'searching') && (
<Flex direction="column" flex={1} align="center" justify="center">
<Spinner color="blue.500" />
</Flex>
)}
</Stack>
</DialogBody>
<DialogFooter>
<SecondaryButton onClick={onClose}>{t('Cancel')}</SecondaryButton>
<PrimaryButton
onClick={() => {
onPick(selectedImage)
}}
>
{t('Select')}
</PrimaryButton>
</DialogFooter>
</Dialog>
)
}
Example #14
Source File: Blob.js From blobs.app with MIT License | 4 votes |
Blob = ({
size,
isOutline,
type,
svgPath,
color,
colors,
image,
pattern,
}) => {
const ref = useRef(null);
const [imgLoaded, setImgLoaded] = useState(false);
const pattenBgColor = useColorModeValue('#d1d8e0', '#6c7c93');
const props = {
fill: color,
};
if (type === 'gradient') {
props.fill = 'url(#gradient)';
}
if (isOutline) {
props.strokeWidth = '7px';
props.fill = 'none';
props.stroke = color;
}
if (type === 'gradient' && isOutline) {
props.stroke = 'url(#gradient)';
}
if (!svgPath) {
return (
<Flex justify="center" alignItems="center" h="100%">
<Spinner />
</Flex>
);
}
return (
<svg
viewBox={`0 0 ${size} ${size}`}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
width="100%"
id="blobSvg"
ref={ref}
>
{type === 'solid' && <path id="blob" d={svgPath} {...props} />}
{type === 'gradient' && (
<>
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style={{ stopColor: colors[0] }} />
<stop offset="100%" style={{ stopColor: colors[1] }} />
</linearGradient>
</defs>
<path id="blob" d={svgPath} {...props} />
</>
)}
{type === 'pattern' && (
<>
<defs>
<pattern
id="pattern"
x="0"
y="0"
width={Patterns[pattern].width}
height={Patterns[pattern].height}
patternUnits="userSpaceOnUse"
fill={pattenBgColor}
>
<path d={Patterns[pattern].path} />
</pattern>
</defs>
<path id="blob" d={svgPath} {...props} fill="url(#pattern)" />
</>
)}
{type === 'image' && (
<>
<defs>
<clipPath id="shape">
<path id="blob" d={svgPath} {...props} />
</clipPath>
</defs>
{!imgLoaded && (
<image
x="0"
y="0"
width="100%"
height="100%"
clipPath="url(#shape)"
xlinkHref={LoadingImg}
preserveAspectRatio="none"
/>
)}
<image
x="0"
y="0"
width="100%"
height="100%"
clipPath="url(#shape)"
xlinkHref={image}
preserveAspectRatio="none"
onLoad={() => {
setImgLoaded(true);
}}
/>
</>
)}
</svg>
);
}
Example #15
Source File: Account.jsx From scaffold-directory with MIT License | 4 votes |
/*
~ What it does? ~
Displays an Address, Balance, and Wallet as one Account component,
also allows users to log in to existing accounts and log out
~ How can I use? ~
<Account
address={address}
localProvider={localProvider}
userProvider={userProvider}
mainnetProvider={mainnetProvider}
price={price}
web3Modal={web3Modal}
loadWeb3Modal={loadWeb3Modal}
logoutOfWeb3Modal={logoutOfWeb3Modal}
blockExplorer={blockExplorer}
/>
~ Features ~
- Provide address={address} and get balance corresponding to the given address
- Provide localProvider={localProvider} to access balance on local network
- Provide userProvider={userProvider} to display a wallet
- Provide mainnetProvider={mainnetProvider} and your address will be replaced by ENS name
(ex. "0xa870" => "user.eth")
- Provide price={price} of ether and get your balance converted to dollars
- Provide web3Modal={web3Modal}, loadWeb3Modal={loadWeb3Modal}, logoutOfWeb3Modal={logoutOfWeb3Modal}
to be able to log in/log out to/from existing accounts
- Provide blockExplorer={blockExplorer}, click on address and get the link
(ex. by default "https://etherscan.io/" or for xdai "https://blockscout.com/poa/xdai/")
*/
export default function Account({
address,
connectText,
ensProvider,
isWalletConnected,
loadWeb3Modal,
logoutOfWeb3Modal,
setUserRole,
userProvider,
userRole,
}) {
const ens = useDisplayAddress(ensProvider, address);
const shortAddress = ellipsizedAddress(address);
const toast = useToast({ position: "top", isClosable: true });
const [isPopoverOpen, setIsPopoverOpen] = useState(true);
const registerButtonRef = useRef();
const openPopover = () => setIsPopoverOpen(true);
const closePopover = () => setIsPopoverOpen(false);
const { primaryFontColor, secondaryFontColor, dividerColor } = useCustomColorModes();
if (!userRole && isWalletConnected) {
return <Spinner />;
}
const hasEns = ens !== shortAddress;
const isAdmin = userRole === USER_ROLES.admin;
const isBuilder = userRole === USER_ROLES.builder;
const isAnonymous = userRole === USER_ROLES.anonymous;
const connectWallet = (
<Button colorScheme="blue" key="loginbutton" onClick={loadWeb3Modal}>
{connectText || "connect"}
</Button>
);
const UserDisplayName = ({ mb, textAlign }) =>
hasEns ? (
<>
<Text fontSize="md" fontWeight="bold" textAlign={textAlign} color={primaryFontColor}>
{ens}
</Text>
<Text color={secondaryFontColor} fontSize="sm" fontWeight="normal" textAlign={textAlign} mb={mb}>
{shortAddress}
</Text>
</>
) : (
<Text fontSize="md" fontWeight="semibold" textAlign={textAlign} color={primaryFontColor} mb={mb}>
{shortAddress}
</Text>
);
const accountMenu = address && (
<LinkBox>
<Flex align="center">
<LinkOverlay as={NavLink} to="/portfolio">
<QRPunkBlockie withQr={false} address={address.toLowerCase()} w={9} borderRadius={6} />
</LinkOverlay>
<Box ml={4}>
{/* ToDo. Move to Utils */}
<UserDisplayName textAlign="left" />
</Box>
<Tooltip label="Disconnect wallet">
<Button ml={4} onClick={logoutOfWeb3Modal} variant="outline" size="sm">
X
</Button>
</Tooltip>
</Flex>
</LinkBox>
);
const handleSignUpSuccess = () => {
closePopover();
toast({
title: "You are now registered!",
description: (
<>
Visit{" "}
<Link href="/portfolio" textDecoration="underline">
your portfolio
</Link>{" "}
to start building
</>
),
status: "success",
});
};
const anonymousMenu = address && (
<Popover placement="bottom-end" initialFocusRef={registerButtonRef} isOpen={isPopoverOpen} onClose={closePopover}>
<PopoverTrigger>
<Button variant="ghost" _hover={{ backgroundColor: "gray.50" }} w={9} p={0} onClick={openPopover}>
<Box>
<Icon as={HeroIconUser} w={6} h={6} color={secondaryFontColor} />
<AvatarBadge boxSize={2} bg="red.500" borderRadius="full" top="4px" right="4px" />
</Box>
</Button>
</PopoverTrigger>
<Tooltip label="Disconnect wallet">
<Button ml={4} onClick={logoutOfWeb3Modal} variant="outline" size="sm">
X
</Button>
</Tooltip>
<PopoverContent w={72}>
<PopoverBody
as={Flex}
direction="column"
px={9}
py={10}
_focus={{ background: "none" }}
_active={{ background: "none" }}
>
<Text color={primaryFontColor} fontWeight="bold" textAlign="center" mb={1}>
Register as a builder
</Text>
<Text color={secondaryFontColor} fontSize="sm" fontWeight="normal" textAlign="center" mb={6}>
Sign a message with your wallet to create a builder profile.
</Text>
<Box m="auto" p="px" borderWidth="1px" borderColor={dividerColor} borderRadius={8}>
<QRPunkBlockie address={address} w={19} borderRadius={6} />
</Box>
<UserDisplayName textAlign="center" mb={6} />
<SignatureSignUp
ref={registerButtonRef}
userProvider={userProvider}
address={address}
onSuccess={handleSignUpSuccess}
setUserRole={setUserRole}
/>
</PopoverBody>
</PopoverContent>
</Popover>
);
const userMenu = isAnonymous ? anonymousMenu : accountMenu;
return (
<Flex align="center">
{isAdmin && (
<Badge colorScheme="red" mr={4}>
admin
</Badge>
)}
{isBuilder && (
<Badge colorScheme="green" mr={4}>
builder
</Badge>
)}
{isWalletConnected ? userMenu : connectWallet}
</Flex>
);
}
Example #16
Source File: index.js From javascript-mini-projects with The Unlicense | 4 votes |
export default function Home({ category, quote, start }) {
const cat = useRef();
const [author, setAuthor] = useState(quote.author);
const [quotes, setQuotes] = useState(quote.content);
const [val, setVal] = useState(false);
const [bgImage, setBgImage] = useState("white");
const [fontCol, setFontCol] = useState("black");
const { reset } = useIdleTimer({
timeout: 1000 * 60 * 3,
onIdle: handleOnIdle,
});
function handleOnIdle() {
cat.current.value =
category[Math.floor(Math.random() * category.length)];
genQuote();
reset();
}
async function genQuote() {
const response = await axios.get(
`https://api.quotable.io/random?tags=${cat.current.value}`
);
setAuthor(response.data.author);
setQuotes(response.data.content);
let x = Math.floor(Math.random() * 256);
let y = Math.floor(Math.random() * 256);
let z = Math.floor(Math.random() * 256);
let bgColor = "rgb(" + x + "," + y + "," + z + ")";
setBgImage(bgColor);
let luminance = (0.299 * x + 0.587 * y + 0.114 * z) / 255;
let d = 0;
if (luminance > 0.5) d = 0;
// bright colors - black font
else d = 255; // dark colors - white font
setFontCol(`rgb(${d},${d},${d})`);
setVal(!val);
}
return (
<>
<Head>
<title>Random Quote Generator</title>
<meta
name="description"
content="Generated by create next app"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="true"
/>
<link
href="https://fonts.googleapis.com/css2?family=Prompt:wght@300&display=swap"
rel="stylesheet"
/>
</Head>
<Box minH="100vh" w="100vw" zIndex="-1" position="fixed"></Box>
<Flex
flexDir="column"
alignItems="center"
justifyContent="center"
w="100vw"
bg={bgImage}
minH="100vh"
>
<Heading my="3rem" fontSize="2rem" color={fontCol}>
Random Quote Generator
</Heading>
<Flex
justifyContent="center"
bg="purple"
w="100vw"
mb="3rem"
p="1rem"
>
<Flex
alignItems="center"
justifyContent="space-around"
w="30%"
minW="200px"
>
<Text as="strong" color="white">
Select a category :
</Text>
<Select
maxW="250px"
textTransform="capitalize"
ref={cat}
defaultValue={start}
variant="outline"
color="black"
bgColor="white"
>
{category &&
category.map((item) => (
<option value={item} key={item}>
{item}
</option>
))}
{!category && <Spinner size="lg" />}
</Select>
</Flex>
</Flex>
<Box
w="50%"
minW="250px"
bg="gray.100"
boxShadow="inset 2px 2px 8px gray"
borderRadius="lg"
p="3rem"
fontSize="1.8rem"
fontFamily="Prompt"
>
<Text as="blockquote" fontWeight="semibold">
{quotes}
</Text>
<Text as="i" d="block" textAlign="right" mt="2rem">
~ {author}
</Text>
</Box>
<Button onClick={genQuote} colorScheme="facebook" mt="3rem">
Get New Quote
</Button>
</Flex>
</>
);
}