DEV Community

Ephriam Henderson
Ephriam Henderson

Posted on

Day 19 [D&D Character Sheet]

Report

This weekend I did a little debugging, not enough for a full report and not the full hour I'm supposed to do. Today I did quite a bit. I..

Edited the character schema to use the Die schema from the Race model.

First I moved the Die schema from the Race schema's file into a folder sharedSchemas/ specifically for embedded documents that will be reused across schema. I spent a while figuring out how I wanted to structure the files, I settled on putting sharedSchema outside of db/models into the the db module's root db/.

Created a logout route, and a button to trigger it.

First I create the logout route.

// router/users/index.js
router.get("/logout", (req, res) => {
    req.logout();
    res.redirect("/");
});

Then add a button to the navbar.

<!-- views/layouts/includes/navbar.ejs -->
<ul class="navbar-nav m-0 ml-auto">
    <% if (isSignedIn) { %>
        <!-- ... -->
        <li class="nav-item">
            <a href="/users/logout" class="nav-link">Logout</a>
        </li>
    <% } else { %>
        <li class="nav-item">
            <a href="/users/login" class="nav-link">Login</a>
        </li>
    <% } %>
</ul>

Created a Character List that displays the logged in player's characters.

I created a character list view, and a new route for viewing the logged-in users characters. This route will likely become more generic in the future, probably allowing anyone to veiw a user's published characters. Speaking of publishing, I'll also be adding an isPublished field to the character model that determines whether the character appears in searches. Here's the ejs for that list.

<!-- views/characters/characterList.ejs -->
<!-- The view is made to be generic for 
reuse in many different routes --> 
<div class="col-md h-100">
    <div class="d-flex justify-content-start">
        <% data.characters.forEach(character => { %>
        <div class="card" style="width: 18rem;">
            <img
                class="card-img-top"
                src="http://via.placeholder.com/215"
                alt="Card image cap"
            />
            <div class="card-body">
                <h5 class="card-title"><%= character.shortName %></h5>
                <p class="card-text text-truncate"><%= character.description %></p>
                <a href="/characters/<%= character.id %> " class="btn btn-primary"
                    >Go somewhere</a
                >
            </div>
        </div>
        <% }) %>
    </div>
</div>

And here's the route.

// router/users/index.js

// route: /users/characters/
router.get("/characters", async (req, res) => {
    // This should be removed
    logger.debug(`[/users/characters] user id: ${req.user.id}`);
    console.log(req.user);
    if (req.isAuthenticated) {
        const characters = await req.context.db.models.Character.find({
            player: req.user.id
        });
        console.log(characters);
        res.render("characters/characterList", {
            page: {
                title: "Your Characters"
            },
            data: {
                characters
            }
        });
    } else {
        res.redirect("/users/login");
    }
});

I also discovered a bug with my passport initialization that I fixed. I forgot to await the Player find method in my deserializeUser function. This led to req.user being an unresolved promise in my routes. I fixed it by adding the forgotten await.

// helpers/init-passport.js
passport.deserializeUser(async (id, done) => {
    logger.debug(`Deserializing user: ${id}`);
    const db = await dbPromise;
    // before:
    // let user = db.models.Player.findById(id);
    // after:
    let user = await db.models.Player.findById(id);
    done(null, user);
});

Thanks for Reading!

Project

[100days] The DND Character Sheet App

This is the first project of my 100 days of coding This is 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

  • 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…

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.

Top comments (0)