aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Header.js12
-rw-r--r--app/Navbar.js46
-rw-r--r--app/PSA.js47
-rw-r--r--app/layout.js4
-rw-r--r--app/page.js4
-rw-r--r--app/psa.json5
-rw-r--r--app/services/page.js2
-rw-r--r--app/travel-advisory/HistoryModal.js40
-rw-r--r--app/travel-advisory/ListCountries.js66
-rw-r--r--app/travel-advisory/page.js4
-rw-r--r--app/updates/DateFormatter.js9
-rw-r--r--app/updates/PostPreview.js15
-rw-r--r--app/updates/[slug]/page.js4
-rw-r--r--app/updates/getPostMetadata.js24
-rw-r--r--app/updates/page.js6
15 files changed, 276 insertions, 12 deletions
diff --git a/app/Header.js b/app/Header.js
new file mode 100644
index 0000000..bd70dd0
--- /dev/null
+++ b/app/Header.js
@@ -0,0 +1,12 @@
+const Header = ({title, description}) => {
+ return (
+ <div className="bg-center bg-no-repeat bg-[url('/jumbotron.webp')] bg-gray-700 bg-blend-multiply">
+ <div className="md:px-40 px-10 max-w-screen-xl text-left py-24 lg:py-10 space-y-3">
+ <h1 className="font-medium text-4xl">{title}</h1>
+ <h2 className="font-light text-lg">{description}</h2>
+ </div>
+ </div>
+ )
+}
+
+export default Header;
diff --git a/app/Navbar.js b/app/Navbar.js
new file mode 100644
index 0000000..1555eb9
--- /dev/null
+++ b/app/Navbar.js
@@ -0,0 +1,46 @@
+"use client";
+import Image from "next/image";
+import Link from "next/link";
+import { useState } from "react";
+
+const Navbar = () => {
+ const [navbar, setNavbar] = useState(false);
+ return (
+ <nav className="border-gray-200 bg-neutral-900">
+ <div className="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
+ <div className="flex items-center">
+ <Image src="/alure_flag.svg" className="mr-5" alt="Alure Flag" width={70} height={70}/>
+ <span className="self-center text-2xl font-medium whitespace-nowrap dark:text-white"><p>Government</p><p>of Alure Regions</p></span>
+ </div>
+ <button data-collapse-toggle="navbar-default" type="button"
+ className="transition duration-150 ease-out hover:ease-in inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-zinc-600 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
+ aria-controls="navbar-default" aria-expanded="false" onClick={() => setNavbar(!navbar)}>
+ <span className="sr-only">Open main menu</span>
+ <svg className="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
+ viewBox="0 0 17 14">
+ <path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2"
+ d="M1 1h15M1 7h15M1 13h15"/>
+ </svg>
+ </button>
+ <div className={`w-full md:block md:w-auto ${navbar ? 'block' : 'hidden' }`}>
+ <ul className="font-medium text-lg flex flex-col p-4 md:p-0 mt-4 rounded-lg md:flex-row md:space-x-8 md:mt-0">
+ {[
+ ['Home', '/'],
+ ['Updates', '/updates'],
+ ['Services', '/services'],
+ ['Travel Advisory', '/travel-advisory'],
+ ].map(([title, url]) => (
+ <li key="links">
+ <Link href={url} className="transition duration-150 ease-out hover:ease-in block py-2 pl-3 pr-4 rounded md:border-0 md:p-0 text-white md:hover:text-blue-500 hover:bg-gray-700 hover:text-white md:hover:bg-transparent" onClick={() => setNavbar(!navbar)}>
+ {title}
+ </Link>
+ </li>
+ ))}
+ </ul>
+ </div>
+ </div>
+ </nav>
+ )
+}
+
+export default Navbar;
diff --git a/app/PSA.js b/app/PSA.js
new file mode 100644
index 0000000..06bf9ba
--- /dev/null
+++ b/app/PSA.js
@@ -0,0 +1,47 @@
+import psaMessage from './psa.json' assert { type: 'json' };
+import Link from "next/link";
+
+const PSA = () => {
+ let defaultStyle = "flex flex-row md:px-40 px-30 py-0.5 space-x-2";
+ let styleImportant;
+ let important;
+ switch (psaMessage.important) {
+ case 0:
+ styleImportant = "hidden"
+ defaultStyle += ' ' + styleImportant
+ break;
+ case 1:
+ important = "Latest News:"
+ styleImportant = "bg-zinc-700"
+ defaultStyle += ' ' + styleImportant
+ break;
+ case 2:
+ important = "WARNING!"
+ styleImportant = "bg-yellow-700"
+ defaultStyle += ' ' + styleImportant
+ break;
+ case 3:
+ important = "EMERGENCY!"
+ styleImportant = "bg-red-800"
+ defaultStyle += ' ' + styleImportant
+ break;
+
+ }
+
+ return (
+ <div className={defaultStyle}>
+ <p className="text-lg font-medium">{important}</p>
+ <div className="flex flex-row space-x-3">
+ <p>{psaMessage.announcement}</p>
+ <p className="text-blue-200 hover:text-blue-500 active:text-blue-700">
+ {psaMessage.link && (
+ <Link href={psaMessage.link}>
+ Learn more ↗
+ </Link>
+ )}</p>
+ </div>
+ </div>
+ )
+}
+
+export default PSA;
diff --git a/app/layout.js b/app/layout.js
index fa5c790..50dad73 100644
--- a/app/layout.js
+++ b/app/layout.js
@@ -1,7 +1,7 @@
import './globals.css'
import { Exo } from 'next/font/google'
-import Navbar from "@/components/Navbar";
-import PSA from "@/components/PSA";
+import Navbar from "@/app/Navbar";
+import PSA from "@/app/PSA";
const exo = Exo({ subsets: ['latin'] })
diff --git a/app/page.js b/app/page.js
index 60f5965..5a089df 100644
--- a/app/page.js
+++ b/app/page.js
@@ -1,5 +1,5 @@
-import getPostMetadata from "@/components/updates/getPostMetadata";
-import PostPreview from "@/components/updates/PostPreview";
+import getPostMetadata from "@/app/updates/getPostMetadata";
+import PostPreview from "@/app/updates/PostPreview";
import Link from "next/link";
export const metadata = {
diff --git a/app/psa.json b/app/psa.json
new file mode 100644
index 0000000..df9869f
--- /dev/null
+++ b/app/psa.json
@@ -0,0 +1,5 @@
+{
+ "important": 0,
+ "announcement": "No important announcements",
+ "link": "https://google.ca"
+}
diff --git a/app/services/page.js b/app/services/page.js
index c91b92e..3acd69f 100644
--- a/app/services/page.js
+++ b/app/services/page.js
@@ -1,4 +1,4 @@
-import Header from "@/components/Header";
+import Header from "@/app/Header";
export const metadata = {
title: 'Services',
diff --git a/app/travel-advisory/HistoryModal.js b/app/travel-advisory/HistoryModal.js
new file mode 100644
index 0000000..3ef2ea8
--- /dev/null
+++ b/app/travel-advisory/HistoryModal.js
@@ -0,0 +1,40 @@
+const HistoryModal = ({ isVisible, onClose, countries, dangerLevel, history }) => {
+ if (!isVisible) return null;
+ const handleClose = (e) => {
+ if(e.target.id === 'wrapper') onClose();
+ }
+
+ let historyList;
+ if (history && history.length > 0) {
+ historyList = history.map((event, index) => {
+ return (
+ <li key={index}>{event}</li>
+ )
+ })
+ } else {
+ historyList = <li>Currently no diplomatic tensions in this country.</li>;
+ }
+
+ return (
+ <div id="wrapper" className="fixed inset-0 bg bg-opacity-25 backdrop-blur-sm flex justify-center items-center" onClick={handleClose}>
+ <div className="w-[700px]">
+ <div className="flex flex-col">
+ <div className="bg-zinc-800 p-5 rounded-lg border border-gray-700">
+ <div className="divide-y space-y-3">
+ <div>
+ <h1 className="font-medium text-3xl">{countries}</h1>
+ <h2 className="font-medium text-xl">{dangerLevel}</h2>
+ </div>
+ <div>
+ <h1 className="font-medium text-2xl pt-3">History</h1>
+ <ul>{historyList}</ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ )
+}
+
+export default HistoryModal;
diff --git a/app/travel-advisory/ListCountries.js b/app/travel-advisory/ListCountries.js
new file mode 100644
index 0000000..c2e233d
--- /dev/null
+++ b/app/travel-advisory/ListCountries.js
@@ -0,0 +1,66 @@
+"use client"
+import countriesData from '@/app/travel-advisory/countries.json' assert { type: 'json' };
+import HistoryModal from "@/app/travel-advisory/HistoryModal";
+import { useState } from "react";
+
+export function getDangerLevel(danger) {
+ let dangerLevel;
+ switch (danger) {
+ case 0:
+ dangerLevel = "Take normal security precautions"
+ break;
+ case 1:
+ dangerLevel = "Exercise a high degree of caution"
+ break;
+ case 2:
+ dangerLevel = "Avoid non-essential travel"
+ break;
+ case 3:
+ dangerLevel = "Avoid all travel"
+ break;
+ default:
+ dangerLevel = "Seems like the danger level is broken!"
+ break;
+ }
+
+ return dangerLevel;
+}
+
+export function Countries(){
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const [showModal, setShowModal] = useState(false);
+ const [selectedCountry, setSelectedCountry] = useState(null);
+ const [selectedDangerLevel, setSelectedDangerLevel] = useState(null);
+ const [selectedCountryHistory, setSelectedCountryHistory] = useState(null);
+ const countries = countriesData.countries;
+
+ return countries.map((country) => {
+ let dangerLevel = getDangerLevel(country.danger);
+
+ const settlementsList = country.settlements.map((settlement) => {
+ return (
+ <div key={settlement.name}>
+ <h2 className="font-medium md:text-3xl text-xl">{settlement.name}</h2>
+ <h2 className="text-base">{getDangerLevel(settlement.danger)}</h2>
+ </div>
+ )
+ })
+
+ return (
+ <div key="countries" className="bg-center bg-no-repeat bg-[image:var(--image-url)] bg-gray-500 bg-blend-multiply" style={{'--image-url': `url(${country.image})`}} >
+ <div className="sm:px-40 px-10 py-10 space-y-3">
+ <h1 className="font-medium md:text-5xl text-3xl">{country.name}</h1>
+ <h2 className="text-lg">{dangerLevel}</h2>
+ <div className="space-y-3">{settlementsList}</div>
+ <button className="transition duration-200 ease-in-out px-4 py-2 font-medium rounded-full bg-blue-600 hover:bg-blue-700 active:bg-blue-800" onClick={()=> {
+ setSelectedCountry(country.name);
+ setSelectedDangerLevel(dangerLevel)
+ setSelectedCountryHistory(country.history)
+ setShowModal(true)
+ }}>Information</button>
+ </div>
+ <HistoryModal isVisible={showModal} onClose={() => setShowModal(false)} countries={selectedCountry} dangerLevel={selectedDangerLevel} history={selectedCountryHistory} />
+ </div>
+ )
+ })
+}
diff --git a/app/travel-advisory/page.js b/app/travel-advisory/page.js
index 415b6c2..259aaa4 100644
--- a/app/travel-advisory/page.js
+++ b/app/travel-advisory/page.js
@@ -1,5 +1,5 @@
-import { Countries, getDangerLevel } from "@/components/travel-advisory/ListCountries";
-import Header from "@/components/Header";
+import { Countries, getDangerLevel } from "@/app/travel-advisory/ListCountries";
+import Header from "@/app/Header";
export const metadata = {
title: 'Travel Advisory',
diff --git a/app/updates/DateFormatter.js b/app/updates/DateFormatter.js
new file mode 100644
index 0000000..9e236d0
--- /dev/null
+++ b/app/updates/DateFormatter.js
@@ -0,0 +1,9 @@
+
+import { parseISO, format } from 'date-fns'
+
+const DateFormatter = (dateString) => {
+ const date = parseISO(dateString)
+ return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
+}
+
+export default DateFormatter
diff --git a/app/updates/PostPreview.js b/app/updates/PostPreview.js
new file mode 100644
index 0000000..23e2176
--- /dev/null
+++ b/app/updates/PostPreview.js
@@ -0,0 +1,15 @@
+import Link from "next/link";
+import DateFormatter from '@/app/updates/DateFormatter'
+
+export default function PostPreview(props) {
+ return (
+ <div key="post" className="bg-zinc-800 py-3 px-5 border border-gray-600 rounded-lg space-y-3">
+ <Link href={`/updates/${props.slug}`}>
+ <h2 className="font-medium text-2xl hover:underline">{props.title}</h2>
+ </Link>
+ <span className="text-sm">{props.author}</span>
+ <p>{props.description}</p>
+ <p className="font-medium text-sm">Posted on {DateFormatter(props.date)}</p>
+ </div>
+ )
+}
diff --git a/app/updates/[slug]/page.js b/app/updates/[slug]/page.js
index d91440e..102a98a 100644
--- a/app/updates/[slug]/page.js
+++ b/app/updates/[slug]/page.js
@@ -1,8 +1,8 @@
import {readFileSync} from "fs";
import Markdown from "markdown-to-jsx"
import matter from "gray-matter";
-import getPostMetadata from "@/components/updates/getPostMetadata";
-import DateFormatter from "@/components/updates/DateFormatter";
+import getPostMetadata from "@/app/updates/getPostMetadata";
+import DateFormatter from "@/app/updates/DateFormatter";
const getPostContent = (slug) => {
const folder = "posts/";
diff --git a/app/updates/getPostMetadata.js b/app/updates/getPostMetadata.js
new file mode 100644
index 0000000..515cc79
--- /dev/null
+++ b/app/updates/getPostMetadata.js
@@ -0,0 +1,24 @@
+import {readdirSync, readFileSync} from "fs";
+import matter from "gray-matter";
+
+export default function getPostMetadata() {
+ const folder = "posts/";
+ const files = readdirSync(folder);
+ const markdownPosts = files.filter((file) => file.endsWith(".md"));
+
+ const posts = markdownPosts.map((fileName) => {
+ const fileContent = readFileSync(`posts/${fileName}`, "utf-8");
+ const matterResult = matter(fileContent);
+ return {
+ title: matterResult.data.title,
+ author: matterResult.data.author,
+ date: matterResult.data.date,
+ description: matterResult.data.description,
+ slug: fileName.replace(".md", "")
+ }
+ })
+
+ // Sort the posts by date in descending order
+ posts.sort((a, b) => new Date(b.date) - new Date(a.date));
+ return posts
+}
diff --git a/app/updates/page.js b/app/updates/page.js
index 04215c9..148c135 100644
--- a/app/updates/page.js
+++ b/app/updates/page.js
@@ -1,6 +1,6 @@
-import getPostMetadata from "@/components/updates/getPostMetadata";
-import PostPreview from "@/components/updates/PostPreview";
-import Header from "@/components/Header";
+import getPostMetadata from "@/app/updates/getPostMetadata";
+import PostPreview from "@/app/updates/PostPreview";
+import Header from "@/app/Header";
export const metadata = {
title: 'Updates',