commit
156f9bcd03
|
|
@ -29,6 +29,7 @@ module.exports = async (req, res) => {
|
|||
name: name,
|
||||
created: currentTime,
|
||||
times: event.times,
|
||||
timezone: event.timezone,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -39,6 +40,7 @@ module.exports = async (req, res) => {
|
|||
name: name,
|
||||
created: currentTime,
|
||||
times: event.times,
|
||||
timezone: event.timezone,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ definitions:
|
|||
type: "string"
|
||||
name:
|
||||
type: "string"
|
||||
timezone:
|
||||
type: "string"
|
||||
created:
|
||||
type: "integer"
|
||||
times:
|
||||
|
|
@ -81,6 +83,8 @@ paths:
|
|||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
timezone:
|
||||
type: "string"
|
||||
times:
|
||||
type: "array"
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { useState, Fragment } from 'react';
|
||||
import { useState, useEffect, Fragment } from 'react';
|
||||
import dayjs from 'dayjs';
|
||||
import localeData from 'dayjs/plugin/localeData';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
|
||||
import { useSettingsStore } from 'stores';
|
||||
|
||||
import { Legend, Center } from 'components';
|
||||
import {
|
||||
Wrapper,
|
||||
Container,
|
||||
|
|
@ -21,6 +22,9 @@ import {
|
|||
TimeLabels,
|
||||
TimeLabel,
|
||||
TimeSpace,
|
||||
People,
|
||||
Person,
|
||||
StyledMain,
|
||||
} from './availabilityViewerStyle';
|
||||
|
||||
dayjs.extend(localeData);
|
||||
|
|
@ -38,83 +42,134 @@ const AvailabilityViewer = ({
|
|||
}) => {
|
||||
const [tooltip, setTooltip] = useState(null);
|
||||
const timeFormat = useSettingsStore(state => state.timeFormat);
|
||||
const [filteredPeople, setFilteredPeople] = useState([]);
|
||||
const [touched, setTouched] = useState(false);
|
||||
const [tempFocus, setTempFocus] = useState(null);
|
||||
const [focusCount, setFocusCount] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
setFilteredPeople(people.map(p => p.name));
|
||||
setTouched(people.length <= 1);
|
||||
}, [people]);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Container>
|
||||
<TimeLabels>
|
||||
{!!timeLabels.length && timeLabels.map((label, i) =>
|
||||
<TimeSpace key={i}>
|
||||
{label.label?.length !== '' && <TimeLabel>{label.label}</TimeLabel>}
|
||||
</TimeSpace>
|
||||
)}
|
||||
</TimeLabels>
|
||||
{dates.map((date, i) => {
|
||||
const parsedDate = isSpecificDates ? dayjs(date, 'DDMMYYYY') : dayjs().day(date);
|
||||
const last = dates.length === i+1 || (isSpecificDates ? dayjs(dates[i+1], 'DDMMYYYY') : dayjs().day(dates[i+1])).diff(parsedDate, 'day') > 1;
|
||||
return (
|
||||
<Fragment key={i}>
|
||||
<Date>
|
||||
{isSpecificDates && <DateLabel>{parsedDate.format('MMM D')}</DateLabel>}
|
||||
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
||||
<>
|
||||
<StyledMain>
|
||||
<Legend
|
||||
min={Math.min(min, filteredPeople.length)}
|
||||
max={Math.min(max, filteredPeople.length)}
|
||||
total={people.filter(p => p.availability.length > 0).length}
|
||||
onSegmentFocus={count => setFocusCount(count)}
|
||||
/>
|
||||
<Center>Hover or tap the calendar below to see who is available</Center>
|
||||
{people.length > 1 && (
|
||||
<>
|
||||
<Center>Click the names below to view people individually</Center>
|
||||
<People>
|
||||
{people.map((person, i) =>
|
||||
<Person
|
||||
key={i}
|
||||
filtered={filteredPeople.includes(person.name)}
|
||||
onClick={() => {
|
||||
setTempFocus(null);
|
||||
if (filteredPeople.includes(person.name)) {
|
||||
if (!touched) {
|
||||
setTouched(true);
|
||||
setFilteredPeople([person.name]);
|
||||
} else {
|
||||
setFilteredPeople(filteredPeople.filter(n => n !== person.name));
|
||||
}
|
||||
} else {
|
||||
setFilteredPeople([...filteredPeople, person.name]);
|
||||
}
|
||||
}}
|
||||
onMouseOver={() => setTempFocus(person.name)}
|
||||
onMouseOut={() => setTempFocus(null)}
|
||||
>{person.name}</Person>
|
||||
)}
|
||||
</People>
|
||||
</>
|
||||
)}
|
||||
</StyledMain>
|
||||
|
||||
<Times>
|
||||
{timeLabels.map((timeLabel, i) => {
|
||||
if (!timeLabel.time) return null;
|
||||
if (!times.includes(`${timeLabel.time}-${date}`)) {
|
||||
return (
|
||||
<TimeSpace key={i} />
|
||||
);
|
||||
}
|
||||
const time = `${timeLabel.time}-${date}`;
|
||||
const peopleHere = people.filter(person => person.availability.includes(time)).map(person => person.name);
|
||||
<Wrapper>
|
||||
<Container>
|
||||
<TimeLabels>
|
||||
{!!timeLabels.length && timeLabels.map((label, i) =>
|
||||
<TimeSpace key={i}>
|
||||
{label.label?.length !== '' && <TimeLabel>{label.label}</TimeLabel>}
|
||||
</TimeSpace>
|
||||
)}
|
||||
</TimeLabels>
|
||||
{dates.map((date, i) => {
|
||||
const parsedDate = isSpecificDates ? dayjs(date, 'DDMMYYYY') : dayjs().day(date);
|
||||
const last = dates.length === i+1 || (isSpecificDates ? dayjs(dates[i+1], 'DDMMYYYY') : dayjs().day(dates[i+1])).diff(parsedDate, 'day') > 1;
|
||||
return (
|
||||
<Fragment key={i}>
|
||||
<Date>
|
||||
{isSpecificDates && <DateLabel>{parsedDate.format('MMM D')}</DateLabel>}
|
||||
<DayLabel>{parsedDate.format('ddd')}</DayLabel>
|
||||
|
||||
return (
|
||||
<Time
|
||||
key={i}
|
||||
time={time}
|
||||
className="time"
|
||||
peopleCount={peopleHere.length}
|
||||
aria-label={peopleHere.join(', ')}
|
||||
maxPeople={max}
|
||||
minPeople={min}
|
||||
onMouseEnter={(e) => {
|
||||
const cellBox = e.currentTarget.getBoundingClientRect();
|
||||
const timeText = timeFormat === '12h' ? 'h:mma' : 'HH:mm';
|
||||
setTooltip({
|
||||
x: Math.round(cellBox.x + cellBox.width/2),
|
||||
y: Math.round(cellBox.y + cellBox.height)+6,
|
||||
available: `${peopleHere.length} / ${people.length} available`,
|
||||
date: parsedDate.hour(time.slice(0, 2)).minute(time.slice(2, 4)).format(isSpecificDates ? `${timeText} ddd, D MMM YYYY` : `${timeText} ddd`),
|
||||
people: peopleHere.join(', '),
|
||||
});
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setTooltip(null);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Times>
|
||||
</Date>
|
||||
{last && dates.length !== i+1 && (
|
||||
<Spacer />
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</Container>
|
||||
{tooltip && (
|
||||
<Tooltip
|
||||
x={tooltip.x}
|
||||
y={tooltip.y}
|
||||
>
|
||||
<TooltipTitle>{tooltip.available}</TooltipTitle>
|
||||
<TooltipDate>{tooltip.date}</TooltipDate>
|
||||
<TooltipContent>{tooltip.people}</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Wrapper>
|
||||
<Times>
|
||||
{timeLabels.map((timeLabel, i) => {
|
||||
if (!timeLabel.time) return null;
|
||||
if (!times.includes(`${timeLabel.time}-${date}`)) {
|
||||
return (
|
||||
<TimeSpace key={i} />
|
||||
);
|
||||
}
|
||||
const time = `${timeLabel.time}-${date}`;
|
||||
const peopleHere = tempFocus !== null
|
||||
? people.filter(person => person.availability.includes(time) && tempFocus === person.name).map(person => person.name)
|
||||
: people.filter(person => person.availability.includes(time) && filteredPeople.includes(person.name)).map(person => person.name);
|
||||
|
||||
return (
|
||||
<Time
|
||||
key={i}
|
||||
time={time}
|
||||
className="time"
|
||||
peopleCount={focusCount !== null && focusCount !== peopleHere.length ? 0 : peopleHere.length}
|
||||
aria-label={peopleHere.join(', ')}
|
||||
maxPeople={tempFocus !== null ? 1 : Math.min(max, filteredPeople.length)}
|
||||
minPeople={tempFocus !== null ? 0 : Math.min(min, filteredPeople.length)}
|
||||
onMouseEnter={(e) => {
|
||||
const cellBox = e.currentTarget.getBoundingClientRect();
|
||||
const timeText = timeFormat === '12h' ? 'h:mma' : 'HH:mm';
|
||||
setTooltip({
|
||||
x: Math.round(cellBox.x + cellBox.width/2),
|
||||
y: Math.round(cellBox.y + cellBox.height)+6,
|
||||
available: `${peopleHere.length} / ${people.length} available`,
|
||||
date: parsedDate.hour(time.slice(0, 2)).minute(time.slice(2, 4)).format(isSpecificDates ? `${timeText} ddd, D MMM YYYY` : `${timeText} ddd`),
|
||||
people: peopleHere.join(', '),
|
||||
});
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setTooltip(null);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Times>
|
||||
</Date>
|
||||
{last && dates.length !== i+1 && (
|
||||
<Spacer />
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</Container>
|
||||
{tooltip && (
|
||||
<Tooltip
|
||||
x={tooltip.x}
|
||||
y={tooltip.y}
|
||||
>
|
||||
<TooltipTitle>{tooltip.available}</TooltipTitle>
|
||||
<TooltipDate>{tooltip.date}</TooltipDate>
|
||||
<TooltipContent>{tooltip.people}</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Wrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -127,3 +127,35 @@ export const TimeLabel = styled.label`
|
|||
user-select: none;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const StyledMain = styled.div`
|
||||
width: 600px;
|
||||
margin: 20px auto;
|
||||
max-width: calc(100% - 60px);
|
||||
`;
|
||||
|
||||
export const People = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
justify-content: center;
|
||||
margin: 14px auto;
|
||||
`;
|
||||
|
||||
export const Person = styled.button`
|
||||
font: inherit;
|
||||
font-size: 15px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid ${props => props.theme.text};
|
||||
color: ${props => props.theme.text};
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
padding: 2px 8px;
|
||||
|
||||
${props => props.filtered && `
|
||||
background: ${props.theme.primary};
|
||||
color: ${props.theme.background};
|
||||
border-color: ${props.theme.primary};
|
||||
`}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { useTWAStore } from 'stores';
|
|||
const PAYMENT_METHOD = 'https://play.google.com/billing';
|
||||
const SKU = 'crab_donation';
|
||||
|
||||
const Donate = () => {
|
||||
const Donate = ({ onDonate = null }) => {
|
||||
const store = useTWAStore();
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -80,9 +80,12 @@ const Donate = () => {
|
|||
alert('Cannot make donation through Google. Please try donating through the website crab.fit 🦀');
|
||||
}
|
||||
}
|
||||
} else if (onDonate !== null) {
|
||||
event.preventDefault();
|
||||
onDonate();
|
||||
}
|
||||
}}
|
||||
href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD"
|
||||
href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=5"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
|
|
|||
28
crabfit-frontend/src/components/Footer/Footer.tsx
Normal file
28
crabfit-frontend/src/components/Footer/Footer.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { Donate } from 'components';
|
||||
import { Wrapper, Link } from './footerStyle';
|
||||
|
||||
const Footer = () => {
|
||||
const [donateMode, setDonateMode] = useState(false);
|
||||
|
||||
return (
|
||||
<Wrapper id="donate" donateMode={donateMode}>
|
||||
{donateMode ? (
|
||||
<>
|
||||
<Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=2" target="_blank">Donate $2</Link>
|
||||
<Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=5" target="_blank"><strong>Donate $5</strong></Link>
|
||||
<Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=10" target="_blank">Donate $10</Link>
|
||||
<Link href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD" target="_blank">Choose an amount</Link>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
|
||||
<Donate onDonate={() => setDonateMode(true)} />
|
||||
</>
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
23
crabfit-frontend/src/components/Footer/footerStyle.ts
Normal file
23
crabfit-frontend/src/components/Footer/footerStyle.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import styled from '@emotion/styled';
|
||||
|
||||
export const Wrapper = styled.footer`
|
||||
width: 600px;
|
||||
margin: 20px auto;
|
||||
max-width: calc(100% - 60px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
${props => props.donateMode && `
|
||||
flex-wrap: wrap;
|
||||
`}
|
||||
`;
|
||||
|
||||
export const Link = styled.a`
|
||||
padding: 11px 10px;
|
||||
white-space: nowrap;
|
||||
|
||||
& strong {
|
||||
font-weight: 800;
|
||||
}
|
||||
`;
|
||||
|
|
@ -11,6 +11,7 @@ const Legend = ({
|
|||
min,
|
||||
max,
|
||||
total,
|
||||
onSegmentFocus,
|
||||
...props
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
|
@ -19,9 +20,13 @@ const Legend = ({
|
|||
<Wrapper>
|
||||
<Label>{min}/{total} available</Label>
|
||||
|
||||
<Bar>
|
||||
<Bar onMouseOut={() => onSegmentFocus(null)}>
|
||||
{[...Array(max-min+1).keys()].map(i =>
|
||||
<Grade key={i} color={`${theme.primary}${Math.round((i/(max-min))*255).toString(16)}`} />
|
||||
<Grade
|
||||
key={i}
|
||||
color={`${theme.primary}${Math.round((i/(max-min))*255).toString(16)}`}
|
||||
onMouseOver={() => onSegmentFocus(i+min)}
|
||||
/>
|
||||
)}
|
||||
</Bar>
|
||||
|
||||
|
|
|
|||
|
|
@ -15,3 +15,4 @@ export { default as Center } from './Center/Center';
|
|||
export { default as Donate } from './Donate/Donate';
|
||||
export { default as Settings } from './Settings/Settings';
|
||||
export { default as Egg } from './Egg/Egg';
|
||||
export { default as Footer } from './Footer/Footer';
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ const Create = ({ offline }) => {
|
|||
event: {
|
||||
name: data.name,
|
||||
times: times,
|
||||
timezone: data.timezone,
|
||||
},
|
||||
});
|
||||
setCreatedEvent(response.data);
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@ import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|||
|
||||
import {
|
||||
Center,
|
||||
Donate,
|
||||
Footer,
|
||||
TextField,
|
||||
SelectField,
|
||||
Button,
|
||||
Legend,
|
||||
AvailabilityViewer,
|
||||
AvailabilityEditor,
|
||||
Error,
|
||||
|
|
@ -21,7 +20,6 @@ import {
|
|||
|
||||
import {
|
||||
StyledMain,
|
||||
Footer,
|
||||
Logo,
|
||||
Title,
|
||||
EventName,
|
||||
|
|
@ -398,14 +396,6 @@ const Event = (props) => {
|
|||
|
||||
{tab === 'group' ? (
|
||||
<section id="group">
|
||||
<StyledMain>
|
||||
<Legend
|
||||
min={min}
|
||||
max={max}
|
||||
total={people.filter(p => p.availability.length > 0).length}
|
||||
/>
|
||||
<Center>Hover or tap the calendar below to see who is available</Center>
|
||||
</StyledMain>
|
||||
<AvailabilityViewer
|
||||
times={times}
|
||||
timeLabels={timeLabels}
|
||||
|
|
@ -451,10 +441,7 @@ const Event = (props) => {
|
|||
</>
|
||||
)}
|
||||
|
||||
<Footer id="donate">
|
||||
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
|
||||
<Donate />
|
||||
</Footer>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,15 +6,6 @@ export const StyledMain = styled.div`
|
|||
max-width: calc(100% - 60px);
|
||||
`;
|
||||
|
||||
export const Footer = styled.footer`
|
||||
width: 600px;
|
||||
margin: 50px auto 20px;
|
||||
max-width: calc(100% - 60px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
export const Logo = styled.img`
|
||||
width: 2.5rem;
|
||||
margin-right: 16px;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Link, useHistory } from 'react-router-dom';
|
|||
import {
|
||||
Button,
|
||||
Center,
|
||||
Donate,
|
||||
Footer,
|
||||
AvailabilityViewer,
|
||||
Legend,
|
||||
} from 'components';
|
||||
|
|
@ -14,7 +14,6 @@ import {
|
|||
Logo,
|
||||
Title,
|
||||
AboutSection,
|
||||
Footer,
|
||||
P,
|
||||
Step,
|
||||
FakeCalendar,
|
||||
|
|
@ -77,11 +76,6 @@ const Help = () => {
|
|||
<P>Send the link to everyone you want to come.</P>
|
||||
<P>After Jenny has sent the link to her friends and waited for them to also fill out their availabilities, she can now easily see them all on the heatmap below and choose the darkest area for a time that suits everyone!</P>
|
||||
<P>In this example, 1pm to 3pm on Friday the 16th works for all Jenny's friends.</P>
|
||||
<Legend
|
||||
min={0}
|
||||
max={5}
|
||||
total={5}
|
||||
/>
|
||||
<AvailabilityViewer
|
||||
times={["1100-12042021","1115-12042021","1130-12042021","1145-12042021","1200-12042021","1215-12042021","1230-12042021","1245-12042021","1300-12042021","1315-12042021","1330-12042021","1345-12042021","1400-12042021","1415-12042021","1430-12042021","1445-12042021","1500-12042021","1515-12042021","1530-12042021","1545-12042021","1600-12042021","1615-12042021","1630-12042021","1645-12042021","1100-13042021","1115-13042021","1130-13042021","1145-13042021","1200-13042021","1215-13042021","1230-13042021","1245-13042021","1300-13042021","1315-13042021","1330-13042021","1345-13042021","1400-13042021","1415-13042021","1430-13042021","1445-13042021","1500-13042021","1515-13042021","1530-13042021","1545-13042021","1600-13042021","1615-13042021","1630-13042021","1645-13042021","1100-14042021","1115-14042021","1130-14042021","1145-14042021","1200-14042021","1215-14042021","1230-14042021","1245-14042021","1300-14042021","1315-14042021","1330-14042021","1345-14042021","1400-14042021","1415-14042021","1430-14042021","1445-14042021","1500-14042021","1515-14042021","1530-14042021","1545-14042021","1600-14042021","1615-14042021","1630-14042021","1645-14042021","1100-15042021","1115-15042021","1130-15042021","1145-15042021","1200-15042021","1215-15042021","1230-15042021","1245-15042021","1300-15042021","1315-15042021","1330-15042021","1345-15042021","1400-15042021","1415-15042021","1430-15042021","1445-15042021","1500-15042021","1515-15042021","1530-15042021","1545-15042021","1600-15042021","1615-15042021","1630-15042021","1645-15042021","1100-16042021","1115-16042021","1130-16042021","1145-16042021","1200-16042021","1215-16042021","1230-16042021","1245-16042021","1300-16042021","1315-16042021","1330-16042021","1345-16042021","1400-16042021","1415-16042021","1430-16042021","1445-16042021","1500-16042021","1515-16042021","1530-16042021","1545-16042021","1600-16042021","1615-16042021","1630-16042021","1645-16042021"]}
|
||||
timeLabels={[{"label":"11 AM","time":"1100"},{"label":"","time":"1115"},{"label":"","time":"1130"},{"label":"","time":"1145"},{"label":"12 PM","time":"1200"},{"label":"","time":"1215"},{"label":"","time":"1230"},{"label":"","time":"1245"},{"label":"1 PM","time":"1300"},{"label":"","time":"1315"},{"label":"","time":"1330"},{"label":"","time":"1345"},{"label":"2 PM","time":"1400"},{"label":"","time":"1415"},{"label":"","time":"1430"},{"label":"","time":"1445"},{"label":"3 PM","time":"1500"},{"label":"","time":"1515"},{"label":"","time":"1530"},{"label":"","time":"1545"},{"label":"4 PM","time":"1600"},{"label":"","time":"1615"},{"label":"","time":"1630"},{"label":"","time":"1645"},{"label":"5 PM","time":null}]}
|
||||
|
|
@ -99,10 +93,7 @@ const Help = () => {
|
|||
</StyledMain>
|
||||
</AboutSection>
|
||||
|
||||
<Footer id="donate">
|
||||
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
|
||||
<Donate />
|
||||
</Footer>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,15 +27,6 @@ export const AboutSection = styled.section`
|
|||
padding: 20px 0;
|
||||
`;
|
||||
|
||||
export const Footer = styled.footer`
|
||||
width: 600px;
|
||||
margin: 20px auto;
|
||||
max-width: calc(100% - 60px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
export const P = styled.p`
|
||||
font-weight: 500;
|
||||
line-height: 1.6em;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import {
|
|||
SelectField,
|
||||
Button,
|
||||
Center,
|
||||
Donate,
|
||||
Error,
|
||||
Footer,
|
||||
} from 'components';
|
||||
|
||||
import {
|
||||
|
|
@ -26,7 +26,6 @@ import {
|
|||
Logo,
|
||||
Links,
|
||||
AboutSection,
|
||||
Footer,
|
||||
P,
|
||||
Stats,
|
||||
Stat,
|
||||
|
|
@ -132,6 +131,7 @@ const Home = ({ offline }) => {
|
|||
event: {
|
||||
name: data.name,
|
||||
times: times,
|
||||
timezone: data.timezone,
|
||||
},
|
||||
});
|
||||
push(`/${response.data.id}`);
|
||||
|
|
@ -244,18 +244,15 @@ const Home = ({ offline }) => {
|
|||
</Stats>
|
||||
<P>Crab Fit helps you fit your event around everyone's schedules. Simply create an event above and send the link to everyone that is participating. Results update live and you will be able to see a heat-map of when everyone is free.<br /><Link to="/how-to">Learn more about how to Crab Fit</Link>.</P>
|
||||
{/* eslint-disable-next-line */}
|
||||
<P>Create a lot of Crab Fits? Get the <a href="https://chrome.google.com/webstore/detail/crab-fit/pnafiibmjbiljofcpjlbonpgdofjhhkj" target="_blank">Chrome extension</a> or <a href="https://addons.mozilla.org/en-US/firefox/addon/crab-fit/" target="_blank">Firefox extension</a> for your browser!</P>
|
||||
<P>Create a lot of Crab Fits? Get the <a href="https://chrome.google.com/webstore/detail/crab-fit/pnafiibmjbiljofcpjlbonpgdofjhhkj" target="_blank">Chrome extension</a> or <a href="https://addons.mozilla.org/en-US/firefox/addon/crab-fit/" target="_blank">Firefox extension</a> for your browser! You can also download the <a href="https://play.google.com/store/apps/details?id=fit.crab" target="_blank">Android app</a> to Crab Fit on the go.</P>
|
||||
{/* eslint-disable-next-line */}
|
||||
<P>Created by <a href="https://bengrant.dev" target="_blank">Ben Grant</a>, Crab Fit is the modern-day solution to your group event planning debates.</P>
|
||||
<P>The code for Crab Fit is open source, if you find any issues or want to contribute, you can visit the <a href="https://github.com/GRA0007/crab.fit" target="_blank" rel="noreferrer">repository</a>.</P>
|
||||
<P>The code for Crab Fit is open source, if you find any issues or want to contribute, you can visit the <a href="https://github.com/GRA0007/crab.fit" target="_blank" rel="noreferrer">repository</a>. By using Crab Fit you agree to the <Link to="/privacy">privacy policy</Link>.</P>
|
||||
<P>Crab Fit costs more than <strong>$100 per month</strong> to run. Consider donating below if it helped you out so it can stay free for everyone. 🦀</P>
|
||||
</StyledMain>
|
||||
</AboutSection>
|
||||
|
||||
<Footer id="donate">
|
||||
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
|
||||
<Donate />
|
||||
</Footer>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,15 +51,6 @@ export const AboutSection = styled.section`
|
|||
padding: 20px 0;
|
||||
`;
|
||||
|
||||
export const Footer = styled.footer`
|
||||
width: 600px;
|
||||
margin: 20px auto;
|
||||
max-width: calc(100% - 60px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
export const P = styled.p`
|
||||
font-weight: 500;
|
||||
line-height: 1.6em;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Link, useHistory } from 'react-router-dom';
|
|||
import {
|
||||
Button,
|
||||
Center,
|
||||
Donate,
|
||||
Footer,
|
||||
} from 'components';
|
||||
|
||||
import {
|
||||
|
|
@ -12,7 +12,6 @@ import {
|
|||
Logo,
|
||||
Title,
|
||||
AboutSection,
|
||||
Footer,
|
||||
P,
|
||||
} from '../Help/helpStyle';
|
||||
|
||||
|
|
@ -95,10 +94,7 @@ const Privacy = () => {
|
|||
</StyledMain>
|
||||
</AboutSection>
|
||||
|
||||
<Footer id="donate">
|
||||
<span>Thank you for using Crab Fit. If you like it, consider donating.</span>
|
||||
<Donate />
|
||||
</Footer>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue