Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add navbar #9

Merged
merged 8 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
VITE_REACT_RDS_BACKEND_BASE_URL='https://staging-api.realdevsquad.com'
VITE_REACT_STATUS_SITE_URL='https://staging-status.realdevsquad.com'
VITE_REACT_MEMBERS_SITE_URL='https://staging-members.realdevsquad.com'
VITE_REACT_WELCOME_SITE_URL='https://welcome.realdevsquad.com'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

.env

node_modules
dist
dist-ssr
Expand Down
9 changes: 9 additions & 0 deletions public/assets/rds-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import './App.css';
import Navbar from './components/navbar';

const App = () => {
return (
<>
<h1 className="text-primary">Real Dev Sqaud</h1>
<Navbar />
</>
);
};
Expand Down
82 changes: 82 additions & 0 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useEffect } from 'react';
import { getConfig, validateEnv } from '../config';

const Navbar: React.FC = () => {
const { welcomeSiteUrl, membersSiteUrl, statusSiteUrl } = getConfig();

useEffect(() => {
try {
validateEnv();
} catch (error) {
console.error('Environment validation error:', error);
}
}, []);

return (
<nav
className="fixed left-0 top-0 w-full border-b border-gray-100 bg-primary p-2"
aria-label="Main Navigation"
data-testid="navbar"
>
<div className="mx-auto flex h-14 w-full max-w-screen-2xl items-center gap-6 px-6">
<a
href="/"
className="flex items-center"
aria-label="Home"
data-testid="navbar-home-link"
>
<img
src="/assets/rds-logo.svg"
alt="RDS Logo"
className="h-12 w-12"
/>
</a>

<div className="flex items-center space-x-6">
<a
href={welcomeSiteUrl}
className="text-white hover:text-accent"
target="_blank"
rel="noopener noreferrer"
aria-label="Go to Welcome site"
data-testid="navbar-welcome-link"
>
Welcome
</a>
<a
href={membersSiteUrl}
className="text-white hover:text-accent"
target="_blank"
rel="noopener noreferrer"
aria-label="Go to Members site"
data-testid="navbar-members-link"
>
Members
</a>
<a
href={statusSiteUrl}
className="text-white hover:text-accent"
target="_blank"
rel="noopener noreferrer"
aria-label="Go to Status site"
data-testid="navbar-status-link"
>
Status
</a>
</div>

<div className="ml-auto">
<button
className="rounded bg-secondary px-4 py-2 text-white hover:bg-accent"
aria-label="Sign In"
data-testid="navbar-signin-btn"
>
Sign In
</button>
</div>
</div>
</nav>
);
};

export default Navbar;
25 changes: 25 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// config.ts
const config = {
appEnv: import.meta.env.VITE_REACT_ENV,
welcomeSiteUrl: import.meta.env.VITE_REACT_WELCOME_SITE_URL,
membersSiteUrl: import.meta.env.VITE_REACT_MEMBERS_SITE_URL,
statusSiteUrl: import.meta.env.VITE_REACT_STATUS_SITE_URL,
};

export const getConfig = () => {
return config;
};

export const validateEnv = () => {
const requiredVars = [
'appEnv',
'welcomeSiteUrl',
'membersSiteUrl',
'statusSiteUrl',
];
for (const key of requiredVars) {
if (!config[key]) {
throw new Error(`Missing required environment variable: ${key}`);
}
}
};
6 changes: 2 additions & 4 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** @type {import('tailwindcss').Config} */
// tailwind.config.js
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
Expand All @@ -15,9 +15,6 @@ export default {
],
},
colors: {
background: {
DEFAULT: '#ffffff',
},
primary: {
DEFAULT: '#1d1283',
light: '#041187',
Expand All @@ -26,6 +23,7 @@ export default {
DEFAULT: '#000000',
light: '#aeaeae',
},
accent: '#87d870',
},
},
},
Expand Down
4 changes: 3 additions & 1 deletion tests/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ import App from '../src/App';

test('renders the app component', () => {
render(<App />);
expect(screen.getByText(/Real Dev Sqaud/i)).toBeInTheDocument();

//check if navbar exists
expect(screen.getByTestId('navbar')).toBeInTheDocument();
});
46 changes: 46 additions & 0 deletions tests/components/Navbar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { render, screen } from '@testing-library/react';
import Navbar from '../../src/components/navbar';
import { describe, it, expect, vi } from 'vitest';

vi.mock('../../src/config', () => ({
getConfig: () => ({
welcomeSiteUrl: 'https://welcome.example.com',
membersSiteUrl: 'https://members.example.com',
statusSiteUrl: 'https://status.example.com',
}),
validateEnv: () => {},
}));

describe('Navbar Component', () => {
it('should render the navbar with correct links', () => {
render(<Navbar />);

expect(screen.getByLabelText(/Home/i)).toBeInTheDocument();
expect(screen.getByLabelText(/Go to Welcome site/i)).toBeInTheDocument();
expect(screen.getByLabelText(/Go to Members site/i)).toBeInTheDocument();
expect(screen.getByLabelText(/Go to Status site/i)).toBeInTheDocument();
});

it('should have links opening in a new tab', () => {
render(<Navbar />);

expect(screen.getByTestId('navbar-home-link')).toBeInTheDocument();
expect(screen.getByTestId('navbar-welcome-link')).toBeInTheDocument();
expect(screen.getByTestId('navbar-members-link')).toBeInTheDocument();
expect(screen.getByTestId('navbar-status-link')).toBeInTheDocument();
expect(screen.getByTestId('navbar-signin-btn')).toBeInTheDocument();

expect(screen.getByLabelText(/Go to Welcome site/i)).toHaveAttribute(
'rel',
'noopener noreferrer',
);
expect(screen.getByLabelText(/Go to Members site/i)).toHaveAttribute(
'rel',
'noopener noreferrer',
);
expect(screen.getByLabelText(/Go to Status site/i)).toHaveAttribute(
'rel',
'noopener noreferrer',
);
});
});
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"esModuleInterop": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"types": ["vitest", "node", "vite/client", "vitest/globals"],
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src", "tests"],
"include": ["src/**/*", "tests/**/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Loading