JSFiddle - React, Tailwind, and code Playground

by Adam Doherty

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.1/css/foundation.min.css">
<script src="http://www.adamjld.com/sd/goose/ngStorage.min.js"></script>
<div id="main" ng-app="GameshowApp" ng-controller="GameshowAppController as g">
    <div class="row titleRow">
        <div class="small-6 columns">
             <h3>{{$storage.title}}</h3>

        </div>
        <div class="small-6 columns">
            <button ng-hide="$storage.teams.length == $storage.settings.maxTeams" class="addTeam" ng-click="addTeam()">Add Team ({{$storage.teams.length}}/{{$storage.settings.maxTeams}})</button>
            <button ng-show="$storage.teams.length == $storage.settings.maxTeams" class="addTeam disabled">Max Teams Reached ({{$storage.teams.length}}/{{$storage.settings.maxTeams}})</button>
        </div>
    </div>
    <div class="row generalSettings">
        <div class="small-6 columns">
            <label> <strong>Max Teams:</strong>

            </label>
            <input type="number" min="{{$storage.teams.length}}" ng-model="$storage.settings.maxTeams" />
        </div>
        <!--<div class="small-6 columns end">
            <label> <strong>Max Players per Team: </strong>

            </label>
            <input type="number" min="{{$storage.min}}" ng-model="$storage.min" />
        </div>--></div>
    <div class="row mainRow" ng-repeat="t in $storage.teams" data-equalizer>
        <div class="teamList small-6 columns" data-equalizer-watch>
            <div class="row">
                <div ng-show="t.name != null" class="small-9 columns teamName">
                    <strong>{{t.name}}</strong>
                </div>
                <div class="small-3 columns end">({{t.players.length}}/{{$storage.settings.maxPlayers}})</div>
            </div>
            <table ng-hide="t.players.length < 1" class="teamListTable small-12 columns" data-equalizer-watch>
                <thead>
                    <tr>
                       ...

CSS

.titleRow {
    padding-top: 20px;
    background: rgba(215, 215, 215, 0.4);
    border-bottom: 1px solid gray;
}
.mainRow, .generalSettings, .resetStartRow {
    margin-top: 20px;
}
.generalSettings {
    border-bottom: 1px solid gray;
    padding-bottom: 10px;
}
.generalSettings label {
    text-align: right;
    clear: both;
    float:left;
    margin-right:15px;
    margin-top: 3px;
}
.generalSettings input {
    width: 50px;
    padding: 0 5px;
}
.teamList, .teamSettings {
    border: 1px solid gray;
    padding-top: 0.9375rem;
}
.teamList .row, .teamSettings .row {
    margin-bottom:0.9375rem;
}
.teamList {
    border-radius: 5px 0px 0px 5px;
    min-height: 140px;
}
.teamListTable {
    padding-left: 0;
    padding-right: 0;
}
.teamSettings {
    border-radius: 0px 5px 5px 0px;
}
.row .row {
    height: 26px;
}
button {
    font-size: inherit;
    padding: 0.2em;
    margin: 0;
    /* the following ensures they're all using the same box-model for rendering */
    -moz-box-sizing: content-box;
    /* or `border-box` */
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
    /*height: 32px;*/
    width: 100%;
    border-radius: 3px;
}
button.addTeam {
    height: 32px;
}
input {
    height: 26px !important;
    margin-bottom: 0 !important;
}
.narrow {
    width: 1px;
}
.center {
    text-align: center;
}

JavaScript

angular.module('GameshowApp', ['ngStorage'])
    .controller('GameshowAppController', function ($scope, $localStorage) {
    $scope.$storage = $localStorage.$default({
        title: "Team Builder",
        settings: {
            maxTeams: 5,
            maxPlayers: 10
        },
        teams: [{
            id: 1,
            name: "Team Discovery Channel",
            players: [{
                name: "Martin Prince",
                captain: true
            }, {
                name: "Nelson Muntz",
                captain: false
            }],
            numOfPlayers: 2,
            points: 0
        }],
        count: 1
    });

    $scope.addTeam = function () {
        $scope.$storage.count++;
        $scope.$storage.teams.push({
            id: $scope.$storage.count,
            //name: "Unnamed Team #" + $scope.$storage.count,
            name: "Unnamed Team",
            players: [],
            numOfPlayers: 0,
            points: 0
        });
    };

    $scope.setTeamName = function (t) {
        t.name = this.teamName;
    };

    $scope.addPlayer = function (t) {
        this.duplicate = false;
        var playerName = this.playerName;
        angular.forEach(t.players, function (p) {
            if (angular.lowercase(playerName) == angular.lowercase(p.name)) {
                this.duplicate = true;
            }
        }, this);

        if (!this.duplicate) {
            t.players.push({
                name: playerName,
                captain: false
            });
            this.playerName = '';
        }
        t.numOfPlayers++;
    };

    $scope.setTeamCaptain = function (p, team) {
        angular.forEach(team.players, function (player) {
            player.captain = false;
        });
        p.captain = true;
    };

    $scope.removePlayer = function (p, team) {
        var index = team.indexOf(p);
        team.splice(index, 1);
        team.numOfPlayers--;
    };

    $scope.showYesOrNo = function () {
       ...