Skip to content

Commit

Permalink
Add .env file and update gitignore, pipeline name, robots.txt, middle…
Browse files Browse the repository at this point in the history
…ware, layout, page, sitemap, and navlink components
  • Loading branch information
xKhronoz committed Jan 30, 2024
1 parent 3ef43bc commit ad58446
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 145 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test Build and Deploy
name: Pipeline [Test, Build, Deploy]

on:
push:
Expand Down
1 change: 1 addition & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__
storage
.env
1 change: 1 addition & 0 deletions backend/example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALLOWED_ORIGINS=http://localhost:3000
2 changes: 1 addition & 1 deletion frontend/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
export default function About() {

return (
<div className="rounded-xl shadow-xl p-4 mb-8 max-w-5xl w-full">
<div className="rounded-xl shadow-xl p-4 max-w-5xl w-full">
<div className="max-w-2xl mx-auto p-4">
<div className="bg-gradient-to-r from-blue-500 to-indigo-500 text-white p-8 rounded-lg shadow-lg">
<h1 className="text-2xl md:text-4xl font-bold mb-4">About Smart Retrieval</h1>
Expand Down
40 changes: 40 additions & 0 deletions frontend/app/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use client";

import { FooterNavLink } from "./ui/navlink";
import { IconGitHub } from "./ui/icons";
import { Text, Cookie } from "lucide-react";

export default function Footer() {
return (
<footer>
<div className="flex flex-col items-center justify-center bg-gray-800 text-white p-4 mb-4 rounded-lg shadow-xl">
<div className="flex flex-col items-center">
<p className="text-sm text-center">
© 2024 JTC DBE. All rights reserved.
</p>
</div>
<div className="flex items-center mt-2 gap-4">
<FooterNavLink href="https://github.com/digitalbuiltenvironment/Smart-Retrieval/" target="_blank">
<div className="text-sm text-center underline">
<IconGitHub className="h-5 w-5 inline mr-2 mb-1" />
Github
</div>
</FooterNavLink>
<FooterNavLink href="/terms-of-service">
<div className="text-sm text-center underline">
<Text className="h-5 w-5 inline mr-2 mb-1" />
Terms of Service
</div>
</FooterNavLink>
<FooterNavLink href="/privacy-policy">
<div className="text-sm text-center underline">
<Cookie className="h-5 w-5 inline mr-2 mb-1" />
Privacy Policy
</div>
</FooterNavLink>
</div>
</div>
</footer>
);
}

187 changes: 48 additions & 139 deletions frontend/app/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,140 +1,47 @@
"use client";

import Link from 'next/link';
import Image from 'next/image';
import { Home, InfoIcon, MessageCircle, Search, FileQuestion, Menu, X } from 'lucide-react';
import { usePathname } from 'next/navigation';
import { useTheme } from "next-themes";
import { useEffect, useState, useRef } from "react";
import { useEffect, useState } from "react";
import { useMedia } from 'react-use';
import useSWR from 'swr'
import logo from '../../public/smart-retrieval-logo.webp'

interface NavLinkProps {
href: string;
children: React.ReactNode;
onClick?: () => void; // Include onClick as an optional prop
}

interface MobileMenuProps {
isOpen: boolean;
onClose: () => void;
}

const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose }) => {
const isLargeScreen = useMedia('(min-width: 1024px)', false);
const menuRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const handleOutsideClick = (event: MouseEvent | TouchEvent) => {
if (
!isLargeScreen &&
isOpen &&
!menuRef.current?.contains(event.target as Node) &&
!((event.target as HTMLElement).closest('.toggle-button')) // Exclude the toggle button
) {
onClose(); // Close the menu
}
};

if (!isLargeScreen && isOpen) {
// Add event listeners for both mouse and touch events
document.addEventListener('mousedown', handleOutsideClick);
}

return () => {
// Remove the event listener when the component unmounts
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [isLargeScreen, isOpen, onClose]);

useEffect(() => {
if (isLargeScreen && isOpen) {
onClose();
}
}, [isLargeScreen, isOpen, onClose]);
return (
<div ref={menuRef} className={`w-full h-full p-2 bg-opacity-80 ${isOpen ? 'flex' : 'hidden'}`}>
<div className="flex items-center justify-center mt-2" style={{ width: '9%', height: '9%' }}>
<Image
className='rounded-full max-w-full'
src={logo}
alt="Logo"
style={{
width: 'auto',
height: 'auto',
}}
priority
sizes="100vw, 50vw, 33vw"
/>
</div>
<div className="flex items-center justify-center h-full">
{/* Mobile menu content */}
<div className="w-64 p-4 rounded-r-md">
<NavLink href="/" onClick={onClose}>
<div className="flex items-center mb-4">
<Home className="mr-2 h-5 w-5" />
Home
</div>
</NavLink>
<NavLink href="/about" onClick={onClose}>
<div className="flex items-center mb-4">
<InfoIcon className="mr-2 h-5 w-5" />
About
</div>
</NavLink>
<NavLink href="/chat" onClick={onClose}>
<div className="flex items-center mb-4">
<MessageCircle className="mr-2 h-5 w-5" />
Chat
</div>
</NavLink>
<NavLink href="/query" onClick={onClose}>
<div className="flex items-center mb-4">
<FileQuestion className="mr-2 h-5 w-5" />
Q&A
</div>
</NavLink>
<NavLink href="/search" onClick={onClose}>
<div className="flex items-center">
<Search className="mr-2 h-5 w-5" />
Search
</div>
</NavLink>
</div>
</div>
</div>
);
};

