Skip to content

Commit

Permalink
feat: use context to store and display urls history
Browse files Browse the repository at this point in the history
  • Loading branch information
abhijithvijayan committed Jul 21, 2020
1 parent be6b078 commit 9960668
Show file tree
Hide file tree
Showing 6 changed files with 508 additions and 245 deletions.
372 changes: 132 additions & 240 deletions source/History/History.tsx
Original file line number Diff line number Diff line change
@@ -1,251 +1,143 @@
import React from 'react';
import tw, {css, styled} from 'twin.macro';
import React, {useEffect, useState} from 'react';
import 'twin.macro';

import {
useShortenedLinks,
ShortenedLinksActionTypes,
} from '../contexts/shortened-links-context';
import {
HostProperties,
useExtensionSettings,
} from '../contexts/extension-settings-context';
import {
useRequestStatus,
RequestStatusActionTypes,
} from '../contexts/request-status-context';
import messageUtil from '../util/mesageUtil';
import {FETCH_URLS_HISTORY} from '../Background/constants';
import {getExtensionSettings} from '../util/settings';
import {
SuccessfulUrlsHistoryFetchProperties,
AuthRequestBodyProperties,
ApiErroredProperties,
ErrorStateProperties,
Kutt,
} from '../Background';
import {isValidUrl} from '../util/tabs';

import BodyWrapper from '../components/BodyWrapper';

const StyledTd = styled.td`
${tw`relative flex items-center px-0 py-4`}
`;

const StyledButton = styled.button`
${tw`flex items-center justify-center p-0 my-0 transition-all duration-200 ease-out border-none outline-none cursor-pointer`}
margin-right: 2px;
margin-left: 12px;
width: 26px;
height: 26px;
box-shadow: rgba(100, 100, 100, 0.1) 0px 2px 4px;
background-color: rgb(222, 222, 222);
border-width: initial;
border-color: initial;
border-image: initial;
border-radius: 100%;
&:hover {
transform: translateY(-3px);
}
img {
width: 12px;
height: 12px;
}
`;
import Loader from '../components/Loader';
import Header from '../Options/Header';
import Table from './Table';

