Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions lib/admin/admin.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.tl-admin-header {
display: grid;
grid-template-columns: 60px 4fr 1fr 1fr;
}

.tl-header-name {
line-height: 56px;
}

.tl-start-tab-panel {
color: black;
background-color: white;
margin: 0 20%;
}

.tl-logo {
height: 40px;
padding: 10% 10% 10% 20%;
}

.new-tutorial-content {
display: grid;
grid-template-columns: repeat(2, 1fr);
background-color: white;
color: black;
margin: 0 10%;
height: 77vh;
}

.title-input, .submit-new-tutorial-box {
margin: auto;
margin-bottom: 5px;
text-align: center;
width: 80%;
}

.title-input {
color: black;
background-color: white;
}

.title-input material-input {
width: 90%;
}

.submit-new-tutorial-box {
padding: 5px 0;
margin-top: 5px;
}

material-button.create-btn[disabled] {
background-color: rgba(0, 191, 255, 0.51);
}

.create-btn {
color: white;
background-color: deepskyblue;
}

.btn-cancel {
color: #212121;
}

.btn-confirm {
color: deepskyblue;
}

material-dialog {
color: black;
font-family: Helvetica, Arial, sans-serif;
}

.CodeMirror {
height: auto;
overflow-y: hidden;
overflow-x: auto;
}

.new-tutorial-textarea-header {
display: grid;
grid-template-columns: repeat(2, 1fr);
color: black;
margin: 0 10%;
}

.new-tutorial-textarea-header div {
text-align: center;
padding: 5px 0;
}

.textarea-header-desc {
background-color: white;
color: rgba(0, 0, 0, 0.54);
}

.textarea-header-source {
background-color: #263238;
color: rgba(233, 237, 237, 0.54);
}

.textarea-header-desc div, .textarea-header-source div {
width: 80%;
margin: auto
}

.textarea-header-desc div {
border-bottom: 1px solid rgba(0, 0, 0, 0.54);
}

.textarea-header-source div {
border-bottom: 1px solid rgba(233, 237, 237, 0.54);
}
97 changes: 97 additions & 0 deletions lib/admin/admin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import 'dart:async';
import 'dart:html';
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
import 'package:angular_router/angular_router.dart';
import 'package:client/service/trylinks_service.dart';
import 'package:codemirror/codemirror.dart';

@Component(
selector: 'admin',
templateUrl: 'admin.html',
styleUrls: const ['admin.css'],
providers: const [overlayBindings],
directives: const [
materialDirectives
])

class AdminPageComponent implements OnInit {
String title;
CodeMirror descEditor;
CodeMirror sourceEditor;
String errorMsg;
bool confirmTutorialCreation = false;
bool validatedInput = false;
bool success;

TryLinksService _service;
Router _router;

AdminPageComponent(this._router, this._service);

@override
Future ngOnInit() async {
if (!_service.isAdmin()) {
_router.navigate(['Dashboard']);
}

success = null;

Map descOptions = {
'mode': 'markdown',
'autofocus': true,
'lineWrapping': true,
'indentWithTabs': true,
};

Map sourceOptions = {
'mode': 'links',
'theme': 'material',
'lineNumbers': true,
'lineWrapping': true,
'indentWithTabs': true,
};

this.descEditor = new CodeMirror.fromTextArea(
querySelector('textarea.new-tutorial-desc'),
options: descOptions);
this.descEditor.setSize('100%', '77vh');

this.sourceEditor = new CodeMirror.fromTextArea(
querySelector('textarea.new-tutorial-editor'),
options: sourceOptions);
this.sourceEditor.setSize('100%', '77vh');
}

Future onCreateTutorial() async {
final result = await _service.createTutorial(
title, this.descEditor.getDoc().getValue(), this.sourceEditor.getDoc().getValue());

if (result != true) {
this.success = false;
print('Failed to create a new tutorial');
} else {
this.success = true;
this.title = null;
this.descEditor.getDoc().setValue('');
this.sourceEditor.getDoc().setValue('');
}
}

void openModal() {
this.confirmTutorialCreation = true;
this.validatedInput = this.title != null && this.title != '' &&
this.descEditor.getDoc().getValue() != null &&
this.descEditor.getDoc().getValue() != '' &&
this.sourceEditor.getDoc().getValue() != null &&
this.sourceEditor.getDoc().getValue() != '';
}

void gotoDashboard() => _router.navigate(['Dashboard']);

Future logout() async {
await _service.logout();
_router.navigate(['Welcome']);
}

}
80 changes: 80 additions & 0 deletions lib/admin/admin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<div class="tl-admin-header">
<img class="tl-logo" src="img/logo.svg" alt="Links Logo">
<div class="tl-header-name">Try Links Admin Mode: Add a new tutorial</div>
<material-button dense (trigger)="gotoDashboard()">Dashboard</material-button>
<material-button dense class="tl-logout-button" (trigger)="logout()">Log out</material-button>
</div>

