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

Added create entry form and updated JournalEntry interface #9

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
45 changes: 12 additions & 33 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,22 @@
import { useState, useEffect } from "react";
import { Routes, Route, HashRouter } from "react-router-dom";
import { Routes, Route, HashRouter } from "react-router-dom";

import Navbar from "./Navbar";
import Create from "./Create";
import Home from "./Home";
import Reports from "./Reports";

function Input() {
let [test, setTest] = useState("");

useEffect(() => {
let timeout = setTimeout(() => {
console.log(test);
}, 500);

return () => {
clearTimeout(timeout);
}
}, [test]);

return <input
type="text"
placeholder="here is a simple placeholder for the input value"
value={test}
onChange={(ev) => {
setTest(ev.target.value);
}}
/>
}
import { JournalProvider } from "./JournalContext";

const App: React.FC = () => (
<HashRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/Create" element={<Create />} />
<Route path="/Reports" element={<Reports />} />
</Routes>
</HashRouter>
<JournalProvider>
<HashRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/Create" element={<Create />} />
<Route path="/Reports" element={<Reports />} />
</Routes>
</HashRouter>
</JournalProvider>
);

export default App;
164 changes: 162 additions & 2 deletions src/Create/Create.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,171 @@
import React, { Component } from "react";
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";

import { JournalEntry } from "../journal";
import { useJournal } from "../JournalContext";

function JournalEntryForm(){

const { addJournalEntry } = useJournal();

const [journalEntry, setJournalEntry] = useState<JournalEntry>({
date: "",
title: "",
hoursActive: 0,
hoursSleeping: 0,
hoursFocused: 0,
hoursOnScreen: 0,
hoursOutside: 0,
hoursReading: 0,
mood: 5,
created: new Date().toISOString(),
reflection: "",
updated: null
});

// for navigation back to home page after submitting
const navigate = useNavigate();

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = event.target;

// update journal on change
setJournalEntry({
...journalEntry,
[name]: (name.startsWith("hours") || name === "mood") // for hours counts and mood, get value and handle empty string
? (value === "" ? "" : Number(value))
: value,
updated: new Date().toISOString(), // for update I will need to change this. Currently can only create entries
created: new Date().toISOString()
});
}

// Handle form submission
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
addJournalEntry(journalEntry);
navigate("/");
};

return(
<form onSubmit={handleSubmit}>
<div>
<label>Date:</label>
<input
type="date"
name="date"
value={journalEntry.date}
onChange={handleInputChange}
/>
</div>

<div>
<label>Title:</label>
<input
type="text"
name="title"
value={journalEntry.title}
onChange={handleInputChange}
placeholder="Journal Title"
/>
</div>

<div>
<label>Hours Active:</label>
<input
type="number"
name="hoursActive"
value={journalEntry.hoursActive}
onChange={handleInputChange}
/>
</div>
<div>
<label>Hours Sleeping:</label>
<input
type="number"
name="hoursSleeping"
value={journalEntry.hoursSleeping}
onChange={handleInputChange}
/>
</div>
<div>
<label>Hours Focused:</label>
<input
type="number"
name="hoursFocused"
value={journalEntry.hoursFocused}
onChange={handleInputChange}
/>
</div>
<div>
<label>Hours on Screen:</label>
<input
type="number"
name="hoursOnScreen"
value={journalEntry.hoursOnScreen}
onChange={handleInputChange}
/>
</div>
<div>
<label>Hours Outside:</label>
<input
type="number"
name="hoursOutside"
value={journalEntry.hoursOutside}
onChange={handleInputChange}
/>
</div>
<div>
<label>Hours Reading:</label>
<input
type="number"
name="hoursReading"
value={journalEntry.hoursReading}
onChange={handleInputChange}
/>
</div>

<div>
<label>Mood (1-10):</label>
<input
type="number"
name="mood"
min="1"
max="10"
value={journalEntry.mood}
onChange={handleInputChange}
/>
</div>

<div>
<label>Contents:</label>
<textarea
name="reflection"
value={journalEntry.reflection}
onChange={handleInputChange}
placeholder="What happened today?"
/>
</div>

<button type="submit">Submit Journal Entry</button>

</form>

);
}




type CreateProps = {
//
};


const Create = (props: CreateProps) => {
return <div>Create</div>;
return <div>
<JournalEntryForm/>
</div>;
}

export default Create;
43 changes: 32 additions & 11 deletions src/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from "react";
import { useContext } from "react";

import { Journal, JournalEntry, JournalEntries, gen_data } from "../journal";
import { JournalContext } from "../JournalContext"

