Merge pull request #9 from GRA0007/dev
Timezones and better url generation
This commit is contained in:
commit
8aed37c413
|
|
@ -18,6 +18,7 @@
|
|||
"cors": "^2.8.5",
|
||||
"dayjs": "^1.10.4",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1"
|
||||
"express": "^4.17.1",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,49 @@
|
|||
const dayjs = require('dayjs');
|
||||
const punycode = require('punycode/');
|
||||
|
||||
const adjectives = require('../res/adjectives.json');
|
||||
const crabs = require('../res/crabs.json');
|
||||
|
||||
const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1);
|
||||
|
||||
const generateId = (name) => {
|
||||
const id = name.trim().toLowerCase().replace(/[^A-Za-z0-9 ]/g, '').replace(/\s+/g, '-');
|
||||
const number = Math.floor(100000 + Math.random() * 900000);
|
||||
return `${id}-${number}`;
|
||||
};
|
||||
const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1);
|
||||
|
||||
// Generate a random name based on an adjective and a crab species
|
||||
const generateName = () => {
|
||||
return `${capitalize(adjectives[Math.floor(Math.random() * adjectives.length)])} ${crabs[Math.floor(Math.random() * crabs.length)]} Crab`;
|
||||
};
|
||||
|
||||
// Generate a slug for the crab fit
|
||||
const generateId = name => {
|
||||
let id = punycode.encode(name.trim().toLowerCase()).trim().replace(/[^A-Za-z0-9 ]/g, '').replace(/\s+/g, '-');
|
||||
if (id.replace(/-/g, '') === '') {
|
||||
id = generateName().trim().toLowerCase().replace(/[^A-Za-z0-9 ]/g, '').replace(/\s+/g, '-');
|
||||
}
|
||||
const number = Math.floor(100000 + Math.random() * 900000);
|
||||
return `${id}-${number}`;
|
||||
};
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const { event } = req.body;
|
||||
|
||||
try {
|
||||
const name = event.name.trim() === '' ? generateName() : event.name.trim();
|
||||
const eventId = generateId(name);
|
||||
let eventId = generateId(name);
|
||||
const currentTime = dayjs().unix();
|
||||
|
||||
const entity = {
|
||||
// Check if the event ID already exists, and if so generate a new one
|
||||
let eventResult;
|
||||
do {
|
||||
const query = req.datastore.createQuery(req.types.event)
|
||||
.select('__key__')
|
||||
.filter('__key__', req.datastore.key([req.types.event, eventId]));
|
||||
|
||||
eventResult = (await req.datastore.runQuery(query))[0][0];
|
||||
|
||||
if (eventResult !== undefined) {
|
||||
eventId = generateId(name);
|
||||
}
|
||||
} while (eventResult !== undefined);
|
||||
|
||||
const entity = {
|
||||
key: req.datastore.key([req.types.event, eventId]),
|
||||
data: {
|
||||
name: name,
|
||||
|
|
|
|||
|
|
@ -942,6 +942,11 @@ pumpify@^2.0.1:
|
|||
inherits "^2.0.3"
|
||||
pump "^3.0.0"
|
||||
|
||||
punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
qs@6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import dayjs from 'dayjs';
|
|||
import utc from 'dayjs/plugin/utc';
|
||||
import timezone from 'dayjs/plugin/timezone';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
|
||||
import {
|
||||
Center,
|
||||
|
|
@ -23,6 +24,7 @@ import {
|
|||
Logo,
|
||||
Title,
|
||||
EventName,
|
||||
EventDate,
|
||||
LoginForm,
|
||||
LoginSection,
|
||||
Info,
|
||||
|
|
@ -40,6 +42,7 @@ import timezones from 'res/timezones.json';
|
|||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
dayjs.extend(customParseFormat);
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
const Event = (props) => {
|
||||
const timeFormat = useSettingsStore(state => state.timeFormat);
|
||||
|
|
@ -283,6 +286,7 @@ const Event = (props) => {
|
|||
{(!!event || isLoading) ? (
|
||||
<>
|
||||
<EventName isLoading={isLoading}>{event?.name}</EventName>
|
||||
<EventDate isLoading={isLoading} title={event?.created && dayjs.unix(event?.created).format('h:mma D MMMM, YYYY')}>{event?.created && `Created ${dayjs.unix(event?.created).fromNow()}`}</EventDate>
|
||||
<ShareInfo
|
||||
onClick={() => navigator.clipboard?.writeText(`https://crab.fit/${id}`)
|
||||
.then(() => {
|
||||
|
|
@ -366,6 +370,22 @@ const Event = (props) => {
|
|||
onChange={event => setTimezone(event.currentTarget.value)}
|
||||
options={timezones}
|
||||
/>
|
||||
{event?.timezone && event.timezone !== timezone && <p>This event was created in the timezone <strong>{event.timezone}</strong>. <a href="#" onClick={e => {
|
||||
e.preventDefault();
|
||||
setTimezone(event.timezone);
|
||||
}}>Click here</a> to use it.</p>}
|
||||
{((
|
||||
Intl.DateTimeFormat().resolvedOptions().timeZone !== timezone
|
||||
&& (event?.timezone && event.timezone !== Intl.DateTimeFormat().resolvedOptions().timeZone)
|
||||
) || (
|
||||
event?.timezone === undefined
|
||||
&& Intl.DateTimeFormat().resolvedOptions().timeZone !== timezone
|
||||
)) && (
|
||||
<p>Your local timezone is detected to be <strong>{Intl.DateTimeFormat().resolvedOptions().timeZone}</strong>. <a href="#" onClick={e => {
|
||||
e.preventDefault();
|
||||
setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
}}>Click here</a> to use it.</p>
|
||||
)}
|
||||
</StyledMain>
|
||||
</LoginSection>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export const Title = styled.span`
|
|||
export const EventName = styled.h1`
|
||||
text-align: center;
|
||||
font-weight: 800;
|
||||
margin: 20px 0 14px;
|
||||
margin: 20px 0 5px;
|
||||
|
||||
${props => props.isLoading && `
|
||||
&:after {
|
||||
|
|
@ -39,6 +39,28 @@ export const EventName = styled.h1`
|
|||
`}
|
||||
`;
|
||||
|
||||
export const EventDate = styled.span`
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
opacity: .8;
|
||||
margin: 0 0 10px;
|
||||
font-weight: 500;
|
||||
letter-spacing: .01em;
|
||||
|
||||
${props => props.isLoading && `
|
||||
&:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
width: 200px;
|
||||
max-width: 100%;
|
||||
background-color: ${props.theme.loading};
|
||||
border-radius: 3px;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
export const LoginForm = styled.form`
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 100px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue