Skip to content
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
42 changes: 0 additions & 42 deletions src/App.css

This file was deleted.

30 changes: 20 additions & 10 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { describe, it } from "vitest";
import { render, screen } from '@testing-library/react'
import App from './App'
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router";
import App from "./App";

describe('App', () => {
it('renders the App component', () => {
render(<App />)

screen.debug(); // prints out the jsx in the App component unto the command line
})
})
describe("App", () => {
it("renders the App component", () => {
// arrange
render(
<MemoryRouter>
<App />
</MemoryRouter>
);

// act
let text = screen.getByText("⚛️ React Boilerplate");

// assert
expect(text).toBeInTheDocument();
});
});
18 changes: 3 additions & 15 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import "./App.css";
import { motion } from "framer-motion";
import HomePage from "./pages/Home";


function App() {
return (
<>
<motion.h1
className="text-blue-400 mb-4"
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5 }}
>
⚛️ React Boilerplate
</motion.h1>
<motion.p initial={{ y: 20 }} animate={{ y: 0 }}>
Status: 🟢 In progress.
</motion.p>
</>
<HomePage />
);
}

Expand Down
68 changes: 0 additions & 68 deletions src/index.css

This file was deleted.

32 changes: 24 additions & 8 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router";

createRoot(document.getElementById('root')!).render(
// page components
import App from "./App.tsx";
import AboutPage from "./pages/About/index.tsx";
import ErrorPage from "./pages/ErrorPage.tsx";

const router = createBrowserRouter([
{
path: "/",
element: <App />,
errorElement: <ErrorPage />,
},
{
path: "/about",
element: <AboutPage />,
},
]);

createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
)
<RouterProvider router={router} />
</StrictMode>
);
21 changes: 21 additions & 0 deletions src/pages/About/About.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router";
import AboutPage from ".";

describe("About Page", () => {
it("should render the about page", () => {
// arrange
render(
<MemoryRouter>
<AboutPage />
</MemoryRouter>
);

// act
let heading = screen.getByRole("heading");

// assert
expect(heading).toHaveTextContent(/about this project/i);
});
});
28 changes: 28 additions & 0 deletions src/pages/About/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Link } from "react-router";

const AboutPage = () => {
return (
<div className="flex flex-col max-w-lg mx-auto gap-4 h-screen justify-center">
<h1 className="text-3xl font-bold">About This Project</h1>
<div className="flex flex-col gap-4 text-gray-600">
<p>
ReactJs Boilerplate is a personal starter or boilerplate code I
created to help me boostrap my React frontend project quickly
</p>
<p>
It comes with some best practices such as eslinting, consistent code
formatting checks before commiting with husky, testing, styling, CI/CD
pipelines with Github Actions, etc
</p>
</div>
<Link
to="/"
className="bg-orange-400 border-2 rounded-md inline-block max-w-[150px] text-center text-black px-4 py-3 mt-4"
>
Home
</Link>
</div>
);
};

export default AboutPage;
20 changes: 20 additions & 0 deletions src/pages/ErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useRouteError, UNSAFE_ErrorResponseImpl } from "react-router";

const ErrorPage = () => {
const error = useRouteError();

return (
<div className="max-w-lg mx-auto h-screen flex flex-col justify-center items-center gap-8">
<h1 className="text-2xl">Oops!</h1>
<p>Sorry, an unexpected error has occured.</p>
<p className="text-gray-500">
<i>
{(error as UNSAFE_ErrorResponseImpl).statusText ||
(error as UNSAFE_ErrorResponseImpl).data}
</i>
</p>
</div>
);
};

export default ErrorPage;
32 changes: 32 additions & 0 deletions src/pages/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { motion } from "framer-motion";
import { Link } from "react-router";

const HomePage = () => {
return (
<div className="h-screen w-full flex flex-col justify-center items-center">
<motion.h1
className="text-blue-400 mb-4 text-4xl"
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5 }}
>
⚛️ React Boilerplate
</motion.h1>
<motion.p
className="mt-2 text-gray-600"
initial={{ y: 20 }}
animate={{ y: 0 }}
>
Status: 🟢 In progress.
</motion.p>
<Link
to="/about"
className="mt-12 px-4 py-3 bg-blue-400 border-2 rounded-md"
>
Learn more
</Link>
</div>
);
};

export default HomePage;