Skip to content

FRONT-END Template Code

Dependencies

Once you create your project ensure to install both axios, react-bootstrap and react-router-dom:

npm install axios react-router-dom react-bootstrap bootstrap

Package.json scripts

{
  "scripts": {
    "dev": "vite --host",
    "build": "vite build",
    "watcher": "vite build --watch",
    "lint": "eslint .",
    "preview": "vite preview"
  }
}

Dockerfile

FROM node:18

WORKDIR /app

COPY . .

RUN npm install

EXPOSE 5173

CMD ["npm", "run", "dev"]

index.css

CLEAR ALL OTHER STYLING

body{
  width: 100%;
  height: 100%;
}

#root{
  width: 100%;
  height: 100%;
}

main.jsx

import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom';
import router from './router';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css'


createRoot(document.getElementById('root')).render(
    <RouterProvider router={router}/>
)

router.jsx

import { createBrowserRouter } from 'react-router-dom'
import AuthPage from "./pages/AuthPage"
import HomePage from "./pages/HomePage"
import App from "./App"

const router = createBrowserRouter([
    {
        path:"/",
        element: <App/>,
        children:[
            {
                index:true,
                element:<AuthPage/>
            },
            {
                path:"home",
                element: <HomePage />
            }
        ]
    }
])

export default router

App.jsx

import { useEffect, useState } from 'react'
import { Outlet } from 'react-router-dom'
import './App.css'

function App() {
  const [user, setUser] = useState(null)

  useEffect(()=>{
    console.log(user)
  }, [user])

  return (
    <>
     <Outlet context={{ user, setUser }}/>
    </>
  )
}

export default App

Pages

AuthPage.jsx

import { useOutletContext } from "react-router-dom";
import AuthForm from "../components/AuthForm";

const AuthPage = () => {
    const {setUser} = useOutletContext()

    return (
        <>
            <h1>Authentication Page</h1>
            <AuthForm setUser={setUser} />
        </>
    )
}

export default AuthPage;

HomePage.jsx

import { useState } from "react";
import { useOutletContext } from "react-router-dom";
import Stack from 'react-bootstrap/Stack';
import TaskDisplay from "../components/TaskDisplay";
import TaskForm from "../components/TaskForm";

const HomePage = () => {
    const {user, setUser} = useOutletContext()
    const [tasks, setTasks] = useState([{id:1, title:"Code some more"}])

    const addTask = (task) => {
        setTasks([...tasks, task])
    }

    const rmTask = (rmTask) => {
        setTasks(tasks.filter((task)=>(
            task.id !== rmTask.id
        )))
    }

    const updateTask = (editTask) => {
        setTasks(tasks.map((task)=>(
            task.id === editTask.id ? editTask : task
        )))
    }

    return (
        <>
            <h1>Welcome {user && user}: Here are your Tasks <button onClick={()=>setUser(null)}>Log Out</button></h1>

            <Stack gap={3}>
                <TaskForm addTask={addTask}/>

                {tasks.map((task)=>(
                    <TaskDisplay 
                        key={task.id} 
                        task={task}
                        rmTask={rmTask}
                        updateTask={updateTask}
                    />
                ))}

            </Stack>
        </>
    )
}

export default HomePage;

Components

AuthForm.jsx

import { useState } from 'react';
import { useNavigate } from 'react-router-dom'
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';

const AuthForm = ({setUser}) => {

    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')
    const [create, setCreate] = useState(true)
    const navigate = useNavigate()

    const handleSubmit = (e) => {
        e.preventDefault()
        let userDict = {
            email:email,
            password: password
        }
        let method = create ? 'CREATE ACCT' : 'LOGIN ACCT'
        console.log(userDict, method)
        setUser(userDict.email)
        setCreate(true)
        setEmail('')
        setPassword('')
        navigate('/home/')
    }

    return (
        <>
            <Form onSubmit={handleSubmit}>
                <Form.Group className="mb-3" controlId="formBasicEmail">
                    <Form.Label>Email address</Form.Label>
                    <Form.Control 
                        type="email" 
                        placeholder="Enter email" 
                        value={email}
                        onChange={(e)=>setEmail(e.target.value)}
                    />
                    <Form.Text className="text-muted">
                    We'll never share your email with anyone else.
                    </Form.Text>
                </Form.Group>

                <Form.Group className="mb-3" controlId="formBasicPassword">
                    <Form.Label>Password</Form.Label>
                    <Form.Control 
                        type="password" 
                        placeholder="Password" 
                        value={password}
                        onChange={(e)=>setPassword(e.target.value)}
                    />
                </Form.Group>

                <Form.Group className="mb-3" controlId="formBasicCheckbox">
                    <Form.Check 
                        type="checkbox" 
                        label={create ? "CREATE ACCOUNT" : "LOG IN"} 
                        checked={create}
                        onChange={(e)=>setCreate(e.target.checked)}
                    />
                </Form.Group>

                <Button variant="primary" type="submit">
                    {create ? "CREATE ACCOUNT" : "LOG IN"} 
                </Button>
            </Form>
        </>
    )
}

export default AuthForm

TaskDisplay.jsx

import Stack from 'react-bootstrap/Stack';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import { useState } from 'react';

const TaskDisplay = ({task, rmTask, updateTask}) => {

    const [edit, setEdit] = useState(false)
    const [editTitle, setEditTitle] = useState(task.title)

    const editTaskHandle = () => {
        let editedTask = {
            id:task.id,
            title: editTitle
        }
        updateTask(editedTask)
        setEdit(!edit)
    }

    return (
        <>
            <Stack direction="horizontal" gap={3} style={{border:"solid black 1vmin"}}>
            {edit ?
            <>
                <Form.Control 
                    className="me-auto" 
                    placeholder={task.title}
                    value={editTitle}
                    onChange={(e)=>setEditTitle(e.target.value)}
                />
                <Button variant="outline-primary" onClick={editTaskHandle}>Submit</Button>
                <div className="vr" />
                <Button variant="outline-secondary" onClick={()=>[setEdit(!edit), setEditTitle(task.title)]}>Cancel</Button>
            </>
            :
            <>
                <div className="p-2">{task.title}</div>
                <div className="p-2 ms-auto">
                    <Button variant='warning' onClick={()=>setEdit(!edit)}>
                        Edit
                    </Button>
                </div>
                <div className="vr" />
                <div className="p-2">
                    <Button variant='danger' onClick={()=>rmTask(task)}>
                        Delete
                    </Button>
                </div>
            </>
        }
        </Stack>
        </>
    )
}

export default TaskDisplay

TaskForm.jsx

import { useState } from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/esm/Button';

function TaskForm({addTask}) {
    const [taskTitle, setTaskTitle] = useState('')

    const handleSubmit = (e) => {
        e.preventDefault()
        let newTask = {
            id: crypto.randomUUID(),
            title: taskTitle
        }
        addTask(newTask)
        setTaskTitle('')
    }

    return (
        <>
            <Form onSubmit={handleSubmit} style={{width:"100%", display:"flex", justifyContent:"space-around"}}>
                <Form.Control
                    type="text"
                    placeholder='input a new task title here'
                    value={taskTitle}
                    onChange={(e)=>setTaskTitle(e.target.value)}
                />
                <Button type='submit'>
                    Create
                </Button>
            </Form>
        </>
    );
}

export default TaskForm;