const NavLink: React.FC<NavLinkProps> = ({ href, children, onClick }) => {
// Use the useRouter hook to get information about the current route
const pathname = usePathname();

// Determine if the current tab is active
const isActive = pathname === href;

const handleClick = () => {
if (onClick) {
onClick(); // Call the onClick handler if provided
}
};

return (
<Link href={href} passHref>
{/* Add a class to highlight the active tab */}
<div className={`flex items-center font-bold ${isActive ? 'text-blue-500' : ''}`} onClick={handleClick}>
{children}
</div>
</Link>
);
};
import useSWR from 'swr';
import logo from '../../public/smart-retrieval-logo.webp';
import { HeaderNavLink } from './ui/navlink';
import { MobileMenu } from './ui/mobilemenu';

const MobileMenuItems = [
{
href: '/',
icon: <Home className="mr-2 h-5 w-5" />,
label: 'Home',
},
{
href: '/about',
icon: <InfoIcon className="mr-2 h-5 w-5" />,
label: 'About',
},
{
href: '/chat',
icon: <MessageCircle className="mr-2 h-5 w-5" />,
label: 'Chat',
},
{
href: '/query',
icon: <FileQuestion className="mr-2 h-5 w-5" />,
label: 'Q&A',
},
{
href: '/search',
icon: <Search className="mr-2 h-5 w-5" />,
label: 'Search',
},
];

