Skip to content

Commit

Permalink
Merge pull request #48 from ric-v/main
Browse files Browse the repository at this point in the history
added timewas feature
  • Loading branch information
ric-v authored Jul 14, 2022
2 parents fa0a5d4 + dcb05a0 commit 5d7e049
Show file tree
Hide file tree
Showing 13 changed files with 471 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ yarn-error.log*
*.tsbuildinfo
pages/api/timezone.ts
pages/api/tz.tsv
.vscode/
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ The `pages/api` directory is mapped to `/api/*`. Files in this directory are tre
## Features

- [x] Display current time in local timezone
- [x] Search other timezones by code or timezone name
- [x] Add selected timestamps to homepage
- [x] Add timezone to history
- [x] Modify date time formatter with custom / templates
- [x] Toggle view for smaller / bigger cards
- [x] Search other timezones by code or timezone name, add or remove them from the dashboard
- [x] Change UI layout from small / large tiles
- [x] Modify the date format with custom formatter support
- [x] Display the time then based on input for different timezones under `the time was`

## Technologies Used

Expand Down
25 changes: 22 additions & 3 deletions components/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { RiCloseFill } from 'react-icons/ri';
import tz from 'timezone/loaded';

import getCurrentTime, { Timezones } from '../functions/timeNow';
import { store } from '../store/store';
Expand All @@ -11,26 +12,44 @@ import TimestampModal from './TimestampModal';
*/
type Props = {
tzData: Timezones;
page: string;
};

/**
* @description Card component for the app to display timezone data in small cards
* @param {Props} props
* @returns
*/
const Card = ({ tzData }: Props) => {
const Card = ({ tzData, page }: Props) => {
// get current time to state
const [currentTime, setCurrentTime] = useState(getCurrentTime(tzData.name, store.getState().storedata.dateFormat));
const [currentTime, setCurrentTime] = useState(page === 'timeis' ? getCurrentTime(tzData.name, store.getState().storedata.dateFormat) : tz(
new Date(store.getState().storedata.timewasData),
store.getState().storedata.dateFormat,
tzData.name,
));
const [selected, setSelected] = useState<Timezones | null>(null);

// set interval to update time
useEffect(() => {
// eslint-disable-next-line react-hooks/rules-of-hooks
page === 'timeis' && useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(getCurrentTime(tzData.name, store.getState().storedata.dateFormat));
}, 100);
return () => clearInterval(interval);
}, [tzData.name]);

// eslint-disable-next-line react-hooks/rules-of-hooks
page === 'timewas' && useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(tz(
new Date(store.getState().storedata.timewasData),
store.getState().storedata.dateFormat,
tzData.name,
));
}, 1000);
return () => clearInterval(interval);
}, [tzData.name]);

return (
<div className="flex flex-row justify-between border border-slate-700 shadow-[0px_50px_30px_-15px_rgba(0,0,0,0.33)]
bg-gradient-to-br from-slate-800 to-slate-900 rounded-lg p-4"
Expand Down
4 changes: 2 additions & 2 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ const Footer = ({ hidden }: Props) => {
<div className='flex flex-col justify-center text-center mt-10 mb-5 bg-slate-900'>
<div className="flex flex-row justify-center">
<div className='grid grid-cols-2 md:grid-cols-2 text-center p-5'>
{/* {footerNav('the time is 🕟', '/', 'left')}
{footerNav('the time is 🕟', '/', 'left')}
{footerNav('the time was? ⌚', '/TimeWas', 'left')}
{footerNav('make it better 🚀', 'https://github.com/dev-asterix/and-the-time-is', 'right')} */}
{footerNav('make it better 🚀', 'https://github.com/dev-asterix/and-the-time-is', 'right')}
</div>
</div>
<div className='text-red-800 font-semibold text-sm lg:text-md'>
Expand Down
27 changes: 24 additions & 3 deletions components/ListView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import { RiCloseFill } from 'react-icons/ri';
import tz from 'timezone/loaded';

import getCurrentTime, { Timezones } from '../functions/timeNow';
import { store } from '../store/store';
Expand All @@ -11,25 +12,45 @@ import TimestampModal from './TimestampModal';
*/
type Props = {
tzData: Timezones;
page: string;
};

/**
* @description component for showing bigger cards
* @param {Props} props
*/
const ListView = ({ tzData }: Props) => {
const ListView = ({ tzData, page }: Props) => {
// get current time to state
const [currentTime, setCurrentTime] = useState(getCurrentTime(tzData.name, store.getState().storedata.dateFormat));
const [currentTime, setCurrentTime] = useState(
page === 'timeis' ? getCurrentTime(tzData.name, store.getState().storedata.dateFormat) : tz(
new Date(store.getState().storedata.timewasData),
store.getState().storedata.dateFormat,
tzData.name,
)
);
const [selected, setSelected] = React.useState<Timezones | null>(null);

// set interval to update time
useEffect(() => {
// eslint-disable-next-line react-hooks/rules-of-hooks
page === 'timeis' && useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(getCurrentTime(tzData.name, store.getState().storedata.dateFormat));
}, 100);
return () => clearInterval(interval);
}, [tzData.name]);

// eslint-disable-next-line react-hooks/rules-of-hooks
page === 'timewas' && useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(tz(
new Date(store.getState().storedata.timewasData),
store.getState().storedata.dateFormat,
tzData.name,
));
}, 1000);
return () => clearInterval(interval);
}, [tzData.name]);