<material-content>
<div class="title-input">
<material-input required
floatingLabel
[error]="errorMsg"
[(ngModel)]="title"
(inputKeyPress)="errorMsg = '';"
label="Title"
type="text">
</material-input>
</div>
<div class="new-tutorial-textarea-header">
<div class="textarea-header-desc"><div>Description</div></div>
<div class="textarea-header-source"><div>Initial Source Code</div></div>
</div>
<div class="new-tutorial-content">
<textarea class="new-tutorial-desc CodeMirror-scroll"
placeholder="Description of the tutorial goes here. Use the Markdown syntax."></textarea>
<textarea class="new-tutorial-editor CodeMirror-scroll"
placeholder="The initial code the user is given goes here"></textarea>
</div>
<div class="submit-new-tutorial-box">
<material-button class="create-btn" raised (trigger)="openModal()">
Create a tutorial
</material-button>
</div>

<modal [visible]="confirmTutorialCreation && validatedInput"
(dismiss)="confirmTutorialCreation = false">
<material-dialog>
<div header><h3>Create a new tutorial?</h3></div>
<p>A new tutorial will be instantly added to the current tutorials and available for other users.</p>
<div footer>
<material-button class="btn-cancel" (trigger)="confirmTutorialCreation = false">Cancel</material-button>
<material-button class="btn-confirm" (trigger)="confirmTutorialCreation = false; onCreateTutorial()">Confirm</material-button>
</div>
</material-dialog>
</modal>

<modal [visible]="confirmTutorialCreation && !validatedInput"
(dismiss)="confirmTutorialCreation = false">
<material-dialog>
<div header><h3>Invalid input</h3></div>
<p>All the fields are required to be completed.</p>
<div footer>
<material-button class="btn-confirm" (trigger)="confirmTutorialCreation = false">OK</material-button>
</div>
</material-dialog>
</modal>

<modal [visible]="success == true"
(dismiss)="success = null">
<material-dialog>
<div header><h3>Success!</h3></div>
<p>Tutorial has been successfully created.</p>
<div footer>
<material-button class="btn-confirm" (trigger)="success = null">OK</material-button>
</div>
</material-dialog>
</modal>

<modal [visible]="success == false"
(dismiss)="success = null">
<material-dialog>
<div header><h3>Something went wrong!</h3></div>
<p>Unfortunately, tutorial could not be created.</p>
<div footer>
<material-button class="btn-confirm" (trigger)="success = null">OK</material-button>
</div>
</material-dialog>
</modal>

</material-content>
2 changes: 2 additions & 0 deletions lib/app_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:client/interactive/interactive.dart';
import 'package:client/start/start.dart';
import 'package:client/tutorial/tutorial.dart';
import 'package:client/welcome/welcome.dart';
import 'package:client/admin/admin.dart';

// AngularDart info: https://webdev.dartlang.org/angular
// Components info: https://webdev.dartlang.org/components
Expand Down Expand Up @@ -38,5 +39,6 @@ import 'package:client/welcome/welcome.dart';
path: '/tutorial/:id',
name: 'Tutorial',
component: TutorialPageComponent),
const Route(path: '/admin', name: 'Admin', component: AdminPageComponent),
])
class AppComponent {}
5 changes: 5 additions & 0 deletions lib/dashboard/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
grid-column: 10 / 12;
}

.tl-admin-button {
grid-row: 1 / 2;
grid-column: 8 / 10;
}

.tl-dashboard-interactive {
grid-row: 3 / 4;
grid-column: 2 / 6;
Expand Down
7 changes: 7 additions & 0 deletions lib/dashboard/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import 'package:client/service/trylinks_service.dart';
styleUrls: const ['dashboard.css'],
directives: const [
materialDirectives,
NgIf
],
)
class DashboardPageComponent implements OnInit {
Router _router;
TryLinksService _service;
String username;
bool isAdmin;

DashboardPageComponent(this._router, this._service);

Expand All @@ -30,6 +32,10 @@ class DashboardPageComponent implements OnInit {
]);
}

void gotoAdmin() {
_router.navigate(['Admin']);
}

Future logout() async {
await _service.logout();
_router.navigate(['Welcome']);
Expand All @@ -42,5 +48,6 @@ class DashboardPageComponent implements OnInit {
username = 'user';
_router.navigate(['Welcome']);
}
this.isAdmin = _service.isAdmin();
}
}
1 change: 1 addition & 0 deletions lib/dashboard/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<img src="img/logo.svg" alt="Links Logo">
</div>
<div class="tl-welcome-msg">Hello, {{username}}</div>
<material-button *ngIf="isAdmin" dense class="tl-admin-button" (trigger)="gotoAdmin()">Modify Tutorials</material-button>
<material-button dense class="tl-logout-button" (trigger)="logout()">Log out</material-button>
<div class="tl-dashboard-interactive">
<h3 class="tl-dashboard-content-header">Interactive Mode</h3>
Expand Down
File renamed without changes.
Loading