Skip to content

Commit

Permalink
Merge pull request #144 from thanhdanh27600/staging
Browse files Browse the repository at this point in the history
Staging
  • Loading branch information
thanhdanh27600 authored Aug 31, 2023
2 parents 7bb4a81 + 1cbe3c2 commit 8f224ce
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/components/atoms/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Loading } from './Loading';
type ButtonVariants = 'filled' | 'outlined';

export interface ButtonProps extends DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
text?: string;
text?: string | React.ReactNode;
TextClassname?: ClassValue;
variant?: ButtonVariants;
loading?: boolean;
Expand Down
32 changes: 15 additions & 17 deletions src/components/atoms/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,21 @@ export const Tabs = (props: Props) => {
{tabs.map((tab) => {
const selected = selectedKey === tab.key;
return (
<>
<li className="mr-2" key={`tab-${tab.key}`}>
<a
href={`#${tab.key}`}
onClick={handleClick(tab)}
className={clsx(
'group inline-flex items-center justify-center rounded-t-lg border-b-2 border-transparent p-4',
!tab.disabled && !selected && 'hover:border-gray-300 hover:text-gray-600',
!tab.disabled &&
selected &&
'border-cyan-500 text-cyan-500 hover:border-cyan-400 hover:text-cyan-400',
tab.disabled && 'cursor-not-allowed text-gray-400',
)}>
<div className={clsx()}>{tab.content}</div>
</a>
</li>
</>
<li className="mr-2" key={`tab-${tab.key}`}>
<a
href={`#${tab.key}`}
onClick={handleClick(tab)}
className={clsx(
'group inline-flex items-center justify-center rounded-t-lg border-b-2 border-transparent p-4',
!tab.disabled && !selected && 'hover:border-gray-300 hover:text-gray-600',
!tab.disabled &&
selected &&
'border-cyan-500 text-cyan-500 hover:border-cyan-400 hover:text-cyan-400',
tab.disabled && 'cursor-not-allowed text-gray-400',
)}>
<div className={clsx()}>{tab.content}</div>
</a>
</li>
);
})}
</ul>
Expand Down
14 changes: 5 additions & 9 deletions src/components/gadgets/FacebookPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { UrlShortenerHistory } from '@prisma/client';
import { CldImage } from 'next-cloudinary';
import { BASE_URL, PLATFORM_AUTH, brandUrlShortDomain } from 'types/constants';
import { BASE_URL_OG, brandUrlShortDomain } from 'types/constants';

import { encrypt } from 'utils/crypto';
import { encodeToBase64 } from 'utils/crypto';
import { useTrans } from 'utils/i18next';

export const FacebookPreview = ({ hash, ogTitle, ogDomain, ogDescription, ogImgSrc }: Partial<UrlShortenerHistory>) => {
const { t, locale } = useTrans();
const title = ogTitle || t('ogTitle', { hash: hash || 'XXX' });
let encodeTitle = '';
if (PLATFORM_AUTH) {
encodeTitle = encrypt(title);
}
const encodeTitle = encodeToBase64(title);

return (
<div className="w-fit">
<div className="ml-auto w-[315px] bg-gray-100/75 sm:w-[420px]">
Expand All @@ -29,9 +27,7 @@ export const FacebookPreview = ({ hash, ogTitle, ogDomain, ogDescription, ogImgS
className="relative origin-top-left scale-[0.2625] sm:scale-[0.35]"
width={1200}
height={630}
src={`${BASE_URL}/api/og?hash=${hash}&title=${encodeURIComponent(
encodeTitle,
)}&locale=${locale}&preview=true`}
src={`${BASE_URL_OG}/api/og?hash=${hash}&title=${encodeTitle}&locale=${locale}&preview=true`}
/>
)}
</div>
Expand Down
14 changes: 5 additions & 9 deletions src/components/gadgets/TwitterPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { UrlShortenerHistory } from '@prisma/client';
import { CldImage } from 'next-cloudinary';
import { BASE_URL, PLATFORM_AUTH, brandUrlShortDomain } from 'types/constants';
import { encrypt } from 'utils/crypto';
import { BASE_URL_OG, brandUrlShortDomain } from 'types/constants';
import { encodeToBase64 } from 'utils/crypto';
import { useTrans } from 'utils/i18next';

export const TwitterPreview = ({ hash, ogTitle, ogDomain, ogDescription, ogImgSrc }: Partial<UrlShortenerHistory>) => {
const { t, locale } = useTrans();
const title = ogTitle || t('ogTitle', { hash: hash || 'XXX' });
let encodeTitle = '';
if (PLATFORM_AUTH) {
encodeTitle = encrypt(title);
}
const encodeTitle = encodeToBase64(title);

return (
<div className="w-fit">
<div className="ml-auto w-[315px] bg-gray-100/75 sm:w-[420px]">
Expand All @@ -28,9 +26,7 @@ export const TwitterPreview = ({ hash, ogTitle, ogDomain, ogDescription, ogImgSr
className="relative origin-top-left scale-[0.2625] sm:scale-[0.35]"
width={1200}
height={630}
src={`${BASE_URL}/api/og?hash=${hash}&title=${encodeURIComponent(
encodeTitle,
)}&locale=${locale}&preview=true`}
src={`${BASE_URL_OG}/api/og?hash=${hash}&title=${encodeTitle}&locale=${locale}&preview=true`}
/>
)}
</div>
Expand Down
13 changes: 8 additions & 5 deletions src/components/sections/URLShortenerResult.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Facebook, Linkedin, Twitter } from '@styled-icons/feather';
import { getQr } from 'api/requests';
import { useBearStore } from 'bear';
import clsx from 'clsx';
Expand Down Expand Up @@ -110,28 +111,30 @@ export const URLShortenerResult = ({ setCopied, copied }: Props) => {
<div className="flex flex-col items-center gap-2 sm:flex-row">
<a href={`http://www.facebook.com/sharer.php?u=${shortenUrl}`} target="_blank">
<Button
text={t('shareFacebook')}
text={<Facebook className="h-6 w-6 fill-white" />}
className="h-fit !bg-[#3b5998] !bg-none hover:!bg-[#4c70ba]"
TextClassname="!text-sm !p-0"
/>
</a>
<a href={`https://twitter.com/share?url=${shortenUrl}`} target="_blank">
<Button
text={t('shareTwitter')}
text={<Twitter className="h-6 w-6 fill-white" />}
className="h-fit !bg-[#409dd5] !bg-none hover:!bg-[#6ab2de]"
TextClassname="!text-sm !p-0"
/>
</a>
<a href={`https://www.linkedin.com/shareArticle?mini=true&url=${shortenUrl}`} target="_blank">
<Button
text={t('shareLinkedIn')}
text={<Linkedin className="h-6 w-6 fill-white" />}
className="h-fit !bg-[#0077b5] !bg-none hover:!bg-[#007ebf]"
TextClassname="!text-sm !p-0"
/>
</a>
{query.data?.qr && (
<div className="mt-1 flex flex-col items-center gap-2">
<Image src={query.data?.qr} alt="QR-Code" width={84} height={84} />
<div className="flex flex-col items-center gap-2">
<div className="border border-cyan-500 p-1">
<Image src={query.data?.qr} alt="QR-Code" width={84} height={84} />
</div>
<a href={query.data?.qr} download={`QR-${shortenUrl.replace(`${BASE_URL_SHORT}/`, '')}`}>
<Button
text={t('downloadQR')}
Expand Down
13 changes: 5 additions & 8 deletions src/pages/[...hash].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import Head from 'next/head';
import { useEffect } from 'react';
import { useMutation } from 'react-query';
import requestIp from 'request-ip';
import { BASE_URL, brandUrlShortDomain, isProduction, PLATFORM_AUTH, Window } from 'types/constants';
import { BASE_URL_OG, brandUrlShortDomain, isProduction, Window } from 'types/constants';
import { Locale } from 'types/locale';
import { MIXPANEL_EVENT, MIXPANEL_STATUS } from 'types/utils';
import { encrypt } from 'utils/crypto';
import { encodeToBase64 } from 'utils/crypto';
import { useTrans } from 'utils/i18next';
import { QueryKey } from 'utils/requests';

Expand Down Expand Up @@ -80,10 +80,7 @@ const ForwardURL = ({ history, hash, ip, error, redirect }: Props) => {
location.replace(`${url.includes('http') ? '' : '//'}${url}`);
}, [forwardUrl]);

let encodeTitle = '';
if (PLATFORM_AUTH) {
encodeTitle = encrypt(ogTitle);
}
const encodeTitle = encodeToBase64(ogTitle);

return (
<>
Expand All @@ -104,14 +101,14 @@ const ForwardURL = ({ history, hash, ip, error, redirect }: Props) => {
<>
<meta
property="og:image"
content={`${BASE_URL}/api/og?hash=${hash}&title=${encodeURIComponent(encodeTitle)}&locale=${locale}`}
content={`${BASE_URL_OG}/api/og?hash=${hash}&title=${encodeTitle}&locale=${locale}`}
/>
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="627" />
<meta property="og:image:alt" content={t('ogDescription')} />
<meta
property="twitter:image"
content={`${BASE_URL}/api/og?hash=${hash}&title=${encodeURIComponent(encodeTitle)}&locale=${locale}`}
content={`${BASE_URL_OG}/api/og?hash=${hash}&title=${encodeTitle}&locale=${locale}`}
/>
<meta name="twitter:image:alt" content={t('ogDescription')}></meta>
<meta property="twitter:card" content="summary_large_image" />
Expand Down
3 changes: 0 additions & 3 deletions src/pages/api/og.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/types/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const baseUrl = (useShortDomain: boolean = false) => {
};
export const BASE_URL = baseUrl();
export const BASE_URL_SHORT = baseUrl(true);
export const BASE_URL_OG = isProduction ? 'https://og.clickdi.top' : 'http://localhost:7071';
export const REDIS_KEY = {
HASH_LIMIT: 'limit',
HASH_HISTORY_BY_ID: 'hHistory',
Expand Down
21 changes: 21 additions & 0 deletions src/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,24 @@ export const encryptS = (word: string) => {
}
return encrypted;
};

export function encodeToBase64(input: string): string {
const buffer = Buffer.from(input);
return buffer.toString('base64');
}

export function decodeFromBase64(input: string) {
const buffer = Buffer.from(input, 'base64');
return buffer.toString('utf-8');
}

export function isValidBase64(input: string) {
try {
const buffer = Buffer.from(input, 'base64');
const decodedString = buffer.toString('utf-8');
const reencodedString = Buffer.from(decodedString).toString('base64');
return reencodedString === input;
} catch (error) {
return false;
}
}

0 comments on commit 8f224ce

Please sign in to comment.