const History: React.FC = () => {
const shortenedLinksDispatch = useShortenedLinks()[1];
const extensionSettingsDispatch = useExtensionSettings()[1];
const [requestStatusState, requestStatusDispatch] = useRequestStatus();
const [errored, setErrored] = useState<ErrorStateProperties>({
error: null,
message: '',
});

useEffect(() => {
async function getUrlsHistoryStats(): Promise<void> {
// ********************************* //
// **** GET EXTENSIONS SETTINGS **** //
// ********************************* //
const {settings = {}} = await getExtensionSettings();
const advancedSettings: boolean =
(settings?.advanced as boolean) || false;

const defaultHost: HostProperties =
(advancedSettings &&
(settings?.host as string) &&
isValidUrl(settings.host as string) && {
hostDomain: (settings.host as string)
.replace('http://', '')
.replace('https://', '')
.replace('www.', '')
.split(/[/?#]/)[0], // extract domain
hostUrl: (settings.host as string).endsWith('/')
? (settings.host as string).slice(0, -1)
: (settings.host as string), // slice `/` at the end
}) ||
Kutt;

// inject existing keys (if field doesn't exist, use default)
const defaultExtensionConfig = {
apikey: (settings?.apikey as string)?.trim() || '',
history: (settings?.history as boolean) || false,
advanced:
defaultHost.hostUrl.trim() !== Kutt.hostUrl && advancedSettings, // disable `advanced` if customhost is not set
host: defaultHost,
};

// extensionSettingsDispatch({
// type: ExtensionSettingsActionTypes.HYDRATE_EXTENSION_SETTINGS,
// payload: defaultExtensionConfig,
// });

// ****************************************************** //
// **************** FETCH URLS HISTORY ****************** //
// ****************************************************** //
const urlsHistoryFetchRequetBody: AuthRequestBodyProperties = {
apikey: defaultExtensionConfig.apikey,
hostUrl: defaultExtensionConfig.host.hostUrl,
};

// call api
const response:
| SuccessfulUrlsHistoryFetchProperties
| ApiErroredProperties = await messageUtil.send(
FETCH_URLS_HISTORY,
urlsHistoryFetchRequetBody
);

if (!response.error) {
setErrored({error: false, message: 'Fetch successful'});

shortenedLinksDispatch({
type: ShortenedLinksActionTypes.HYDRATE_SHORTENED_LINKS,
payload: {
items: response.data.data,
total: response.data.total,
},
});
} else {
setErrored({error: true, message: response.message});
}

requestStatusDispatch({
type: RequestStatusActionTypes.SET_LOADING,
payload: false,
});
}

getUrlsHistoryStats();
}, [
extensionSettingsDispatch,
requestStatusDispatch,
shortenedLinksDispatch,
]);

return (
<BodyWrapper>
<div id="history" tw="h-screen flex justify-center px-6 py-8 bg-gray-200">
<div
css={[
tw` flex flex-col items-center w-full min-h-screen`,

css`
flex: 0 0 auto;
`,
]}
>
<div
css={[
tw`flex flex-col mx-0 mt-10 mb-32`,

css`
width: 1200px;
max-width: 95%;
`,
]}
>
<div tw="flex items-center justify-center">
<h2
css={[
tw`mx-0 text-2xl`,

css`
margin-right: 0.8rem;
`,
]}
>
Recent shortened links. (last 15 results)
</h2>
<div>
<Header />

{/* eslint-disable-next-line no-nested-ternary */}
{!requestStatusState.loading ? (
!errored.error ? (
<Table />
) : (
<h2>{errored.message}</h2>
)
) : (
<div tw="h-10">
<Loader />
</div>
<table
css={[
tw`flex flex-col flex-auto bg-white`,

css`
border-radius: 12px;
box-shadow: rgba(50, 50, 50, 0.2) 0px 6px 30px;
`,
]}
>
<thead
css={[
tw`flex flex-col flex-auto`,

css`
background-color: rgb(241, 241, 241);
border-top-right-radius: 12px;
border-top-left-radius: 12px;
`,
]}
>
<tr
css={[
tw`flex justify-between flex-auto px-6 py-0`,

css`
border-bottom: 1px solid rgb(234, 234, 234);
`,
]}
>
<th
css={[
tw`relative flex items-center justify-start px-0 py-4 text-base leading-normal`,

css`
flex: 2 2 0px;
`,
]}
>
Original URL
</th>
<th
css={[
tw`relative flex items-center justify-start px-0 py-4 text-base leading-normal`,

css`
flex: 1 1 0px;
`,
]}
>
Short URL
</th>
</tr>
</thead>
<tbody tw="flex flex-col flex-auto">
<tr
css={[
tw`flex justify-between flex-auto px-6 py-0`,

css`
border-bottom: 1px solid rgb(234, 234, 234);
`,
]}
>
<StyledTd
css={[
tw`relative overflow-hidden whitespace-no-wrap`,

css`
flex: 2 2 0px;
&::after {
content: '';
position: absolute;
right: 0px;
top: 0px;
height: 100%;
width: 56px;
background: linear-gradient(
to left,
white,
white,
transparent
);
}
`,
]}
>
<a
css={[
tw`hover:border-black text-base leading-normal no-underline transition-all duration-200 ease-out border border-transparent border-dotted`,

css`
color: rgb(33, 150, 243);
`,
]}
href="%longLink%"
target="_blank"
rel="noopener noreferrer nofollow"
>
%longLink%
</a>
</StyledTd>

<StyledTd
css={[
tw`relative overflow-hidden whitespace-no-wrap`,

css`
flex: 1 1 23px;
&::after {
content: '';
position: absolute;
right: 0px;
top: 0px;
height: 100%;
width: 56px;
background: linear-gradient(
to left,
white,
white,
transparent
);
}
`,
]}
>
<div
css={[
tw`absolute top-0 left-0 text-xs text-green-900`,

css`
font-size: 11px;
`,
]}
>
Copied to clipboard!
</div>
<div tw="flex items-center">
<a
css={[
tw`hover:border-black text-base leading-normal no-underline transition-all duration-200 ease-out border border-transparent border-dotted`,

css`
color: rgb(33, 150, 243);
`,
]}
href="%shortLink%"
target="_blank"
rel="noopener noreferrer nofollow"
>
%shortLink%
</a>
</div>
</StyledTd>

<StyledTd>
<div tw="flex items-center justify-end">
<StyledButton type="button" title="Copy">
<img
tw="select-none"
src="assets/copy.svg"
alt="Copy"
/>
</StyledButton>
<StyledButton type="button" title="QR Code">
<img
tw="select-none"
src="assets/qrcode.svg"
alt="QR Code"
/>
</StyledButton>
</div>
</StyledTd>
</tr>
</tbody>
</table>
</div>
)}
</div>
</div>
</BodyWrapper>
Expand Down
Loading

0 comments on commit 9960668

Please sign in to comment.