Skip to content

Commit

Permalink
improve page layout and transition
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicarrojado committed Aug 15, 2023
1 parent fd2a43c commit c5d831e
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 36 deletions.
17 changes: 13 additions & 4 deletions components/lastAvailableSlotsInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useEffect } from 'react';
import cn from 'classnames';
import Alert from './alert';
import { useGetLastAvailableSlotsDate } from '@/lib/api-hooks';
import { FetchState } from '@/lib/types';

export default function LastAvailableSlotsInfo() {
const [lastAvailableSlotsDate, getLastAvailableSlotsDate] =
const [fetchState, lastAvailableSlotsDate, getLastAvailableSlotsDate] =
useGetLastAvailableSlotsDate();

useEffect(() => {
Expand All @@ -12,9 +14,16 @@ export default function LastAvailableSlotsInfo() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
return fetchState !== FetchState.ERROR ? (
<Alert>
Last available slots were spotted on {lastAvailableSlotsDate}.
<div
className={cn(
'transition-opacity duration-300',
fetchState !== FetchState.SUCCESS ? 'opacity-0' : 'opacity-100'
)}
>
Last available slots were spotted on {lastAvailableSlotsDate}.
</div>
</Alert>
);
) : null;
}
10 changes: 0 additions & 10 deletions components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,11 @@ export default function Layout({ children }: Props) {
<SvgGraphs />
</div>
<main className="mx-auto max-w-xl">
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_HEADER}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="mb-8"
/>
<PageTitle>
Embassy of Japan in Singapore Visa Appointment Notification Service
for Visa (Tourism) applications
</PageTitle>
<PageBody>{children}</PageBody>
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_FOOTER}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="mt-8"
/>
</main>
<Footer className="mt-10" />
</div>
Expand Down
11 changes: 10 additions & 1 deletion components/subscribeForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Link from 'next/link';
import React, { useState } from 'react';
import cn from 'classnames';
import { useSubmitSubscribeRequest } from '@/lib/api-hooks';
import { useIsCookieBannerClosed } from '@/lib/custom-hooks';
import { trackEvent } from '@/lib/google-analytics';
import { FetchState, GoogleAnalyticsEvent, Route } from '@/lib/types';
import Button from './button';
Expand All @@ -13,6 +15,7 @@ import Input from './input';
export default function SubscribeForm() {
const submitText = 'Subscribe Now';
const [fetchState, submitSubscriptionRequest] = useSubmitSubscribeRequest();
const isCookieBannerClosed = useIsCookieBannerClosed();
const [submittedEmail, setSubmittedEmail] = useState('');
const isLoading = fetchState === FetchState.LOADING;
const formOnSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
Expand All @@ -31,7 +34,13 @@ export default function SubscribeForm() {
};

return (
<Form className="sticky bottom-6" onSubmit={formOnSubmit}>
<Form
className={cn(
'sticky transition-all duration-500 delay-700',
isCookieBannerClosed ? 'bottom-6' : 'bottom-32 xl:bottom-6'
)}
onSubmit={formOnSubmit}
>
<FormBody>
{fetchState !== FetchState.SUCCESS ? (
<>
Expand Down
40 changes: 24 additions & 16 deletions lib/api-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,35 +87,43 @@ export function useUnsubscribe() {
}

export function useGetLastAvailableSlotsDate() {
const [fetchState, setFetchState] = useState(FetchState.DEFAULT);
const [lastAvailableSlotsDate, setLastAvailableSlotsDate] = useState(
'----------------------'
);
const getLastAvailableSlotsDate = async (): Promise<boolean> => {
const getLastAvailableSlotsDate = async () => {
try {
setFetchState(FetchState.LOADING);

const axios = (await import('axios')).default;
const res = await axios.get(
`${API_URL}${ApiEndpoint.LAST_AVAILABLE_SLOTS_INFO}`
);

if (res.data && res.data.updatedAt) {
const date = new Date(res.data.updatedAt);
const formattedDate = new Intl.DateTimeFormat('en-GB', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true,
}).format(date);

setLastAvailableSlotsDate(formattedDate);
if (!res.data || !res.data.updatedAt) {
throw new Error('No data');
}

return true;
const date = new Date(res.data.updatedAt);
const formattedDate = new Intl.DateTimeFormat('en-GB', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true,
}).format(date);

setLastAvailableSlotsDate(formattedDate);
setFetchState(FetchState.SUCCESS);
} catch (err) {
return false;
setFetchState(FetchState.ERROR);
}
};

return [lastAvailableSlotsDate, getLastAvailableSlotsDate] as const;
return [
fetchState,
lastAvailableSlotsDate,
getLastAvailableSlotsDate,
] as const;
}
2 changes: 2 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export const MAIN_URL = `${MAIN_ORIGIN}${MAIN_PATH}`;
export const API_URL = 'https://api.dominicarrojado.com';

export const GOOGLE_ADSENSE_CLIENT_ID = 'ca-pub-3632473845121107';

export const COOKIE_BANNER_IS_CLOSED_KEY = 'isCookieBannerClosed';
16 changes: 16 additions & 0 deletions lib/custom-hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useEffect, useState } from 'react';
import { checkIsLocalhost } from './location';
import { COOKIE_BANNER_IS_CLOSED_KEY } from './constants';

export function useIsCookieBannerClosed() {
const [isCookieBannerClosed, setIsCookieBannerClosed] = useState(true);

useEffect(() => {
setIsCookieBannerClosed(
checkIsLocalhost() ||
localStorage.getItem(COOKIE_BANNER_IS_CLOSED_KEY) === '1'
);
}, []);

return isCookieBannerClosed;
}
2 changes: 1 addition & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export enum GoogleAnalyticsEvent {
}

export enum GoogleAdSenseUnitSlot {
PROJECT_HEADER = '2299922139',
PROJECT_BODY = '2574409710',
PROJECT_FOOTER = '3221836158',
}

Expand Down
17 changes: 16 additions & 1 deletion pages/index.page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ExternalUrl } from '@/lib/types';
import SubscribeForm from '@/components/subscribeForm';
import LastAvailableSlotsInfo from '@/components/lastAvailableSlotsInfo';
import AdUnit from '@/components/adUnit';
import {
ExternalUrl,
GoogleAdSenseUnitFormat,
GoogleAdSenseUnitSlot,
} from '@/lib/types';

export default function Home() {
return (
Expand All @@ -19,6 +24,11 @@ export default function Home() {
visa applications, and sends out email notifications to my subscribers
the moment a slot becomes available.
</p>
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_BODY}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="my-4"
/>
<p>
I created this service because I had the same problem when applying for
my Japan tourist visa. The embassy had turned off the waitlist feature,
Expand Down Expand Up @@ -53,6 +63,11 @@ export default function Home() {
. <br />
Thank you!
</p>
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_FOOTER}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="mt-8"
/>
</>
);
}
13 changes: 12 additions & 1 deletion pages/subscribe.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import React, { useEffect } from 'react';
import { NextSeo } from 'next-seo';
import ButtonLink from '@/components/buttonLink';
import PageSubtitle from '@/components/pageSubtitle';
import AdUnit from '@/components/adUnit';
import { useVerifySubscription } from '@/lib/api-hooks';
import { FetchState, Route } from '@/lib/types';
import {
FetchState,
GoogleAdSenseUnitFormat,
GoogleAdSenseUnitSlot,
Route,
} from '@/lib/types';

export default function Subscribe() {
const [fetchState, verifySubscription] = useVerifySubscription();
Expand Down Expand Up @@ -68,6 +74,11 @@ export default function Subscribe() {
</p>
</>
)}
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_FOOTER}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="mt-8"
/>
</>
);
}
14 changes: 12 additions & 2 deletions pages/unsubscribe.page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { NextSeo } from 'next-seo';
import UnsubscribeForm from '@/components/unsubscribeForm';
import { getMetaTitle, getRouteCanonical } from '@/lib/meta';
import { Route } from '@/lib/types';
import UnsubscribeForm from '@/components/unsubscribeForm';
import AdUnit from '@/components/adUnit';
import {
GoogleAdSenseUnitFormat,
GoogleAdSenseUnitSlot,
Route,
} from '@/lib/types';

export default function Unsubscribe() {
const metaUrl = getRouteCanonical(Route.UNSUBSCRIBE);
Expand All @@ -19,6 +24,11 @@ export default function Unsubscribe() {
below and confirm. Thank you for your interest in my content.
</p>
<UnsubscribeForm />
<AdUnit
adSlot={GoogleAdSenseUnitSlot.PROJECT_FOOTER}
adFormat={GoogleAdSenseUnitFormat.FLUID}
className="mt-8"
/>
</>
);
}

0 comments on commit c5d831e

Please sign in to comment.