export default function Header() {
const isLargeScreen = useMedia('(min-width: 1024px)', false);
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
// const [apiStatus, setApiStatus] = useState(false);
// Use SWR for API status fetching
const healthcheck_api = process.env.NEXT_PUBLIC_HEALTHCHECK_API;
const { data: apiStatus, error: apiError } = useSWR(healthcheck_api, async (url) => {
Expand Down Expand Up @@ -164,6 +71,8 @@ export default function Header() {
else {
console.error('[Header] Error fetching Backend API Status:', apiError.message);
}
} else {
console.log('[Header] API Status:', apiStatus);
}

useEffect(() => {
Expand Down Expand Up @@ -227,43 +136,43 @@ export default function Header() {
</button>
</div>
{/* Mobile menu component */}
<MobileMenu isOpen={isMobileMenuOpen} onClose={() => setMobileMenuOpen(false)} />
<MobileMenu isOpen={isMobileMenuOpen} onClose={() => setMobileMenuOpen(false)} logoSrc={logo} items={MobileMenuItems} />
<div className={`hidden items-center gap-4 lg:flex`}>
<NavLink href="/">
<HeaderNavLink href="/">
<div className="flex items-center transition duration-300 ease-in-out transform hover:scale-125">
<Home className="mr-1 h-4 w-4" />
Home
</div>
</NavLink>
<NavLink href="/about">
</HeaderNavLink>
<HeaderNavLink href="/about">
<div className="flex items-center transition duration-300 ease-in-out transform hover:scale-125">
<InfoIcon className="mr-1 h-4 w-4" />
About
</div>
</NavLink>
<NavLink href="/chat">
</HeaderNavLink>
<HeaderNavLink href="/chat">
<div className="flex items-center transition duration-300 ease-in-out transform hover:scale-125">
<MessageCircle className="mr-1 h-4 w-4" />
Chat
</div>
</NavLink>
<NavLink href="/query">
</HeaderNavLink>
<HeaderNavLink href="/query">
<div className="flex items-center transition duration-300 ease-in-out transform hover:scale-125">
<FileQuestion className="mr-1 h-4 w-4" />
Q&A
</div>
</NavLink>
<NavLink href="/search">
</HeaderNavLink>
<HeaderNavLink href="/search">
<div className="flex items-center transition duration-300 ease-in-out transform hover:scale-125">
<Search className="mr-1 h-4 w-4" />
Search
</div>
</NavLink>
</HeaderNavLink>
</div>
<div className="flex items-center ml-auto">
{/* Status Page Button/Indicator */}
<span className='flex items-center mr-1'>API:</span>
<NavLink href='/status'>
<HeaderNavLink href='/status'>
<div className="flex items-center mr-2 text-xl transition duration-300 ease-in-out transform hover:scale-125">
{apiError ? (
<span role="img" aria-label="red circle">
Expand All @@ -275,7 +184,7 @@ export default function Header() {
</span>
)}
</div>
</NavLink>
</HeaderNavLink>
<span className="lg:text-lg font-nunito">|</span>
{/* Toggle button with icon based on the theme */}
<button
Expand Down
86 changes: 86 additions & 0 deletions frontend/app/components/ui/mobilemenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"use client";

import { useEffect, useRef } from 'react';
import Image, { StaticImageData } from 'next/image';
import { HeaderNavLink } from '@/app/components/ui/navlink';
import { useMedia } from 'react-use';

interface MenuItem {
href: string;
icon: React.ReactNode;
label: string;
}

interface MobileMenuProps {
isOpen: boolean;
onClose: () => void;
logoSrc: StaticImageData;
items: MenuItem[];
}

const MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose, logoSrc, items }) => {
const isLargeScreen = useMedia('(min-width: 1024px)', false);
const menuRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const handleOutsideClick = (event: MouseEvent | TouchEvent) => {
if (
!isLargeScreen &&
isOpen &&
!menuRef.current?.contains(event.target as Node) &&
!((event.target as HTMLElement).closest('.toggle-button')) // Exclude the toggle button
) {
onClose(); // Close the menu
}
};

if (!isLargeScreen && isOpen) {
// Add event listeners for both mouse and touch events
document.addEventListener('mousedown', handleOutsideClick);
}

return () => {
// Remove the event listener when the component unmounts
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [isLargeScreen, isOpen, onClose]);

useEffect(() => {
if (isLargeScreen && isOpen) {
onClose();
}
}, [isLargeScreen, isOpen, onClose]);

return (
<div ref={menuRef} className={`w-full h-full p-2 bg-opacity-80 ${isOpen ? 'flex' : 'hidden'}`}>
<div className="flex items-center justify-center mt-2" style={{ width: '9%', height: '9%' }}>
<Image
className='rounded-full max-w-full'
src={logoSrc}
alt="Logo"
style={{
width: 'auto',
height: 'auto',
}}
priority
sizes="100vw, 50vw, 33vw"
/>
</div>
<div className="flex items-center justify-center h-full">
{/* Mobile menu content */}
<div className="w-64 p-4 rounded-r-md">
{items.map((item, index) => (
<HeaderNavLink key={index} href={item.href} onClick={onClose}>
<div className="flex items-center mb-4">
{item.icon}
{item.label}
</div>
</HeaderNavLink>
))}
</div>
</div>
</div>
);
};

export { MobileMenu };
Loading

0 comments on commit ad58446

Please sign in to comment.