Skip to content

Commit

Permalink
Merge branch 'issue-47' of github.com:typeofweb/polskifrontend into i…
Browse files Browse the repository at this point in the history
…ssue-47
  • Loading branch information
wisnie committed Jan 1, 2021
2 parents 6da04ab + 4fa372d commit 963b10e
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 73 deletions.
7 changes: 4 additions & 3 deletions components/AddContentCreatorForm/AddContentCreatorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import clsx from 'clsx';
import type { ChangeEventHandler, FormEventHandler } from 'react';
import { useEffect, useRef, useCallback, useState } from 'react';

import { useAddContentCreatorMutation } from '../../hooks/useAddContentCreatorMutation';
import { useMutation } from '../../hooks/useMutation';
import { addContentCreator } from '../../utils/api/addContentCreator';
import { Button } from '../Button/Button';

import { FormStatus } from './FormStatus';
Expand All @@ -12,11 +13,11 @@ import styles from './addContentCreatorForm.module.scss';
export const AddContentCreatorForm = () => {
const [fields, setFields] = useState({ contentURL: '', email: '' });
const [token, setToken] = useState<string | null>(null);
const [mutate, status] = useAddContentCreatorMutation();
const [touched, setTouched] = useState<Record<string, boolean>>({});
const captchaRef = useRef<null | HCaptcha>(null);
const formRef = useRef<null | HTMLFormElement>(null);
const [isFormValid, setIsFormValid] = useState(false);
const { mutate, status, errorCode } = useMutation(addContentCreator);

useEffect(() => {
if (status === 'success') {
Expand Down Expand Up @@ -110,7 +111,7 @@ export const AddContentCreatorForm = () => {
Zgłoś
</Button>
</div>
<FormStatus status={status} />
<FormStatus status={status} errorCode={errorCode} />
</form>
);
};
71 changes: 34 additions & 37 deletions components/AddContentCreatorForm/FormStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
import clsx from 'clsx';
import { memo } from 'react';

import type { Status } from '../../hooks/useAddContentCreatorMutation';
import type { Status } from '../../hooks/useMutation';

import styles from './FormStatus.module.css';

type Props = {
readonly status: Status;
readonly errorCode?: number;
};

export const FormStatus = memo<Props>(({ status }) => {
const errorToMessage: Record<number, string> = {
409: 'Blog o podanym adresie został już dodany do naszej bazy danych. Jeżeli nie pojawiają się najnowsze wpisy, lub masz inne zastrzeżenia - proszę skontaktuj się z administratorem.',
422: 'Nie udało się odnaleźć pliku RSS na twojej stronie, jeśli ten błąd się powtarza, proszę skontaktuj się z administratorem.',
};

const defaultErrorMessage =
'Wystąpił błąd podczas dodawania nowego serwisu, sprawdź poprawność danych i spróbuj ponownie';

function getStatusMessage({ status, errorCode }: Props) {
switch (status) {
case 'loading':
return (
<div className={styles.statusContainer}>
<span className={clsx(styles.statusIcon, 'icon-spinner')}></span>
<span>Oczekiwanie...</span>
</div>
);
case 'error':
return (
<div className={styles.statusContainer}>
<span className={clsx(styles.statusIcon, 'icon-error')}></span>
<span>
Wystąpił błąd podczas dodawania nowego serwisu, sprawdź poprawność danych i spróbuj
ponownie
</span>
</div>
);
case 'notRssFound':
return (
<div className={styles.statusContainer}>
<span className={clsx(styles.statusIcon, 'icon-error')}></span>
<span>
Nie udało się odnaleźć pliku rss na twojej stronie, jeśli ten błąd się powtarza, proszę
skontaktuj się z administratorem.
</span>
</div>
);
return 'Oczekiwanie...';
case 'success':
return (
<div className={styles.statusContainer}>
<span className={clsx(styles.statusIcon, 'icon-checkmark')}></span>
<span>
Dziękujemy za zgłoszenie, dodany serwis pojawi się na stronie po zaakceptowaniu przez
administrację
</span>
</div>
);
return 'Dziękujemy za zgłoszenie, dodany serwis pojawi się na stronie po zaakceptowaniu przez administrację';
case 'error':
return errorCode ? errorToMessage[errorCode] ?? defaultErrorMessage : defaultErrorMessage;
default:
return null;
}
}

export const FormStatus = memo<Props>(({ status, errorCode }) => {
if (status === 'idle') {
return null;
}

return (
<div className={styles.statusContainer}>
<span
className={clsx(styles.statusIcon, {
'icon-spinner': status === 'loading',
'icon-checkmark': status === 'success',
'icon-error': status === 'error',
})}
></span>
<span>{getStatusMessage({ status, errorCode })}</span>
</div>
);
});
FormStatus.displayName = 'FormStatus';
13 changes: 11 additions & 2 deletions components/ArticleSection/ArticleSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ import Link from 'next/link';
import { memo } from 'react';

import type { ArticlePageProps } from '../../pages/artykuly/[slug]';
import { detectContentGenre } from '../../utils/creator-utils';
import { formatDate } from '../../utils/date-utils';
import { addTrackingToLink } from '../../utils/link-utils';
import { Button } from '../Button/Button';

import styles from './articleSection.module.scss';

const linkLabels: Record<ReturnType<typeof detectContentGenre>, string> = {
blog: 'Przejdź do artykułu',
podcast: 'Przejdź do podcastu',
youtube: 'Przejdź do filmu',
};

type ArticleSectionProps = Pick<ArticlePageProps, 'article'>;

export const ArticleSection = memo<ArticleSectionProps>(({ article }) => {
const readableDate = formatDate(article.publishedAt);

const articleLinkLabel = linkLabels[detectContentGenre(article)];

return (
<section className={styles.section}>
<h2 className={styles.heading}>
Expand Down Expand Up @@ -42,10 +51,10 @@ export const ArticleSection = memo<ArticleSectionProps>(({ article }) => {
<time className={styles.publishDate}>{readableDate}</time>
<div dangerouslySetInnerHTML={{ __html: article.sanitizedDescription }} />
<section className={styles.linkWrapper}>
<p className={styles.linkHeader}>Chcesz więcej? Przeczytaj w oryginale!</p>
<p className={styles.linkHeader}>Chcesz więcej? Sprawdź w oryginale!</p>
<Link href={addTrackingToLink(article.href, { utm_medium: 'article_page' })} passHref>
<Button icon="icon-new-tab" as="a" target="_blank" rel="noopener noreferrer">
Przejdź do artykułu
{articleLinkLabel}
</Button>
</Link>
</section>
Expand Down
28 changes: 0 additions & 28 deletions hooks/useAddContentCreatorMutation.tsx

This file was deleted.

28 changes: 28 additions & 0 deletions hooks/useMutation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useCallback, useState } from 'react';

export type Status = 'idle' | 'loading' | 'error' | 'success';

export function useMutation<Body>(mutation: (body: Body) => Promise<Response>) {
const [status, setStatus] = useState<{ readonly status: Status; readonly errorCode?: number }>({
status: 'idle',
});

const mutate = useCallback(
async (body: Body) => {
setStatus({ status: 'loading' });
try {
const response = await mutation(body);
if (response.ok) {
setStatus({ status: 'success' });
} else {
setStatus({ status: 'error', errorCode: response.status });
}
} catch (err) {
setStatus({ status: 'error' });
}
},
[mutation],
);

return { mutate, ...status } as const;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "polskifrontend",
"version": "3.5.0",
"version": "3.6.0",
"np": {
"branch": "main",
"releaseDraft": true
Expand Down Expand Up @@ -39,6 +39,8 @@
"@sentry/browser": "5.29.2",
"@sentry/integrations": "5.29.2",
"@sentry/node": "5.29.2",
"@sentry/react": "5.29.2",
"@sentry/tracing": "5.29.2",
"@sentry/webpack-plugin": "1.14.0",
"@zeit/next-source-maps": "0.0.4-canary.1",
"cheerio": "1.0.0-rc.5",
Expand Down
2 changes: 1 addition & 1 deletion pages/api/content-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default withAsync(
const url = new URL(req.body.contentURL).toString();

const contentCreator = await addContentCreator(url, req.body.email);
await sendNewCreatorNotification(contentCreator);
await sendNewCreatorNotification(contentCreator).catch(() => {});

return null;
}),
Expand Down
2 changes: 1 addition & 1 deletion utils/api/addContentCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type ContentCreatorReqBody = {
};

export const addContentCreator = (requestBody: ContentCreatorReqBody) => {
return fetch(`https://${process.env.NEXT_PUBLIC_URL as string}/api/content-creator`, {
return fetch(`/api/content-creator`, {
method: 'POST',
body: JSON.stringify(requestBody),
});
Expand Down
17 changes: 17 additions & 0 deletions utils/creator-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ArticlePageProps } from '../pages/artykuly/[slug]';

// Detect YouTube videos by the article URL
const ytRegex = /youtu(\.be|be\.com)\//;

// Detect podcasts by the anchor.fm in article URL (most popular hosting) or podcast name (common words like talk or podcast)
const podcastRegex = /(anchor\.fm\/|talk|podcast)/i;

export const detectContentGenre = (article: ArticlePageProps['article']) => {
if (ytRegex.test(article.href)) {
return 'youtube' as const;
} else if (podcastRegex.test(article.href) || podcastRegex.test(article.blog.name)) {
return 'podcast' as const;
} else {
return 'blog' as const;
}
};
6 changes: 6 additions & 0 deletions utils/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// https://github.com/vercel/next.js/blob/db329fe9b0e13a389a84cb98fd936e8a671ba8ec/examples/with-sentry/utils/sentry.js
import { RewriteFrames } from '@sentry/integrations';
import * as Sentry from '@sentry/node';
import { Integrations } from '@sentry/tracing';

export const initSentry = () => {
if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
Expand All @@ -21,13 +22,18 @@ export const initSentry = () => {
},
}),
);
integrations.push(new Sentry.Integrations.Http({ tracing: true }));
}
if (process.env.NEXT_IS_SERVER !== 'true') {
integrations.push(new Integrations.BrowserTracing());
}

Sentry.init({
enabled: process.env.NODE_ENV === 'production',
integrations,
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
release: process.env.NEXT_PUBLIC_COMMIT_SHA,
tracesSampleRate: 1.0,
});
}
};
3 changes: 3 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"regions": ["dub1"]
}
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,18 @@
lru_map "^0.3.3"
tslib "^1.9.3"

"@sentry/react@5.29.2":
version "5.29.2"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.29.2.tgz#e0e2055db6f9c7a3957630e726b23d6a0f2d12f2"
integrity sha512-Fvh4l6/wrnO3FWqte7lPUsuWE5o6t3FHwZqVINgCIabpwPMorvOVzm/gwG7uzhuCoyNTP28svR670sl4BnRuTg==
dependencies:
"@sentry/browser" "5.29.2"
"@sentry/minimal" "5.29.2"
"@sentry/types" "5.29.2"
"@sentry/utils" "5.29.2"
hoist-non-react-statics "^3.3.2"
tslib "^1.9.3"

"@sentry/tracing@5.29.2":
version "5.29.2"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47"
Expand Down

0 comments on commit 963b10e

Please sign in to comment.