type SortDir = -1 | 1;

Expand All @@ -23,33 +24,53 @@ function get_sort(dir: SortDir) {
const sort_desc = get_sort(-1);

interface EntriesViewProps {
entries: JournalEntries
entries: JournalEntry[]
}

const EntriesView = ({entries}: EntriesViewProps) => {
let tr_rows = [];

// this is probably not optimal
for (let entry of Object.values(entries).sort(sort_desc)) {
tr_rows.push(<tr key={entry.date}>
<td>{entry.date}</td>
<td>{entry.mood}</td>
<td>{entry.updated != null ? entry.updated : entry.created}</td>
</tr>);
tr_rows.push(
<tr key={entry.date}>
<td>{entry.date}</td>
<td>{entry.title}</td>
<td>{entry.hoursActive}</td>
<td>{entry.hoursSleeping}</td>
<td>{entry.hoursFocused}</td>
<td>{entry.hoursOnScreen}</td>
<td>{entry.hoursOutside}</td>
<td>{entry.hoursReading}</td>
<td>{entry.mood}</td>
<td>{entry.reflection}</td>
<td>{entry.created}</td>
<td>{entry.updated !== null ? entry.updated : entry.created}</td>
</tr>
);
}

if (tr_rows.length === 0) {
tr_rows.push(<tr key={"empty"}>
<td colSpan={3}>No Entries</td>
<td colSpan={12}>No Entries</td>
</tr>);
}

return <table>
<thead>
<tr>
<th>Date</th>
<th>Title</th>
<th>Hours Active</th>
<th>Hours Sleeping</th>
<th>Hours Focused</th>
<th>Hours on Screen</th>
<th>Hours Outside</th>
<th>Hours Reading</th>
<th>Mood</th>
<th>Mod</th>
<th>Contents</th>
<th>Created</th>
<th>Updated</th>
</tr>
</thead>
<tbody>{tr_rows}</tbody>
Expand All @@ -59,10 +80,10 @@ const EntriesView = ({entries}: EntriesViewProps) => {
type HomeProps = {};

const Home = ({}: HomeProps) => {
const [journal, setJournal] = useState<Journal>(gen_data(new Date(), 10));
const { journalList } = useContext(JournalContext);

return <div>
<EntriesView entries={journal.entries}/>
<EntriesView entries={journalList}/>
</div>;
}

Expand Down
63 changes: 63 additions & 0 deletions src/JournalContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { createContext, useContext, useState } from 'react';
import { JournalEntry } from './journal';

interface JournalContextType {
journalList: JournalEntry[];
addJournalEntry: (entry: JournalEntry) => void;
}

export const JournalContext = createContext<JournalContextType | undefined>(undefined);

// Dummy journal entries
const dummyEntries: JournalEntry[] = [
{
date: '2024-10-01',
title: 'First Day',
hoursActive: 4,
hoursSleeping: 8,
hoursFocused: 5,
hoursOnScreen: 3,
hoursOutside: 2,
hoursReading: 1,
mood: 10,
reflection: 'Had a productive day!',
created: new Date().toISOString(),
updated: new Date().toISOString(),
},
{
date: '2024-10-02',
title: 'Second Day',
hoursActive: 3,
hoursSleeping: 7,
hoursFocused: 4,
hoursOnScreen: 4,
hoursOutside: 1,
hoursReading: 2,
mood: 1,
reflection: 'Just an average day.',
created: new Date().toISOString(),
updated: new Date().toISOString(),
},
];

export const useJournal = () => {
const context = useContext(JournalContext);
if (!context) {
throw new Error('useJournal must be used within a JournalProvider');
}
return context;
};

export const JournalProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [journalEntries, setJournalEntries] = useState<JournalEntry[]>(dummyEntries);

const addJournalEntry = (entry: JournalEntry) => {
setJournalEntries(prevEntries => [...prevEntries, entry]);
};

return (
<JournalContext.Provider value={{ journalList: journalEntries, addJournalEntry }}>
{children}
</JournalContext.Provider>
);
};
1 change: 0 additions & 1 deletion src/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React, { Component } from "react";
import './Navbar.css';
import { Link } from "react-router-dom";

Expand Down
8 changes: 7 additions & 1 deletion src/journal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ export interface JournalEntry {
date: string,

title: string,
contents: string,
hoursActive: number,
hoursSleeping: number,
hoursFocused: number,
hoursOnScreen: number,
hoursOutside: number,
hoursReading: number,
reflection: string,

mood: number,

Expand Down