return (
<div className="flex flex-row justify-between border border-slate-700 shadow-[0px_50px_30px_-15px_rgba(0,0,0,0.33)]
bg-gradient-to-br from-slate-800 to-slate-900 rounded-lg p-4"
Expand Down
16 changes: 11 additions & 5 deletions components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ import Card from './Card';
import DateFormatModal from './DateFormatModal';
import ListView from './ListView';

type mainProps = {
page: string;
}

/**
* @description - main component for the app
*/
const Main = () => {
const Main = ({ page }: mainProps) => {

// get timezones from local storage
const [timezones, setTimezones] = useState<Timezones[]>([]);
Expand Down Expand Up @@ -65,7 +69,9 @@ const Main = () => {
type="button"
className="w-full inline-flex justify-center rounded-md border border-transparent
shadow-sm px-4 py-2 bg-teal-600 font-medium text-clip text-white hover:bg-teal-700
focus:outline-none sm:ml-3"
focus:outline-none sm:ml-3 transition ease-in-out duration-1000"
data-bs-toggle="timestampmodal"
data-bs-target="#timestampmodal"
onClick={() => {
setFormatPickerSelected(true);
}}
Expand All @@ -81,10 +87,10 @@ const Main = () => {

// if layout is grid
(<>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 2xl:grid-cols-5 3xl:grid-cols-6 p-2 md:p-5 w-full gap-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 p-2 md:p-5 w-full gap-6">
{
timezones && timezones.map((tzData) => (
<Card key={tzData.name} tzData={tzData} />
<Card key={tzData.name} tzData={tzData} page={page} />
))
}
</div>
Expand All @@ -95,7 +101,7 @@ const Main = () => {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2 p-3">
{
timezones && timezones.map((tzData) => (
<ListView key={tzData.name} tzData={tzData} />
<ListView key={tzData.name} tzData={tzData} page={page} />
))
}
</div>
Expand Down
92 changes: 77 additions & 15 deletions components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@
import Link from 'next/link';
import { useEffect, useState } from 'react';
import tz from 'timezone/loaded';

import getCurrentTime, { Timezones } from '../functions/timeNow';
import { timezoneList } from '../pages/api/timezones';
import { store } from '../store/store';
import TimePicker from './TimePicker';
import TimestampModal from './TimestampModal';
import TimezoneSearch from './TimezoneSearch';

export type TimePickerType = {
year: string;
month: string;
day: string;
hour: string;
minute: string;
second: string;
}

type navbarProps = {
title: string;
searchBar?: boolean;
timePicker?: boolean;
}

/**
* @description - Navbar component with local time and timezone search
* @param {Props} props
*/
const Navbar = () => {
const Navbar = ({ title, searchBar, timePicker }: navbarProps) => {
// get current time to state
const [selected, setSelected] = useState<Timezones | null>(null);
const [currentTime, setCurrentTime] = useState(
getCurrentTime(Intl.DateTimeFormat().resolvedOptions().timeZone, store.getState().storedata.dateFormat),
);

const now = new Date();
const [dateString, setDateString] = useState({
year: now.getFullYear().toString(),
month: (now.getMonth()).toString(),
day: now.getDate().toString(),
hour: now.getHours().toString(),
minute: now.getMinutes().toString(),
second: now.getSeconds().toString(),
} as TimePickerType);

// set interval to update time
useEffect(() => {
// eslint-disable-next-line react-hooks/rules-of-hooks
searchBar && useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(
getCurrentTime(Intl.DateTimeFormat().resolvedOptions().timeZone, store.getState().storedata.dateFormat),
Expand All @@ -28,6 +55,22 @@ const Navbar = () => {
return () => clearInterval(interval);
}, []);

// eslint-disable-next-line react-hooks/rules-of-hooks
timePicker && useEffect(() => {

// construct the timestring from dateString
const pickedDate = `${dateString.day} ${new Date(Number.parseInt(dateString.year), Number.parseInt(dateString.month), 1).toLocaleString('default', { month: 'long' })} ${dateString.year}, ${dateString.hour}:${dateString.minute}:${dateString.second}`;
store.dispatch({ type: 'timewas/data', payload: pickedDate });
// set the current time to the picked time
setCurrentTime(
tz(
new Date(pickedDate),
store.getState().storedata.dateFormat,
Intl.DateTimeFormat().resolvedOptions().timeZone
),
);
}, [dateString]);

return (
<>
<div
Expand All @@ -38,22 +81,41 @@ const Navbar = () => {
<div className='p-2 lg:p-8 mt-2 lg:mt-10'>
<Link href={"/"}>
<a className='text-4xl font-nova-flat md:text-6xl pb-2 animate-pulse hover:text-teal-500'>
And the time is ...
{title}
</a>
</Link>
<div className='mt-5 md:mt-20 font-nova-flat text-slate-300'>
<p className='text-teal-500 text-lg'>
{`Local Time in ${Intl.DateTimeFormat().resolvedOptions().timeZone} :`}
</p>
<p className='mt-3 text-xl truncate md:text-3xl list-outside hover:text-teal-300'
onClick={() => setSelected(timezoneList.filter(tz => tz.name === Intl.DateTimeFormat().resolvedOptions().timeZone)[0] as Timezones)}
>
{currentTime}
</p>
</div>
{
searchBar && (
<div className='mt-5 md:mt-20 font-nova-flat text-slate-300'>
<p className='text-teal-500 text-lg'>
{`Local Time in ${Intl.DateTimeFormat().resolvedOptions().timeZone} :`}
</p>
<p className='mt-3 text-xl truncate md:text-3xl list-outside hover:text-teal-300'
onClick={() => setSelected(timezoneList.filter(tz => tz.name === Intl.DateTimeFormat().resolvedOptions().timeZone)[0] as Timezones)}
>
{currentTime}
</p>
</div>)
}

{
timePicker && (
<div className='mt-5 md:mt-20 font-nova-flat text-slate-300'>
<p className='text-teal-500 text-lg'>
{`Local Time in ${Intl.DateTimeFormat().resolvedOptions().timeZone} :`}
</p>
<p className='mt-3 text-xl truncate md:text-3xl list-outside hover:text-teal-300'
onClick={() => setSelected(timezoneList.filter(tz => tz.name === Intl.DateTimeFormat().resolvedOptions().timeZone)[0] as Timezones)}
>
{currentTime}
</p>
</div>)
}

</div>
<div className='p-2 lg:p-10 mt-0 md:mt-10 md:z-10'>
<TimezoneSearch />
{searchBar && <TimezoneSearch />}
{timePicker && <TimePicker now={now} dateString={dateString} setDateString={setDateString} />}
</div>
</div>
</div>
Expand Down
Loading

1 comment on commit 5d7e049

@vercel
Copy link

@vercel vercel bot commented on 5d7e049 Jul 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

and-the-time-is – ./

and-the-time-is-asterix-dev.vercel.app
and-the-time-is-git-main-asterix-dev.vercel.app
andthetimeis.vercel.app

Please sign in to comment.