Web frontend work

This commit is contained in:
Deon George 2021-05-13 22:40:21 +10:00
parent 834ece2645
commit 5e5d0d6c3d
20 changed files with 722 additions and 21 deletions

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Domain;
class DomainController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Add or edit a node
*/
public function add_edit(Request $request,Domain $o)
{
if ($request->post()) {
foreach (['name','dnsdomain','active','notes'] as $key)
$o->{$key} = $request->post($key);
$o->active = TRUE;
$o->save();
return redirect()->action([self::class,'home']);
}
return view('domain.addedit')
->with('o',$o);
}
public function home()
{
return view('domain.home');
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Node;
class NodeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Add or edit a node
*/
public function add_edit(Request $request,Node $o)
{
if ($request->post()) {
foreach ([
'zone_id','host_id','node_id','point_id',
'system','sysop','location','email',
'address','port','notes','software_id','protocol_id',
'sespass','pktpass','ticpass','fixpass'
] as $key)
$o->{$key} = $request->post($key);
foreach(['is_zc','is_rc','is_hub','is_host','active'] as $key)
$o->{$key} = $request->post($key,FALSE);
$o->save();
return redirect()->action([self::class,'home']);
}
return view('node.addedit')
->with('o',$o);
}
public function home()
{
return view('node.home');
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Zone;
class ZoneController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Add or edit a node
*/
public function add_edit(Request $request,Zone $o)
{
if ($request->post()) {
foreach (['zone_id','name','active','description','notes','domain_id'] as $key)
$o->{$key} = $request->post($key);
$o->active = TRUE;
$o->save();
return redirect()->action([self::class,'home']);
}
return view('zone.addedit')
->with('o',$o);
}
public function home()
{
return view('zone.home');
}
}

12
app/Models/Domain.php Normal file
View File

@ -0,0 +1,12 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Traits\ScopeActive;
class Domain extends Model
{
use ScopeActive;
}

View File

@ -6,18 +6,64 @@ use Illuminate\Database\Eloquent\Model;
class Node extends Model
{
protected $casts = [
'is_zc'=>'boolean',
'is_rc'=>'boolean',
'is_hub'=>'boolean',
'is_host'=>'boolean',
];
protected $fillable = ['zone_id','host_id','node_id','point_id'];
public function flags() {
/* SCOPES */
public function scopeHost()
{
}
/* RELATIONS */
/**
* Node nodelist flags
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function flags()
{
return $this->belongsToMany(Flag::class);
}
public function getFTNAttribute()
public function zone()
{
return sprintf('%s:%s/%s.%s',$this->zone_id,$this->host_id,$this->node_id,$this->point_id);
return $this->belongsTo(Zone::class);
}
public function hasFlag($relation, $model)
/* ATTRIBUTES */
/**
* Render the node name in full 5D
*
* @return string
*/
public function getFTNAttribute()
{
return $this->zone_id
? sprintf('%s:%s/%s.%s',$this->zone->zone_id,$this->host_id,$this->node_id,$this->point_id)
: '-';
}
/**
* Get this nodes uplink
*/
public function getUplinkAttribute()
{
// @todo Need to work this out properly
return static::where('zone_id','10')->where('host_id',1)->where('node_id',0)->where('point_id',0)->first();
}
/* METHODS */
public function hasFlag($relation,$model)
{
return (bool) $this->{$relation}()
->wherePivot($model->getForeignKey(),$model->{$model->getKeyName()})

9
app/Models/Protocol.php Normal file
View File

@ -0,0 +1,9 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Protocol extends Model
{
}

9
app/Models/Software.php Normal file
View File

@ -0,0 +1,9 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Software extends Model
{
}

View File

@ -10,6 +10,13 @@ class Zone extends Model
{
use ScopeActive;
/* RELATIONS */
public function domain()
{
return $this->belongsTo(Domain::class);
}
/* SCOPES */
/**

View File

@ -18,6 +18,8 @@ class CreateDomains extends Migration
$table->timestamps();
$table->string('name',8)->unique();
$table->string('dnsdomain')->nullable();
$table->string('notes')->nullable();
$table->boolean('active');
});
}

View File

@ -14,12 +14,13 @@ class CreateZones extends Migration
public function up()
{
Schema::create('zones', function (Blueprint $table) {
$table->integer('id')->primary();
$table->id();
$table->timestamps();
$table->integer('zone_id');
$table->string('description')->nullable();
$table->boolean('active')->default(TRUE);
$table->boolean('active');
$table->string('notes')->nullable();
$table->boolean('public')->default(TRUE);
$table->ipAddress('ipv4')->nullable();
@ -33,6 +34,8 @@ class CreateZones extends Migration
$table->binary('zt_id',10)->nullable()->unique();
$table->foreign('zt_id')->references('id')->on('zt');
$table->unique(['zone_id','domain_id']);
});
}

View File

@ -13,14 +13,32 @@ class CreateNodes extends Migration
*/
public function up()
{
Schema::create('protocols', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('name');
$table->integer('port')->nullable();
$table->boolean('active');
});
Schema::create('software', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('name');
$table->boolean('active');
});
Schema::create('nodes', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('zone_id')->index();
$table->integer('zone_id')->nullable()->index();
$table->foreign('zone_id')->references('id')->on('zones');
$table->integer('region_id')->nullable();
$table->integer('host_id')->index();
$table->integer('host_id')->nullable()->index();
$table->integer('hub_id')->nullable()->index();
$table->integer('node_id')->index();
$table->integer('node_id')->nullable()->index();
$table->integer('point_id')->default(0);
$table->boolean('active');
@ -28,15 +46,34 @@ class CreateNodes extends Migration
$table->string('system');
$table->string('sysop');
$table->string('location');
$table->integer('baud')->default('0');
$table->string('email')->nullable();
$table->string('address')->nullable();
$table->integer('port')->nullable();
$table->integer('baud')->nullable();
$table->string('phone')->nullable();
$table->string('notes')->nullable();
$table->binary('zt',10)->nullable();
$table->boolean('is_zc')->default(FALSE);
$table->boolean('is_rc')->default(FALSE);
$table->boolean('is_hub')->default(FALSE);
$table->boolean('is_host')->default(FALSE);
$table->string('sespass')->nullable();
$table->string('pktpass',8)->nullable();
$table->string('ticpass')->nullable();
$table->string('fixpass')->nullable();
$table->string('zt',10)->nullable();
$table->unique(['zone_id','host_id','node_id','point_id']);
$table->unique(['zone_id','zt']);
$table->foreign('zone_id')->references('id')->on('zones');
$table->integer('protocol_id')->nullable();
$table->foreign('protocol_id')->references('id')->on('protocols');
$table->integer('software_id')->nullable();
$table->foreign('software_id')->references('id')->on('software');
// $table->unique(['zone_id','host_id','id']);
// $table->index(['zone_id','host_id']);
@ -54,5 +91,7 @@ class CreateNodes extends Migration
public function down()
{
Schema::dropIfExists('nodes');
Schema::dropIfExists('protocols');
Schema::dropIfExists('software');
}
}

View File

@ -30,7 +30,8 @@ class InitialSetupSeeder extends Seeder
]);
DB::table('domains')->insert([
'name' => 'private',
'name'=>'private',
'active'=>TRUE,
]);
DB::table('zones')->insert([
@ -62,8 +63,9 @@ class InitialSetupSeeder extends Seeder
'opt_md'=>'1',
]);
DB::table('setup')->insert([
'node_id' => '1',
DB::table('node_setup')->insert([
'node_id'=>'1',
'setup_id'=>'1',
]);
}
}

View File

@ -0,0 +1,58 @@
@extends('layouts.app')
@section('htmlheader_title')
@if($o->exists) Update @else Add @endif Domain
@endsection
@section('main-content')
<div class="pb-3">
<h2>@if($o->exists) Update @else Add @endif Domain</h2>
<form method="POST">
{{ csrf_field() }}
<div class="row">
<div class="col-9 m-auto">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="name">Name:</label>
<input class="col-9" type="text" name="name" value="{{ $o->name }}">
</div>
<div class="row m-3">
<label class="col-3" for="dnsdomain">DNS Domain:</label>
<input class="col-9" type="text" name="dnsdomain" value="{{ $o->dnsdomain }}">
</div>
<div class="row m-3">
<label class="col-3" for="active">Active:</label>
<div class="form-group col-3">
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="active" id="active_yes" value="1" required @if($o->active)checked @endif>
<label class="custom-control-label" for="active_yes">Yes</label>
</div>
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="active" id="active_no" value="0" required @if(! $o->active)checked @endif>
<label class="custom-control-label" for="active_no">No</label>
</div>
</div>
</div>
<div class="row m-3">
<label class="col-3" for="notes">Notes:</label>
<textarea class="col-9" rows=3 cols=68 name="notes" placeholder="Notes...">{{ $o->notes }}</textarea>
</div>
<div class="row m-3">
<div class="col-12">
<button type="submit" name="submit" class="btn btn-lg btn-success mr-0 float-right">@if ($o->exists)Save @else Add @endif</button>
<a href="{{ url('/') }}" class="btn btn-lg btn-primary float-right">Cancel</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,45 @@
@extends('layouts.app')
@section('main-content')
<div class="row">
<div class="col-6">
<table class="table table-bordered m-5">
<thead>
<tr>
<th>ID</th>
<th>Active</th>
<th>Domain</th>
<th>DNS domain</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4"><a href="{{ url('ftn/domain/addedit') }}">Add New Domain</a></td>
</tr>
@foreach (\App\Models\Domain::cursor() as $oo)
<tr>
<td><a href="{{ url('ftn/domain/addedit',[$oo->id]) }}">{{ $oo->id }}</a></td>
<td>{{ $oo->active ? 'YES' : 'NO' }}</td>
<td>{{ $oo->name }}</td>
<td>{{ $oo->dnsdomain }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('table tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
</script>
@append

View File

@ -22,9 +22,9 @@
<li class="nav-item dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="false" aria-expanded="false"> <span class="nav-label">FTN </span></a>
<ul class="dropdown-menu">
<li class="nav-item"><a class="dropdown-item disabled" href="{{ url('ftn/domains') }}">Domains</a></li>
<li class="nav-item"><a class="dropdown-item disabled" href="{{ url('ftn/zones') }}">Zones</a></li>
<li class="nav-item"><a class="dropdown-item disabled" href="{{ url('ftn/nodes') }}">Nodes</a></li>
<li class="nav-item"><a class="dropdown-item" href="{{ url('ftn/domain') }}">Domains</a></li>
<li class="nav-item"><a class="dropdown-item" href="{{ url('ftn/zone') }}">Zones</a></li>
<li class="nav-item"><a class="dropdown-item" href="{{ url('ftn/node') }}">Nodes</a></li>
</ul>
</li>
@endauth

View File

@ -0,0 +1,166 @@
@extends('layouts.app')
@section('htmlheader_title')
@if($o->exists) Update @else Add @endif Node
@endsection
@section('main-content')
<div class="pb-3">
<h2>@if($o->exists) Update @else Add @endif Node</h2>
<form method="POST">
{{ csrf_field() }}
<div class="row">
<div class="col-3">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="zone_id">Zone</label>
<select class="col-9" name="zone_id">
<option value="">&nbsp;</option>
@foreach (\App\Models\Zone::cursor() as $oo)
<option value="{{ $oo->id }}" @if($o->zone_id==$oo->id)selected @endif>{{ $oo->zone_id }} ({{ $oo->name }})</option>
@endforeach
</select>
</div>
<div class="row m-3">
<label class="col-3" for="host_id">Hub</label>
<select class="col-9" name="hub_id">
<option value="{{ $o->hub_id }}" disabled>{{ $o->hub_id }} ({{ $o->system }})</option>
</select>
</div>
<div class="row m-3">
<label class="col-3" for="host_id">Host</label>
<select class="col-9" name="host_id">
<option value="{{ $o->host_id }}" selected>{{ $o->host_id }} ({{ $o->system }})</option>
</select>
</div>
<div class="row m-3">
<label class="col-3" for="node_id">Node</label>
<input class="col-9" type="text" name="node_id" value="{{ $o->node_id }}">
</div>
<div class="row m-3">
<label class="col-3" for="point_id">Point</label>
<input class="col-9" type="text" name="point_id" value="{{ $o->point_id ?: 0 }}">
</div>
<hr>
<div class="row m-3">
<label class="col-4" for="is_rc">Is ZC</label>
<input class="col-3" type="checkbox" name="is_rc" value="1" @if($o->is_rc)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_rc">Is RC</label>
<input class="col-3" type="checkbox" name="is_rc" value="1" @if($o->is_regis_rcion)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_hub">Is Hub</label>
<input class="col-3" type="checkbox" name="is_hub" value="1" @if($o->is_hub)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="is_host">Is Host</label>
<input class="col-3" type="checkbox" name="is_host" value="1" @if($o->is_host)checked @endif>
</div>
<div class="row m-3">
<label class="col-4" for="active">Active</label>
<input class="col-3" type="checkbox" name="active" value="1" @if($o->active)checked @endif>
</div>
</div>
</div>
<div class="col-9">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="system">BBS Name:</label>
<input class="col-9" type="text" name="system" value="{{ $o->system }}">
</div>
<div class="row m-3">
<label class="col-3" for="sysop">SYSOP Name:</label>
<input class="col-9" type="text" name="sysop" value="{{ $o->sysop }}">
</div>
<div class="row m-3">
<label class="col-3" for="email">Email Address:</label>
<input class="col-9" type="email" name="email" value="{{ $o->email }}">
</div>
<div class="row m-3">
<label class="col-3" for="location">System Location:</label>
<input class="col-9" type="text" name="location" value="{{ $o->location }}">
</div>
<div class="row m-3">
<label class="col-2" for="protocol_id">Connection Method:</label>
<div class="form-group col-2">
@foreach (\App\Models\Protocol::cursor() as $oo)
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="protocol_id" id="{{ $oo->id }}" value="{{ $oo->id }}" required @if($o->protocol_id==$oo->id)checked @endif>
<label class="custom-control-label" for="{{ $oo->id }}">{{ $oo->name }}</label>
</div>
@endforeach
</div>
<div class="col-8">
<div class="row m-3">
<label class="col-4" for="address">Mailer Address:</label>
<input class="col-8" type="text" name="address" value="{{ $o->address }}">
</div>
<div class="row m-3">
<label class="col-4" for="port">Mailer Port:</label>
<input class="col-4" type="text" name="port" value="{{ $o->port }}">
</div>
<div class="row m-3">
<label class="col-4" for="software_id">Mailer Software:</label>
<select class="col-8" name="software_id">
<option value="">&nbsp;</option>
@foreach (\App\Models\Software::cursor() as $oo)
<option value="{{ $oo->id }}" @if($o->protocol_id==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach
</select>
</div>
<div class="row m-3">
<label class="col-4" for="sespass">Session Password:</label>
<input class="col-4" type="text" name="sespass" value="{{ $o->sespass }}">
</div>
<div class="row m-3">
<label class="col-4" for="pktpass">Packet Password:</label>
<input class="col-4" type="text" name="pktpass" value="{{ $o->pktpass }}">
</div>
<div class="row m-3">
<label class="col-4" for="ticpass">TIC Password:</label>
<input class="col-4" type="text" name="ticpass" value="{{ $o->ticpass }}">
</div>
<div class="row m-3">
<label class="col-4" for="fixpass">Areafix Password:</label>
<input class="col-4" type="text" name="fixpass" value="{{ $o->fixpass }}">
</div>
</div>
</div>
<div class="row m-3">
<label class="col-3" for="notes">Notes:</label>
<textarea class="col-9" rows=3 cols=68 name="notes" placeholder="Notes...">{{ $o->notes }}</textarea>
</div>
<div class="row m-3">
<div class="col-12">
<button type="submit" name="submit" class="btn btn-lg btn-success mr-0 float-right">@if ($o->exists)Save @else Add @endif</button>
<a href="{{ url('/') }}" class="btn btn-lg btn-primary float-right">Cancel</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,49 @@
@extends('layouts.app')
@section('main-content')
<div class="row">
<div class="col-6">
<table class="table table-bordered m-5">
<thead>
<tr>
<th>ID</th>
<th>Domain</th>
<th>Node</th>
<th>Active</th>
<th>System</th>
<th>Sysop</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4"><a href="{{ url('ftn/node/addedit') }}">Add New Node</a></td>
</tr>
@foreach (\App\Models\Node::with(['zone'])->cursor() as $oo)
<tr>
<td><a href="{{ url('ftn/node/addedit',[$oo->id]) }}">{{ $oo->id }}</a></td>
<td>@if ($oo->zone_id){{ $oo->zone->name }}@else - @endif</td>
<td>{{ $oo->ftn }}</td>
<td>{{ $oo->active ? 'YES' : 'NO' }}</td>
<td>{{ $oo->system }}</td>
<td>{{ $oo->sysop }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('table tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
</script>
@append

View File

@ -0,0 +1,73 @@
@extends('layouts.app')
@section('htmlheader_title')
@if($o->exists) Update @else Add @endif Zone
@endsection
@section('main-content')
<div class="pb-3">
<h2>@if($o->exists) Update @else Add @endif Zone</h2>
<form method="POST">
{{ csrf_field() }}
<div class="row">
<div class="col-9 m-auto">
<div class="bg-blue">
<div class="row m-3">
<label class="col-3" for="zone_id">Zone:</label>
<input class="col-2" type="text" name="zone_id" value="{{ $o->zone_id }}">
</div>
<div class="row m-3">
<label class="col-3" for="name">Name:</label>
<input class="col-9" type="text" name="name" value="{{ $o->name }}">
</div>
<div class="row m-3">
<label class="col-3" for="domain_id">Domain:</label>
<select class="col-3" name="domain_id">
<option value="">&nbsp;</option>
@foreach (\App\Models\Domain::active()->cursor() as $oo)
<option value="{{ $oo->id }}" @if($o->domain_id==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach
</select>
</div>
<div class="row m-3">
<label class="col-3" for="description">Description:</label>
<input class="col-9" type="text" name="description" value="{{ $o->description }}">
</div>
<div class="row m-3">
<label class="col-3" for="active">Active:</label>
<div class="form-group col-3">
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="active" id="active_yes" value="1" required @if($o->active)checked @endif>
<label class="custom-control-label" for="active_yes">Yes</label>
</div>
<div class="custom-control custom-radio mb-3">
<input type="radio" class="custom-control-input" name="active" id="active_no" value="0" required @if(! $o->active)checked @endif>
<label class="custom-control-label" for="active_no">No</label>
</div>
</div>
</div>
<div class="row m-3">
<label class="col-3" for="notes">Notes:</label>
<textarea class="col-9" rows=3 cols=68 name="notes" placeholder="Notes...">{{ $o->notes }}</textarea>
</div>
<div class="row m-3">
<div class="col-12">
<button type="submit" name="submit" class="btn btn-lg btn-success mr-0 float-right">@if ($o->exists)Save @else Add @endif</button>
<a href="{{ url('/') }}" class="btn btn-lg btn-primary float-right">Cancel</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@ -0,0 +1,45 @@
@extends('layouts.app')
@section('main-content')
<div class="row">
<div class="col-6">
<table class="table table-bordered m-5">
<thead>
<tr>
<th>ID</th>
<th>Active</th>
<th>Zone</th>
<th>Domain</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="4"><a href="{{ url('ftn/zone/addedit') }}">Add New Zone</a></td>
</tr>
@foreach (\App\Models\Zone::cursor() as $oo)
<tr>
<td><a href="{{ url('ftn/zone/addedit',[$oo->id]) }}">{{ $oo->zone_id }}</a></td>
<td>{{ $oo->active ? 'YES' : 'NO' }}</td>
<td>{{ $oo->name }}</td>
<td>{{ $oo->domain->name }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('table tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
</script>
@append

View File

@ -3,7 +3,7 @@
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\{HomeController,DomainController,NodeController,ZoneController};
use App\Http\Controllers\Auth\LoginController;
/*
@ -28,6 +28,18 @@ Auth::routes([
Route::get('logout',[LoginController::class,'logout']);
Route::get('/',[HomeController::class,'welcome']);
Route::get('network/{name}',[HomeController::class,'network']);
Route::get('home',[HomeController::class,'home']);
Route::get('ftn/domain',[DomainController::class,'home']);
Route::match(['get','post'],'ftn/domain/addedit/{o?}',[DomainController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/node',[NodeController::class,'home']);
Route::match(['get','post'],'ftn/node/addedit/{o?}',[NodeController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/zone',[ZoneController::class,'home']);
Route::match(['get','post'],'ftn/zone/addedit/{o?}',[ZoneController::class,'add_edit'])
->where('o','[0-9]+');
Route::get('ftn/network/{name}',[HomeController::class,'network']);