diff options
| -rw-r--r-- | app/Http/Controllers/VerbController.php | 86 | ||||
| -rw-r--r-- | app/Http/Middleware/Login.php | 34 | ||||
| -rw-r--r-- | app/Http/routes.php | 30 | ||||
| -rw-r--r-- | app/User.php | 9 | ||||
| -rw-r--r-- | app/Verb.php | 42 | ||||
| -rw-r--r-- | app/VerbAction.php | 41 | ||||
| -rw-r--r-- | bootstrap/app.php | 1 | ||||
| -rw-r--r-- | database/migrations/2016_09_04_081754_create_verb_actions_table.php | 38 | ||||
| -rw-r--r-- | database/migrations/2016_09_04_081924_add_active_to_verbs.php | 31 | ||||
| -rw-r--r-- | public/css/hebrewparsetrainer.css | 17 | ||||
| -rw-r--r-- | public/js/moderators.js | 57 | ||||
| -rw-r--r-- | resources/views/contribute.blade.php | 35 | ||||
| -rw-r--r-- | resources/views/layouts/master.blade.php | 33 | ||||
| -rw-r--r-- | resources/views/stats.blade.php | 51 | ||||
| -rw-r--r-- | resources/views/suggest.blade.php | 76 | ||||
| -rw-r--r-- | resources/views/suggestions.blade.php | 32 | 
16 files changed, 555 insertions, 58 deletions
| diff --git a/app/Http/Controllers/VerbController.php b/app/Http/Controllers/VerbController.php new file mode 100644 index 0000000..98b0579 --- /dev/null +++ b/app/Http/Controllers/VerbController.php @@ -0,0 +1,86 @@ +<?php +/** + * HebrewParseTrainer - practice Hebrew verbs + * Copyright (C) 2015  Camil Staps <info@camilstaps.nl> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +namespace App\Http\Controllers; + +use HebrewParseTrainer\Verb; +use HebrewParseTrainer\VerbAction; +use HebrewParseTrainer\RandomLog; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Input; +use Illuminate\Support\Facades\Auth; +use Laravel\Lumen\Routing\Controller as BaseController; + +class VerbController extends BaseController { + +	public function random() { +		$verbs = Verb::where('active', 1)->get(); +		foreach (Input::get() as $col => $val) { +			$val = explode(',', $val); +			$verbs = $verbs->filter(function(Verb $item) use ($col, $val) { +				return in_array($item->getAttribute($col), $val); +			}); +		} +		$verb = $verbs->random(); + +		$log = new RandomLog(); +		$log->request = json_encode(Input::get()); +		$log->response = $verb->id; +		$log->ip = $_SERVER['REMOTE_ADDR']; +		$log->save(); + +		$obj = ['verb' => $verb, 'answers' => $verb->otherParsings()]; +		return response()->json($obj); +	} + +	public function vote($choice, $verb_id) { +		$verb = Verb::findOrFail($verb_id); +		$user = Auth::user(); + +		if ($verb->active) +			return ['success' => false, 'message' => 'This verb has been accepted already.']; + +		foreach ($verb->actions()->where('kind', VerbAction::KIND_VOTE)->get() as $vote) { +			if ($vote->user->id == $user->id) { +				$vote->delete(); +			} +		} + +		$vote = new VerbAction; +		$vote->user_id = $user->id; +		$vote->verb_id = $verb_id; +		$vote->kind = VerbAction::KIND_VOTE; +		$vote->vote_weight = ($choice == 1 ? 1 : -1) * $user->voteWeight(); +		$vote->save(); + +		$message = 'You have voted.'; + +		if ($verb->voteCount() >= Verb::ACCEPTED_VOTE_COUNT) { +			$verb->active = 1; +			$verb->save(); +		} + +		return [ +			'success' => true, +			'vote_weight' => $user->voteWeight(), +			'accepted' => (bool) $verb->active, +			'new_vote_count' => $verb->voteCount() +		]; +	} + +} diff --git a/app/Http/Middleware/Login.php b/app/Http/Middleware/Login.php new file mode 100644 index 0000000..8a71104 --- /dev/null +++ b/app/Http/Middleware/Login.php @@ -0,0 +1,34 @@ +<?php + +namespace App\Http\Middleware; + +use Closure; +use Illuminate\Support\Facades\Auth; + +class Login { +	/** +	 * Create a new middleware instance. +	 * +	 * @param  \Illuminate\Contracts\Auth\Factory  $auth +	 * @return void +	 */ +	public function __construct() { +	} + +	/** +	 * Handle an incoming request. +	 * +	 * @param  \Illuminate\Http\Request  $request +	 * @param  \Closure  $next +	 * @param  string|null  $guard +	 * @return mixed +	 */ +	public function handle($request, Closure $next, $guard = null) { +		if ($request->has('login') && !Auth::check()) { +			return response('Unauthorized.', 401) +				->header('WWW-Authenticate', 'Basic realm="Please enter your email and password"'); +		} + +		return $next($request); +	} +} diff --git a/app/Http/routes.php b/app/Http/routes.php index 9cf12b4..8313029 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -29,7 +29,10 @@  */  $app->group( -	['prefix' => parse_url(env('APP_URL'), PHP_URL_PATH)], +	[ +		'prefix' => parse_url(env('APP_URL'), PHP_URL_PATH), +		'middleware' => 'login' +	],  	function ($app) {  		$app->get('/', function () use ($app) { @@ -44,15 +47,24 @@ $app->group(  			return \HebrewParseTrainer\Tense::all();  		}); +		$app->get('/verb/random', +			'App\Http\Controllers\VerbController@random'); +  		$app->get('/logout', function () use ($app) { -			return response('Unauthorized.', 401) -				->header('WWW-Authenticate', 'Basic realm="Please click OK, then Cancel to logout."'); +			return response('You have been logged out.', 401) +				->header( +					'WWW-Authenticate', +					'Basic realm="Please click OK, then Cancel to logout."');  		}); -		$app->get('/verb/random', 'App\Http\Controllers\RandomVerbController@show'); +		$app->get('/contribute', function () use ($app) { +			return view('contribute'); +		}); -		$app->get('/user/create', 'App\Http\Controllers\UserController@createForm'); -		$app->post('/user/create', 'App\Http\Controllers\UserController@createForm'); +		$app->get('/user/create', +			'App\Http\Controllers\UserController@createForm'); +		$app->post('/user/create', +			'App\Http\Controllers\UserController@createForm');  		$app->group(  			['middleware' => 'auth:basic-http'], @@ -62,6 +74,12 @@ $app->group(  					return view('stats');  				}); +				$app->get('/verb/{id}/vote/{choice}', +					'App\Http\Controllers\VerbController@vote'); + +				$app->post('/verb/suggest', +					'App\Http\Controllers\VerbController@suggest'); +  			});  }); diff --git a/app/User.php b/app/User.php index 3c1799d..dda14ca 100644 --- a/app/User.php +++ b/app/User.php @@ -28,6 +28,8 @@ class User extends Model implements Authenticatable {  	public $timestamps = false;  	protected $fillable = ['email', 'name']; +	const VOTE_WEIGHT_BASE = 5; +  	public function changePoints($kind, $change, $verb = null) {  		$change = new PointChange;  		$change->user = $this->id; @@ -40,6 +42,13 @@ class User extends Model implements Authenticatable {  		$this->save();  	} +	public function voteWeight() { +		if ($this->points <= 0) +			return 0; + +		return floor(log($this->points, self::VOTE_WEIGHT_BASE)); +	} +  	public function setPasswordAttribute($pass) {  		$this->attributes['password'] = Hash::make($pass);  	} diff --git a/app/Verb.php b/app/Verb.php index 28e22ea..aa0db26 100644 --- a/app/Verb.php +++ b/app/Verb.php @@ -22,14 +22,38 @@ use Illuminate\Database\Eloquent\Model;  class Verb extends Model { -    protected $table = 'verbs'; -    public $timestamps = false; -    protected $fillable = ['verb', 'root', 'stem', 'tense', 'person', 'gender', 'number']; +	protected $table = 'verbs'; +	public $timestamps = false; +	protected $fillable = ['verb', 'root', 'stem', 'tense', 'person', 'gender', 'number']; -    public function otherParsings() -    { -        return self::where('verb', $this->verb)->get() -            ->filter(function($v){return $v->verb === $this->verb;}); -    } +	const ACCEPTED_VOTE_COUNT = 1; -}
\ No newline at end of file +	public function actions() { +		return $this->hasMany('HebrewParseTrainer\VerbAction'); +	} + +	public function otherParsings() { +		return self::where('verb', $this->verb)->get() +			->filter(function($v){return $v->verb === $this->verb;}); +	} + +	public function voteCount() { +		$votes = $this->actions()->where('kind', VerbAction::KIND_VOTE)->get(); +		$total = 0; +		foreach ($votes as $vote) +			$total += $vote->vote_weight; +		return $total; +	} + +	public function userVote(User $user) { +		$votes = $this->actions() +			->where('kind', VerbAction::KIND_VOTE) +			->where('user_id', $user->id) +			->get(); +		foreach ($votes as $vote) { +			return $vote->vote_weight; +		} +		return 0; +	} + +} diff --git a/app/VerbAction.php b/app/VerbAction.php new file mode 100644 index 0000000..79c8cd0 --- /dev/null +++ b/app/VerbAction.php @@ -0,0 +1,41 @@ +<?php +/** + * HebrewParseTrainer - practice Hebrew verbs + * Copyright (C) 2015  Camil Staps <info@camilstaps.nl> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +namespace HebrewParseTrainer; + +use Illuminate\Database\Eloquent\Model; + +class VerbAction extends Model { + +	protected $table = 'verb_actions'; +	public $timestamps = false; +	protected $dates = ['date']; +	protected $fillable = ['user_id', 'verb_id', 'kind', 'vote_weight', 'comment_text']; + +	const KIND_SUGGEST = 1; +	const KIND_VOTE = 2; + +	public function verb() { +		return $this->belongsTo('HebrewParseTrainer\Verb'); +	} + +	public function user() { +		return $this->belongsTo('HebrewParseTrainer\User'); +	} + +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 04f448e..c72ab23 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -68,6 +68,7 @@ $app->singleton(  $app->routeMiddleware([  	'auth' => App\Http\Middleware\Authenticate::class, +	'login' => App\Http\Middleware\Login::class,  ]);  /* diff --git a/database/migrations/2016_09_04_081754_create_verb_actions_table.php b/database/migrations/2016_09_04_081754_create_verb_actions_table.php new file mode 100644 index 0000000..d7b0f29 --- /dev/null +++ b/database/migrations/2016_09_04_081754_create_verb_actions_table.php @@ -0,0 +1,38 @@ +<?php + +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreateVerbActionsTable extends Migration +{ +	/** +	 * Run the migrations. +	 * +	 * @return void +	 */ +	public function up() +	{ +		Schema::create('verb_actions', function (Blueprint $table) { +			$table->increments('id'); +			$table->integer('user_id')->unsigned(); +			$table->integer('verb_id')->unsigned(); +			$table->tinyInteger('kind'); +			$table->tinyInteger('vote_weight')->nullable(); +			$table->string('comment_text')->nullable(); +			$table->timestamp('date')->default(DB::raw('CURRENT_TIMESTAMP')); + +			$table->foreign('user_id')->references('id')->on('users'); +			$table->foreign('verb_id')->references('id')->on('verbs'); +		}); +	} + +	/** +	 * Reverse the migrations. +	 * +	 * @return void +	 */ +	public function down() +	{ +		Schema::drop('verb_actions'); +	} +} diff --git a/database/migrations/2016_09_04_081924_add_active_to_verbs.php b/database/migrations/2016_09_04_081924_add_active_to_verbs.php new file mode 100644 index 0000000..79c5993 --- /dev/null +++ b/database/migrations/2016_09_04_081924_add_active_to_verbs.php @@ -0,0 +1,31 @@ +<?php + +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class AddActiveToVerbs extends Migration +{ +	/** +	 * Run the migrations. +	 * +	 * @return void +	 */ +	public function up() +	{ +		Schema::table('verbs', function (Blueprint $table) { +			$table->boolean('active')->default(true); +		}); +	} + +	/** +	 * Reverse the migrations. +	 * +	 * @return void +	 */ +	public function down() +	{ +		Schema::table('verbs', function (Blueprint $table) { +			$table->dropColumn('active'); +		}); +	} +} diff --git a/public/css/hebrewparsetrainer.css b/public/css/hebrewparsetrainer.css index 54f0c2d..30ef258 100644 --- a/public/css/hebrewparsetrainer.css +++ b/public/css/hebrewparsetrainer.css @@ -20,6 +20,23 @@  	src: url('fonts/EzraSIL.ttf');  } +body { +	padding-top: 20px; +} + +.large { +	font-size: 150%; +} + +.header { +	border-bottom: 1px solid #e5e5e5; +	margin-bottom: 30px; +} + +.suggestions td { +	vertical-align: middle !important; +} +  #trainer-404 {  	display: none;  	padding: 15px; diff --git a/public/js/moderators.js b/public/js/moderators.js new file mode 100644 index 0000000..2b192f8 --- /dev/null +++ b/public/js/moderators.js @@ -0,0 +1,57 @@ +/** + * HebrewParseTrainer - practice Hebrew verbs + * Copyright (C) 2015  Camil Staps <info@camilstaps.nl> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +$(document).ready(function(){ +	$('.vote').click(function(){ +		var vote = parseInt($(this).data('vote')); +		var verbId = $(this).data('verb'); + +		var container = $(this).parent(); + +		$.ajax({ +			url: app_url + 'verb/' + verbId + '/vote/' + vote, +			success: function(data) { +				if (!data.success) { +					fail(data.message); +					return; +				} + +				var btns = container.find('.vote'); +				if (vote) { +					$(btns[0]).removeClass('btn-danger'); +					$(btns[0]).addClass('btn-default'); +					$(btns[1]).addClass('btn-success'); +					$(btns[1]).removeClass('btn-default'); +				} else { +					$(btns[0]).addClass('btn-danger'); +					$(btns[0]).removeClass('btn-default'); +					$(btns[1]).removeClass('btn-success'); +					$(btns[1]).addClass('btn-default'); +				} + +				container.find('.vote-count').text(data.new_vote_count); + +				if (data.accepted) { +					alert('This verb has now been accepted!'); +					container.parent().remove(); +				} +			} +		}); + +		return true; +	}); +}); diff --git a/resources/views/contribute.blade.php b/resources/views/contribute.blade.php new file mode 100644 index 0000000..4c3b6de --- /dev/null +++ b/resources/views/contribute.blade.php @@ -0,0 +1,35 @@ +@extends('layouts.master') + +@section('master-content') +<p class="lead"> +	Thank you for wanting to help out! To expand our database, we are looking for volunteers to enter more verbs. +</p> + +@if(!Auth::check()) +	<a class="btn btn-lg btn-primary" href="{{ env('APP_URL') }}contribute?login=yes">Login</a> +	<a class="btn btn-lg btn-success" href="{{ env('APP_URL') }}user/create">Sign up</a> +@endif + +<h3>Here's how it works:</h3> + +<ul> +	<li>Any user can <em>suggest new verbs</em>.</li> +	<li>These have to be <em>peer-reviewed</em> by other contributors.</li> +	<li>It has to get <em>five</em> votes to be accepted.</li> +	<li>Contributors <em>earn points</em> for all accepted verbs they suggested.</li> +	<li>The <em>vote weight</em> is dependent on the number of points a user has.</li> +</ul> + +@if(Auth::check()) +	<hr/> +	<div class="row"> +		<div class="col-lg-6"> +			@include('suggestions') +		</div> +		<div class="col-lg-6"> +			@include('suggest') +		</div> +	</div> +@endif + +@endsection diff --git a/resources/views/layouts/master.blade.php b/resources/views/layouts/master.blade.php index 3c111da..199db2d 100644 --- a/resources/views/layouts/master.blade.php +++ b/resources/views/layouts/master.blade.php @@ -16,17 +16,43 @@ GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program.  If not, see <http://www.gnu.org/licenses/>.   --> +<?php +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Request; + +$activePage = isset($activePage) ? $activePage : ''; +$menu = [ +	'Train' => ['/', ''], +	'Contribute' => ['contribute', 'contribute'], +]; + +if (Auth::check()) { +	$menu['Statistics'] = ['stats', 'stats']; +	$menu['Logout'] = ['logout', 'logout']; +} +?>  <html lang="en">  	<head>  		<meta charset="utf-8">  		<title>ParseTrainer</title>  		<link rel="stylesheet" href="{{ env('APP_URL') }}vendor/twbs/bootstrap/dist/css/bootstrap.min.css">  		<link rel="stylesheet" href="{{ env('APP_URL') }}public/css/hebrewparsetrainer.css"> + +		<script type="text/javascript"> +			var app_url = '{{ env('APP_URL') }}'; +		</script>  	</head>  	<body role="application">  		<div class="container" role="main"> -			<div class="page-header"> -				<h1>ParseTrainer</h1> +			<div class="header clearfix"> +				<nav> +					<ul class="nav nav-pills pull-right"> +						@foreach($menu as $name => $link) +							<li role="presentation" class="{{ Request::is($link[0]) ? 'active' : '' }}"><a href="{{ env('APP_URL') }}{{ $link[1] }}">{{ $name }}</a></li> +						@endforeach +					</ul> +				</nav> +				<h2 class="text-muted">ParseTrainer</h2>  			</div>  			@yield('master-content') @@ -35,5 +61,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  		<script src="{{ env('APP_URL') }}vendor/components/jquery/jquery.min.js"></script>  		<script src="{{ env('APP_URL') }}vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>  		<script src="{{ env('APP_URL') }}public/js/hebrewparsetrainer.js"></script> +		@if(Auth::check()) +			<script src="{{ env('APP_URL') }}public/js/moderators.js"></script> +		@endif  	</body>  </html> diff --git a/resources/views/stats.blade.php b/resources/views/stats.blade.php index f68c9ac..04fabfe 100644 --- a/resources/views/stats.blade.php +++ b/resources/views/stats.blade.php @@ -1,42 +1,3 @@ -<!DOCTYPE html> -<!-- -HebrewParseTrainer - practice Hebrew verbs -Copyright (C) 2015  Camil Staps <info@camilstaps.nl> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. - --> -<html lang="en"> -<head> -	<meta charset="utf-8"> -	<title>ParseTrainer statistics</title> -	<link rel="stylesheet" href="{{ url("/vendor/twbs/bootstrap/dist/css/bootstrap.min.css") }}"> -	<link rel="stylesheet" href="{{ url("/vendor/twbs/bootstrap/dist/css/bootstrap-theme.min.css") }}"> -	<link rel="stylesheet" href="{{ url("/public/css/hebrewparsetrainer.css") }}"> -</head> -<body role="application"> -<div class="container" role="main"> -	<div class="page-header"> -		<h1>ParseTrainer statistics</h1> -	</div> - -	<div class="row"> -		<div class="col-md-12"> -			<div id="statistics" style="height:400px;"></div> -		</div> -	</div> -</div> -  <?php  use \HebrewParseTrainer\RandomLog; @@ -53,6 +14,15 @@ foreach ($db_stats as $stat) {  $stats = "[" . implode(",", $stats) . "]";  ?> +@extends('layouts.master') + +@section('master-content') +<div class="row"> +	<div class="col-md-12"> +		<div id="statistics" style="height:400px;"></div> +	</div> +</div> +  <script src="{{ url("/vendor/components/jquery/jquery.min.js") }}"></script>  <script src="{{ url("/vendor/twbs/bootstrap/dist/js/bootstrap.min.js") }}"></script>  <script src="//code.highcharts.com/stock/highstock.js"></script> @@ -105,5 +75,4 @@ $stats = "[" . implode(",", $stats) . "]";  		]  	});  </script> -</body> -</html> +@endsection diff --git a/resources/views/suggest.blade.php b/resources/views/suggest.blade.php new file mode 100644 index 0000000..6a1ebe8 --- /dev/null +++ b/resources/views/suggest.blade.php @@ -0,0 +1,76 @@ +<?php +use HebrewParseTrainer\Root; +use HebrewParseTrainer\Tense; +use HebrewParseTrainer\Verb; +?> +<div class="panel panel-default"> +	<div class="panel-heading"> +		<h3 class="panel-title">Suggest a new verb</h3> +	</div> +	<div class="panel-body"> +		<form class="form-horizontal"> +			<div class="form-group"> +				<label for="suggest-verb" class="col-sm-2 control-label">Verb</label> +				<div class="col-sm-10"> +					<input type="text" class="form-control" id="suggest-verb" placeholder="קָטַל"/> +				</div> +			</div> +			<div class="form-group"> +				<label for="suggest-root" class="col-sm-2 control-label">Root</label> +				<div class="col-sm-10"> +					<select id="suggest-root" class="form-control"> +						@foreach(Root::all() as $root) +							<option value="{{ $root->id }}">{{{ $root->root }}}</option> +						@endforeach +					</select> +				</div> +			</div> +			<div class="form-group"> +				<label for="suggest-tense" class="col-sm-2 control-label">Tense</label> +				<div class="col-sm-10"> +					<select id="suggest-tense" class="form-control"> +						@foreach(Tense::all() as $tense) +							<option value="{{ $tense->id }}">{{{ $tense->abbreviation }}}: {{{ $tense->name }}}</option> +						@endforeach +					</select> +				</div> +			</div> +			<div class="form-group"> +				<label for="suggest-person" class="col-sm-2 control-label">Person</label> +				<div class="col-sm-10"> +					<select id="suggest-person" class="form-control"> +						<option value="">(none)</option> +						<option value="1">1</option> +						<option value="2">2</option> +						<option value="3">3</option> +					</select> +				</div> +			</div> +			<div class="form-group"> +				<label for="suggest-gender" class="col-sm-2 control-label">Gender</label> +				<div class="col-sm-10"> +					<select id="suggest-gender" class="form-control"> +						<option value="">(none)</option> +						<option value="m">masculine</option> +						<option value="f">feminine</option> +					</select> +				</div> +			</div> +			<div class="form-group"> +				<label for="suggest-number" class="col-sm-2 control-label">Number</label> +				<div class="col-sm-10"> +					<select id="suggest-number" class="form-control"> +						<option value="">(none)</option> +						<option value="s">singular</option> +						<option value="p">plural</option> +					</select> +				</div> +			</div> +			<div class="form-group"> +				<div class="col-sm-offset-2 col-sm-10"> +					<button type="submit" class="btn btn-primary">Suggest</button> +				</div> +			</div> +		</form> +	</div> +</div> diff --git a/resources/views/suggestions.blade.php b/resources/views/suggestions.blade.php new file mode 100644 index 0000000..dcec56a --- /dev/null +++ b/resources/views/suggestions.blade.php @@ -0,0 +1,32 @@ +<?php +use HebrewParseTrainer\Verb; +?> +<div class="panel panel-default"> +	<div class="panel-heading"> +		<h3 class="panel-title">Current suggestions</h3> +	</div> +	<div class="panel-body"> +		<table class="table table-hover table-condensed suggestions"> +			<tr> +				<th>Verb</th> +				<th>Root</th> +				<th>Parsing</th> +				<th>Votes</th> +			</tr> +			@forelse(Verb::where('active', 0)->orderBy('verb')->get() as $verb) +				<tr> +					<td class="large">{{ $verb->verb }}</td> +					<td class="large">{{ $verb->root }}</td> +					<td>{{ $verb->stem }} {{ $verb->tense }} {{ $verb->person }}{{ $verb->gender }}{{ $verb->number }}</td> +					<td> +						<button data-vote="0" data-verb="{{ $verb->id }}" class="vote btn btn-{{ $verb->userVote(Auth::user()) < 0 ? 'danger' : 'default' }}">-</button> +						<span class="vote-count btn">{{ $verb->voteCount() }}</span> +						<button data-vote="1" data-verb="{{ $verb->id }}" class="vote btn btn-{{ $verb->userVote(Auth::user()) > 0 ? 'success' : 'default' }}">+</button> +					</td> +				</tr> +			@empty +				<tr><td colspan="4">There are no active suggestions. Why not add a verb yourself?</td></tr> +			@endforelse +		</table> +	</div> +</div> | 
