Day 20 [D&D Character Sheet]
Tags: 100daysofcode
Published: 2020-04-08 04:50:14

# Report
Today I have have an actual app! You can click around and do stuff! Not much but... In all seriousness, today you can create an account an log-in, stay logged, and see a list of characters. There's still a lot of features to develop, but I'm making progress, however slowly. Anyway here's what I did today.

## Finished up authentication.
First priority was fixing a bug in the user signup. The form validation failed continuously failed, preventing a user from signing up. I'm using HTML5 form validation on the signup fields, and despite meeting the requirements the password kept being rejected as invalid.

### A Tale of Debugging
I started debugging yesterday after I encountered the error. I started my search under the assumption that something was wrong with the password field since that was what threw the error. Given my inexperience with regex I focused my debugging efforts there. Today I decided to remove the pattern attribute on my password field and discovered that the validation failed even without the pattern!

And that is why you shouldn't make assumptions. I should have through checked to verify what was wrong with the form before jumping into debugging regex. After some testing I realized that the validation on all the field failed and that something in that page's javascript was causing the bug. In the end the javascript was cruft and needed to be wiped anyway. 

I didn't identify the exact source of the bug, I'm guessing it was the setCustomValidity() function? That doesn't seem likely given what the function is supposed to do according to the documentation. If anyone is interested here's the offending code.
```js
// public/js/users/login.js
$(document).ready(() => {
	document
		.getElementById("signup-password")
		.setCustomValidity(
			"Include 1 lowercase, 1 uppercase, and 1 number.\n Minimum 8 characters, maximum 40 characters."
		);

	$("form").on("submit", e => {
		e.preventDefault();
		const $form = $(e.target);
		fetch($form.prop("action"), {
			method: "POST",
			credentials: "same-origin",
			redirect: "follow",
			headers: {
				"Content-Type": "application/x-www-form-urlencoded"
			},
			body: $form.serialize()
		})
			.then(response => {
				if (response.redirected) {
					window.location.href = response.url;
				} else {
					return response.json();
				}
			})
			.then(data => {
				console.log(data);
			})
			.catch(err => {
				console.log(err);
			});
	});
});
```

```html
// views/users/login.ejs
<form action="/users/signup" method="post">
	<div class="form-group">
		<label for="signup-email">Email</label>
		<input
			type="email"
			name="email"
			id="signup-email"
			class="form-control"
			required
		/>
	</div>
	<div class="form-group">
		<label for="signup-username">Username</label>
		<input
			type="text"
			name="username"
			id="signup-username"
			class="form-control"
			required
		/>
	</div>
	<div class="form-group">
		<label for="signup-password">Password</label>
		<input
			type="password"
			name="password"
			id="signup-password"
			class="form-control"
			required
			minlength="8"
			maxlength="50"
			pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,50})"
		/>
	</div>
	<div class="form-group">
		<button class="btn" type="submit">Signup</button>
	</div>
</form>
```

I also add some flash messages from the server to provide error messages with the signup is invalid. Here's the flash middleware.
```js
// index.js
app.use((req, res, next) => {
	req.flash = function (flash) {
		this.session.sessionFlash = { type: flash.type, message: flash.message };
		return this;
	};
	res.locals.sessionFlash = req.session.sessionFlash;
	req.session.sessionFlash = null;
	next();
});
```
Lastly I began persisting the state(making it so that sessions could last past a server shutdown) to the mongo database.

## Wrote a Character List view
I wrote a simple Character List view. It still initial and needs testing but it's accessible in app via a link in the navbar.

---
## Thanks for reading!

# Project

{% github ApproachingApathy/100days-dnd-character-sheets %}

The First project will be an app to keep D&D character sheets.

## Stack

I'll be using Node.js and building a full-stack Express app with MongoDB.
### Requirements
#### Minimum Viable 

- [ ] Investigate automating or finding a source of info for the data in the SRD.
- [X] Present a D&D Character Sheet
    - [ ] The sheet should display all the same info as the first page of the 5e Official sheet.
- [ ] Users should be able to log in and create player-characters.
- [ ] Users should be able to edit character sheets.
- [ ] Users should be able to organize character sheets into groups (parties/tables)
- [ ] Sheets should auto calculate basic stats like ability modifiers.
    - [ ] Support Proficiency Bonuses 

### Cake
- [ ] Extend character creation to allow the user to use any of the three common stat gen methods.
    - [ ] Point Buy
    - [ ] Standard Array
    - [ ] Roll
- [ ] Extend the character sheet to all the info in the 5e official sheet.
- [ ] Allow for image uploads for character portraits.
- [ ] Allow for extended descriptions/backstories.
    - [ ] Characters should have nice full page backstories.
    - [ ] Preferably use a markdown editor.