Skip to content

Commit

Permalink
Add solution: SecureZone; use HashRouter
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Tai committed Nov 15, 2024
1 parent 8fefc6a commit aa19efc
Show file tree
Hide file tree
Showing 18 changed files with 667 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ html/
stats.html

# Secrets
.env
.env.*
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
"@ant-design/colors" : "^7.1.0",
"@ant-design/icons" : "^5.5.1",
"@contentful/rich-text-html-renderer" : "^17.0.0",
"antd" : "^5.21.6",
"antd" : "^5.22.1",
"contentful" : "^11.2.1",
"i18next" : "^23.16.5",
"i18next-browser-languagedetector" : "^8.0.0",
"mdb-react-ui-kit" : "^9.0.0",
"react" : "^18.3.1",
"react-dom" : "^18.3.1",
"react-i18next" : "^15.1.1",
Expand All @@ -44,7 +45,7 @@
"@types/node" : "^22.9.0",
"@types/react" : "^18.3.12",
"@types/react-dom" : "^18.3.1",
"@typescript-eslint/parser" : "^8.13.0",
"@typescript-eslint/parser" : "^8.14.0",
"@vitejs/plugin-react-swc" : "^3.7.1",
"eslint" : "^9.14.0",
"eslint-plugin-import" : "^2.31.0",
Expand All @@ -56,8 +57,8 @@
"prop-types" : "^15.8.1",
"rollup-plugin-visualizer" : "^5.12.0",
"typescript" : "^5.6.3",
"typescript-eslint" : "^8.13.0",
"vite" : "^5.4.10"
"typescript-eslint" : "^8.14.0",
"vite" : "^5.4.11"
},
"engines" : {
"node" : ">=20",
Expand Down
Binary file added public/kutan-ural-MZPwImQUDM0-unsplash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/margo-brodowicz-nzAZxPyhZ2g-unsplash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/matt-jones-xpDHTc-pkog-unsplash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { createBrowserRouter, RouterProvider, } from 'react-router-dom';
import { createHashRouter, RouterProvider, } from 'react-router-dom';

import { AgreementPage, HomePage, } from './pages';
import { AgreementPage, HomePage, SecureZone, } from './pages';

const router = createBrowserRouter([
const router = createHashRouter([
{
path : '/',
Component : HomePage,
},
{
path : '/products/securezone',
Component : SecureZone,
},
{
path : '/agreements',
children : [
Expand All @@ -17,4 +21,5 @@ const router = createBrowserRouter([
],
},
]);

export const App = () => <RouterProvider router={router} />;
4 changes: 2 additions & 2 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ export const Footer = () => {

return (
<Button
size='small'
type='text'
style={{
color : '#fff',
}}
size='small'
type='text'
onClick={handleClick}>
{children}
</Button>
Expand Down
26 changes: 16 additions & 10 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Anchor, Button, Layout, Typography, } from 'antd';
import { useEffect, useState, } from 'react';
import { type MouseEvent, type ReactNode, useEffect, useState, } from 'react';
import { useNavigate, } from 'react-router-dom';
import { useTranslation, } from 'react-i18next';
import { useMediaQuery, } from 'usehooks-ts';
Expand All @@ -19,16 +19,21 @@ export const Header = ({

const { t, } = useTranslation();

const handleScroll = () => {
if (window.scrollY > 0) {
setIsTop(false);
} else {
setIsTop(true);
}
};
const handleScroll = () => setIsTop(window.scrollY === 0);

const handleClick = () => navigate('/');

const handleHashLinkClick = (e : MouseEvent<HTMLElement>, link : {
title : ReactNode,
href : string,
}) => {
e.preventDefault();

document.getElementById(link.href)!.scrollIntoView({
behavior : 'smooth',
});
};

useEffect(() => {
window.addEventListener('scroll', handleScroll);

Expand Down Expand Up @@ -80,7 +85,7 @@ export const Header = ({
'solutions',
].map(key => ({
key,
href : `#${key}`,
href : `${key}`,
title : (
<Typography.Link style={{
fontSize : '1rem',
Expand All @@ -89,7 +94,8 @@ export const Header = ({
{t(`menu.${key}`)}
</Typography.Link>
),
}))} />
}))}
onClick={handleHashLinkClick} />
)}
</div>
</Layout.Header>
Expand Down
28 changes: 28 additions & 0 deletions src/components/InfoText/InfoText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Tooltip, Typography, } from 'antd';
import type { FC, } from 'react';

import { InfoTextProps, } from './InfoText.types';

const InfoText : FC<InfoTextProps> = ({
title,
children,
...props
}) => {
const { style, ...rest } = props;

return (
<Tooltip title={title}>
<Typography.Text
style={{
textDecorationLine : 'underline',
textDecorationStyle : 'dashed',
...(style ?? []),
}}
{...rest}>
{children}
</Typography.Text>
</Tooltip>
);
};

export default InfoText;
7 changes: 7 additions & 0 deletions src/components/InfoText/InfoText.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { ReactNode, } from 'react';

export interface InfoTextProps {
title? : string,
children? : ReactNode,
[ key : string ] : any,
}
1 change: 1 addition & 0 deletions src/components/InfoText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as InfoText, } from './InfoText';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { Footer, } from './Footer';
export { Header, } from './Header';
export { InfoText, } from './InfoText';
100 changes: 70 additions & 30 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,72 @@
{
"app.name" : "GeekyLifeHacks",
"menu.home" : "Home",
"menu.about" : "About",
"menu.solutions" : "Solutions",
"sections.home.title" : "Everyday Solutions\nExtraordinary Savings",
"sections.home.subtitle" : "At GeekyLifeHacks, we offer affordable, practical and cost-effective solutions, From our easy-to-follow guides and expert advice to professional-grade apps, we simplify your life.",
"sections.about.title" : "We've got what you need!",
"sections.about.subtitle" : "From weather alerts to AI-powered security features and automated software installation scripts, our aim is to provide accessible and practical solutions to meet your unique needs.",
"sections.solutions.title" : "At your service",
"sections.solutions.0.caption" : "Innovative solutions",
"sections.solutions.0.description" : "Leading the future with groundbreaking technologies",
"sections.solutions.1.caption" : "Inspiring ideas",
"sections.solutions.1.description" : "Igniting creativity and fueling innovation",
"sections.solutions.2.caption" : "Honest approach",
"sections.solutions.2.description" : "Building trust through transparency and integrity",
"sections.solutions.3.caption" : "Passionate team",
"sections.solutions.3.description" : "Driven by a deep love for what we do",
"sections.products.0.caption" : "SecureZone",
"sections.products.0.description" : "A powerful security solution that protects your home",
"sections.products.1.caption" : "WeatherWatch",
"sections.products.1.description" : "Stay informed with real-time weather updates",
"sections.products.2.caption" : "MacBrewer",
"sections.products.2.description" : "The easiest way to install software on your Mac",
"footer.copyright" : "Copyright © {{year}} {{appName}}",
"footer.terms_and_conditions" : "Terms and Conditions",
"footer.privacy_policy" : "Privacy Policy",
"footer.acceptable_use_policy" : "Acceptable Use Policy",
"footer.disclaimer" : "Disclaimer",
"footer.return_policy" : "Return Policy",
"tags.coming_soon" : "Coming Soon"
"app.name" : "GeekyLifeHacks",
"menu.home" : "Home",
"menu.about" : "About",
"menu.solutions" : "Solutions",
"sections.home.title" : "Everyday Solutions\nExtraordinary Savings",
"sections.home.subtitle" : "At GeekyLifeHacks, we offer affordable, practical and cost-effective solutions, From our easy-to-follow guides and expert advice to professional-grade apps, we simplify your life.",
"sections.about.title" : "We've got what you need!",
"sections.about.subtitle" : "From weather alerts to AI-powered security features and automated software installation scripts, our aim is to provide accessible and practical solutions to meet your unique needs.",
"sections.solutions.title" : "At your service",
"sections.solutions.0.caption" : "Innovative solutions",
"sections.solutions.0.description" : "Leading the future with groundbreaking technologies",
"sections.solutions.1.caption" : "Inspiring ideas",
"sections.solutions.1.description" : "Igniting creativity and fueling innovation",
"sections.solutions.2.caption" : "Honest approach",
"sections.solutions.2.description" : "Building trust through transparency and integrity",
"sections.solutions.3.caption" : "Passionate team",
"sections.solutions.3.description" : "Driven by a deep love for what we do",
"sections.products.0.caption" : "SecureZone",
"sections.products.0.description" : "A powerful security solution that protects your home",
"sections.products.0.title" : "Protect you home. Your way.",
"sections.products.0.subtitle" : "Advanced intrusion detection solution that prioritises privacy by processing video locally, without sending data to the cloud.",
"sections.products.0.tagline.0" : "Your Privacy, Protected.",
"sections.products.0.summary.0" : "Safeguard your home without compromising your privacy. Our AI-powered security solution operates locally, ensuring your data remains secure on your home network.",
"sections.products.0.tagline.1" : "Big Security, Small Price Tag.",
"sections.products.0.summary.1" : "Experience professional-grade security without the premium cost. Our solution offers robust protection for your home at an affordable price.",
"sections.products.0.tagline.2" : "Smart Security, Simple Setup.",
"sections.products.0.summary.2" : "Easy to install and manage, our intelligent security solution offers powerful protection without the hassle.",
"sections.products.1.caption" : "WeatherWatch",
"sections.products.1.description" : "Stay informed with real-time weather updates",
"sections.products.2.caption" : "MacBrewer",
"sections.products.2.description" : "The easiest way to install software on your Mac",
"label.upgrade.title" : "Compare features across plans",
"label.upgrade.plans" : [
"Basic",
"Standard",
"Premier"
],
"label.upgrade.plans.0.description" : "A Basic Plan subscription\nallows 24/7 monitoring of\nup to 2 IP camera video streams",
"label.upgrade.plans.1.description" : "A Standard Plan subscription\nallows 24/7 monitoring of\nup to 5 IP camera video\nstreams and support rich notifications",
"label.upgrade.plans.2.description" : "A Premier Plan subscription\nallows 24/7 monitoring of\nup to 15 IP camera video\nstreams, support rich notifications\nand record videos even before\na detection is triggered",
"label.upgrade.plans.price" : "Monthly subscription",
"label.upgrade.plans.0.price" : "£2.99",
"label.upgrade.plans.1.price" : "£5.49",
"label.upgrade.plans.2.price" : "£12.49",
"label.upgrade.running_monitors" : "Running monitors",
"label.upgrade.intrusion_trigger" : "24/7 moving object intrusion trigger",
"label.upgrade.synology_integration" : "Integrated with Synology NAS",
"label.upgrade.snapshot_capture" : "Snapshot capture",
"label.upgrade.snapshot_capture_tooltip" : "See an image snapshot what was happening during moving object recognition events",
"label.upgrade.video_capture" : "Video capture",
"label.upgrade.video_capture_tooltip" : "See a video of what was happening during moving object recognition events",
"label.upgrade.video_capture_option_1" : "10 seconds",
"label.upgrade.video_capture_option_2" : "60 seconds\n(with 30 seconds before\nand after the event)",
"label.upgrade.rich_notifications" : "Rich notifications",
"label.upgrade.rich_notifications_tooltip" : "Rich notifications include a photo preview that let you see exactly what triggered an event",
"label.upgrade.customer_support" : "Customer support",
"label.upgrade.customer_support_options" : [
"Community forum",
"Community forum",
"Live chat"
],
"footer.copyright" : "Copyright © {{year}} {{appName}}",
"footer.terms_and_conditions" : "Terms and Conditions",
"footer.privacy_policy" : "Privacy Policy",
"footer.acceptable_use_policy" : "Acceptable Use Policy",
"footer.disclaimer" : "Disclaimer",
"footer.return_policy" : "Return Policy",
"tags.coming_soon" : "Coming Soon",
"actions.find_out_more" : "Find out more",
"actions.download" : "Download"
}
3 changes: 2 additions & 1 deletion src/pages/Agreement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { documentToHtmlString, } from '@contentful/rich-text-html-renderer';
import { Layout, Typography, } from 'antd';
import { createClient, } from 'contentful';
import { useEffect, useState, } from 'react';
import { useParams, } from 'react-router-dom';
import { ScrollRestoration, useParams, } from 'react-router-dom';
import { useMediaQuery, } from 'usehooks-ts';

import { Footer, Header, } from '../components';
Expand Down Expand Up @@ -45,6 +45,7 @@ export const AgreementPage = () => {
<Layout>
<Header />
<Layout.Content>
<ScrollRestoration />
<section style={{
display : 'flex',
flexDirection : 'column',
Expand Down
Loading

0 comments on commit aa19efc

Please sign in to comment.