Adedd front-end support for validation and some other minor UI improvements.
This commit is contained in:
parent
cbc49f1037
commit
75b0d09974
@ -1 +1 @@
|
|||||||
{}
|
{"i6bxw12wk2k5lzpk":{"number":32,"timestamp":1572855599882,"message":"Henl"}}
|
@ -1 +1 @@
|
|||||||
{"data":[false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,true,false,false,false,false,true,false,false,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false]}
|
[false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,true,false,false,false,false,true,false,false,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false]
|
||||||
|
@ -7,7 +7,7 @@ const path = __dirname + '/../database/data.json'
|
|||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', function(req, res, next) {
|
router.get('/', function(req, res, next) {
|
||||||
res.json(JSON.parse(fs.readFileSync(path).toString()));
|
res.json({ result: { success: true, data: JSON.parse(fs.readFileSync(path).toString())}});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/login', (req, res, _next) => {
|
router.post('/login', (req, res, _next) => {
|
||||||
@ -21,7 +21,7 @@ router.post('/login', (req, res, _next) => {
|
|||||||
router.post('/update/:index', (req, res, _next) => {
|
router.post('/update/:index', (req, res, _next) => {
|
||||||
if (req.body.username === 'Mediatheek' && req.body.password === '@MediatheekHetHeerenlanden!') {
|
if (req.body.username === 'Mediatheek' && req.body.password === '@MediatheekHetHeerenlanden!') {
|
||||||
const data = JSON.parse(fs.readFileSync(path).toString());
|
const data = JSON.parse(fs.readFileSync(path).toString());
|
||||||
data.data[Number(req.params.index)] = data.data[Number(req.params.index)] ? false : true;
|
data[Number(req.params.index)] = data[Number(req.params.index)] ? false : true;
|
||||||
fs.writeFileSync(path, JSON.stringify(data));
|
fs.writeFileSync(path, JSON.stringify(data));
|
||||||
}
|
}
|
||||||
res.send(null);
|
res.send(null);
|
||||||
|
@ -15,8 +15,19 @@ const readJsonFile = (file) => {
|
|||||||
return JSON.parse(fs.readFileSync(path.join(__dirname, file)).toString());
|
return JSON.parse(fs.readFileSync(path.join(__dirname, file)).toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** This function is for the validation of the email address.
|
||||||
|
* Required arguments (in POST) are:
|
||||||
|
* email: string
|
||||||
|
* message: string
|
||||||
|
* number: number
|
||||||
|
* name: string
|
||||||
|
*/
|
||||||
router.post('/', (req, res, _next) => {
|
router.post('/', (req, res, _next) => {
|
||||||
|
|
||||||
|
// Generate an id.
|
||||||
const id = uniqid();
|
const id = uniqid();
|
||||||
|
|
||||||
|
// Send an email with a link to validate the id.
|
||||||
sendmail({
|
sendmail({
|
||||||
from: 'surpise-box@jobbel.nl',
|
from: 'surpise-box@jobbel.nl',
|
||||||
to: req.body.email,
|
to: req.body.email,
|
||||||
@ -24,6 +35,7 @@ router.post('/', (req, res, _next) => {
|
|||||||
html: `
|
html: `
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
|
<p>Beste ${req.body.name},</p>
|
||||||
<p>
|
<p>
|
||||||
Deze email is verzonden omdat u surprise box ${req.body.number} voor de kerstmarkt van Het Heerenlanden heeft aangevraagd.<br>
|
Deze email is verzonden omdat u surprise box ${req.body.number} voor de kerstmarkt van Het Heerenlanden heeft aangevraagd.<br>
|
||||||
Om uw aanvraag te bevestigen, moet u om de volgende link klikken:<br>
|
Om uw aanvraag te bevestigen, moet u om de volgende link klikken:<br>
|
||||||
@ -34,22 +46,38 @@ router.post('/', (req, res, _next) => {
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
|
|
||||||
|
// Once it is sent
|
||||||
}, function(err, reply) {
|
}, function(err, reply) {
|
||||||
|
|
||||||
|
// If there's an error
|
||||||
if (err) {
|
if (err) {
|
||||||
|
// Notify the front-end
|
||||||
res.json({result: {success: false, data: err}});
|
res.json({result: {success: false, data: err}});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Add the user's data to the database identified by the id.
|
||||||
writeJsonFile(confirmationsPath, {
|
writeJsonFile(confirmationsPath, {
|
||||||
|
// Make sure that the other records are preserved.
|
||||||
...readJsonFile(confirmationsPath),
|
...readJsonFile(confirmationsPath),
|
||||||
|
// Then add the new one
|
||||||
[id]: {
|
[id]: {
|
||||||
|
'name': req.body.name,
|
||||||
'number': Number(req.body.number),
|
'number': Number(req.body.number),
|
||||||
'timestamp': Date.now()
|
'timestamp': Date.now(),
|
||||||
|
'message': req.body.message
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// Notify the front-end
|
||||||
res.json({result: {success: true, data: reply}});
|
res.json({result: {success: true, data: reply}});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** This function is used when a user clicks on the link in their email.
|
||||||
|
*
|
||||||
|
* This should be extremely user-friendly.
|
||||||
|
*/
|
||||||
router.get('/validate/:id', (req, res, _next) => {
|
router.get('/validate/:id', (req, res, _next) => {
|
||||||
const data = readJsonFile(confirmationsPath);
|
const data = readJsonFile(confirmationsPath);
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
@ -58,7 +86,8 @@ router.get('/validate/:id', (req, res, _next) => {
|
|||||||
if (data[id] && Date.now() <= (data[id].timestamp + 3600000 /* one hour in milliseconds */)) {
|
if (data[id] && Date.now() <= (data[id].timestamp + 3600000 /* one hour in milliseconds */)) {
|
||||||
|
|
||||||
// send success result
|
// send success result
|
||||||
res.json({result: {success: true, data: data[id].number}});
|
// res.json({result: {success: true, data: data[id].number}});
|
||||||
|
res.render('validate-success', {number: data[id].number})
|
||||||
|
|
||||||
// Delete the record
|
// Delete the record
|
||||||
delete data[id];
|
delete data[id];
|
||||||
@ -69,7 +98,8 @@ router.get('/validate/:id', (req, res, _next) => {
|
|||||||
if (data[id] && Date.now() > (data[id].timestamp + 3600000)) {
|
if (data[id] && Date.now() > (data[id].timestamp + 3600000)) {
|
||||||
|
|
||||||
// send result
|
// send result
|
||||||
res.json({result: {success: false, data: 'expired'}});
|
//res.json({result: {success: false, data: 'expired'}});
|
||||||
|
res.render('validate-error', {data: 'expired', number: data[id].number });
|
||||||
|
|
||||||
// delete the record
|
// delete the record
|
||||||
delete data[id];
|
delete data[id];
|
||||||
@ -77,7 +107,8 @@ router.get('/validate/:id', (req, res, _next) => {
|
|||||||
|
|
||||||
// If the id is not found
|
// If the id is not found
|
||||||
} else {
|
} else {
|
||||||
res.json({result: {success: false, data: 'ID not found'}});
|
//res.json({result: {success: false, data: 'ID not found'}});
|
||||||
|
res.render('validate-error', {data: 'not found'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
8
server/views/validate-error.pug
Normal file
8
server/views/validate-error.pug
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
extends layout.pug
|
||||||
|
block content
|
||||||
|
if data == 'expired'
|
||||||
|
h1 Uw aanvraag is verlopen
|
||||||
|
p Probeer uw aanvraag voor surprise box #{number} opnieuw in te dienen.
|
||||||
|
else if data == 'not found'
|
||||||
|
h1 Een aanvraag met de gegeven ID is niet gevonden
|
||||||
|
p Als u gelooft dat dit een fout is, meld het dan bij het surprise box team van Het Heerenlanden.
|
4
server/views/validate-success.pug
Normal file
4
server/views/validate-success.pug
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
extends layout.pug
|
||||||
|
block content
|
||||||
|
h1 Uw aanvraag voor box #{number} is sucessvol verstuurd!
|
||||||
|
p U krijgt binnenkort antwoord van het surprise box team van Het Heerenlanden.
|
@ -1,8 +1,10 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<!-- nav here -->
|
<!-- nav here -->
|
||||||
<span>Surprise box reserveren</span>
|
<span>Surprise box reserveren</span>
|
||||||
<a routerLink="login"><i class="fas fa-sign-in-alt"></i></a>
|
<a routerLink="login"><fa-icon [icon]="faSignInAlt"></fa-icon></a>
|
||||||
</nav>
|
</nav>
|
||||||
<main>
|
<main>
|
||||||
|
<div class="overlay" *ngIf="form.visible"></div>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</main>
|
<app-form *ngIf="form.visible" [number]="form.number"></app-form>
|
||||||
|
</main>
|
||||||
|
@ -16,7 +16,7 @@ body {
|
|||||||
@if type-of($number) == 'number' and not unitless($number) {
|
@if type-of($number) == 'number' and not unitless($number) {
|
||||||
@return $number / ($number * 0 + 1);
|
@return $number / ($number * 0 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@return $number;
|
@return $number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ nav {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
transform: translate(0, -50%);
|
transform: translate(0, -50%);
|
||||||
i {
|
fa-icon {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,4 +62,13 @@ main {
|
|||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
position:fixed;
|
||||||
|
left:0;
|
||||||
|
top: 0;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { FormService } from './services/form.service';
|
||||||
|
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -6,5 +8,9 @@ import { Component } from '@angular/core';
|
|||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'HHFSBRS';
|
|
||||||
|
faSignInAlt = faSignInAlt;
|
||||||
|
|
||||||
|
constructor(public form: FormService) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,14 @@ import { AppRoutingModule } from './app-routing.module';
|
|||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { HomeComponent } from './components/home/home.component';
|
import { HomeComponent } from './components/home/home.component';
|
||||||
import { LoginComponent } from './components/login/login.component';
|
import { LoginComponent } from './components/login/login.component';
|
||||||
|
import { FormComponent } from './components/form/form.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
LoginComponent
|
LoginComponent,
|
||||||
|
FormComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
27
src/app/components/form/form.component.html
Normal file
27
src/app/components/form/form.component.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<fa-icon (click)="formService.hideForm()" [icon]="faTimes"></fa-icon>
|
||||||
|
|
||||||
|
<form *ngIf="!submitted" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||||
|
|
||||||
|
<h4>Formulier voor surpise box {{ number }}</h4>
|
||||||
|
|
||||||
|
<label for="name">Naam: </label>
|
||||||
|
<input type="text" formControlName="name"><br>
|
||||||
|
|
||||||
|
<label for="email">Email: </label>
|
||||||
|
<input type="email" formControlName="email"><br>
|
||||||
|
|
||||||
|
<label for="message">Bericht: </label>
|
||||||
|
<textarea formControlName="message"></textarea><br>
|
||||||
|
|
||||||
|
<input type="submit" value="Verzenden" [disabled]="!form.valid">
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div *ngIf="submitted">
|
||||||
|
<h4>Uw aanvraag is ingediend</h4>
|
||||||
|
<p>Check uw mailbox om uw aanvrag te valideren. Als u de mail niet kan vinden, check dan ook uw spam.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
16
src/app/components/form/form.component.scss
Normal file
16
src/app/components/form/form.component.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
fa-icon {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
25
src/app/components/form/form.component.spec.ts
Normal file
25
src/app/components/form/form.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FormComponent } from './form.component';
|
||||||
|
|
||||||
|
describe('FormComponent', () => {
|
||||||
|
let component: FormComponent;
|
||||||
|
let fixture: ComponentFixture<FormComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ FormComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(FormComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
45
src/app/components/form/form.component.ts
Normal file
45
src/app/components/form/form.component.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { FormBuilder, Validators } from '@angular/forms';
|
||||||
|
import { DataService } from 'src/app/services/data.service';
|
||||||
|
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { FormService } from 'src/app/services/form.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-form',
|
||||||
|
templateUrl: './form.component.html',
|
||||||
|
styleUrls: ['./form.component.scss']
|
||||||
|
})
|
||||||
|
export class FormComponent implements OnInit {
|
||||||
|
// tslint:disable-next-line: no-input-rename
|
||||||
|
@Input('number') number: number;
|
||||||
|
|
||||||
|
faTimes = faTimes;
|
||||||
|
|
||||||
|
form = this.fb.group({
|
||||||
|
email: ['', [Validators.email, Validators.required]],
|
||||||
|
name: ['', Validators.required],
|
||||||
|
message: ['', Validators.required]
|
||||||
|
});
|
||||||
|
|
||||||
|
submitted = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private fb: FormBuilder,
|
||||||
|
private data: DataService,
|
||||||
|
public formService: FormService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
const value = this.form.value;
|
||||||
|
|
||||||
|
value.number = 32;
|
||||||
|
|
||||||
|
this.data.mail(value.email, value.number, value.message, value.name).subscribe(res => {
|
||||||
|
this.submitted = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,8 +12,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<span *ngIf="loggedIn" (click)="logout()">Log uit</span>
|
<span *ngIf="loggedIn" (click)="logout()">Log uit</span>
|
||||||
<div class="container" *ngIf="!loggedIn && (data | async) as data">
|
<div class="container" *ngIf="!loggedIn && (data | async) as data">
|
||||||
<div *ngFor="let item of data.data; let i = index">
|
<div *ngFor="let item of data.result.data; let i = index">
|
||||||
<a [href]="item ? '' : ('mailto:doemiddag.hetheerenlanden@cvo-av.nl?subject=Reservatie Surprise box ' + (i + 1))">
|
<!-- [href]="item ? '' : ('mailto:doemiddag.hetheerenlanden@cvo-av.nl?subject=Reservatie Surprise box ' + (i + 1))" -->
|
||||||
|
<a [class]="item && 'disabled'" (click)="!item && form.showForm(i + 1)">
|
||||||
<span class="{{ item ? 'unavailable' : 'available' }}">{{ i + 1 }}<br>
|
<span class="{{ item ? 'unavailable' : 'available' }}">{{ i + 1 }}<br>
|
||||||
<div class="tooltip">{{ item ? 'Gereserveerd' : 'Klik om te reserveren' }}</div>
|
<div class="tooltip">{{ item ? 'Gereserveerd' : 'Klik om te reserveren' }}</div>
|
||||||
<fa-icon [icon]="faGift"></fa-icon>
|
<fa-icon [icon]="faGift"></fa-icon>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
// HLC blue (0,175,241) red (247,0,0) yellow (255,255,0)
|
// HLC blue (0,175,241) red (247,0,0) yellow (255,255,0)
|
||||||
|
|
||||||
|
a.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
p:nth-child(2) {
|
p:nth-child(2) {
|
||||||
border-bottom: 1px solid rgba(0,0,0,0.5);
|
border-bottom: 1px solid rgba(0,0,0,0.5);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -3,6 +3,7 @@ import { Observable } from 'rxjs';
|
|||||||
import { ApiData, DataService } from 'src/app/services/data.service';
|
import { ApiData, DataService } from 'src/app/services/data.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { faGift } from '@fortawesome/free-solid-svg-icons';
|
import { faGift } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { FormService } from 'src/app/services/form.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
@ -18,7 +19,8 @@ export class HomeComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dataService: DataService,
|
private dataService: DataService,
|
||||||
private router: Router
|
private router: Router,
|
||||||
|
public form: FormService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -3,7 +3,10 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
export interface ApiData {
|
export interface ApiData {
|
||||||
data: Array<boolean>;
|
result: {
|
||||||
|
success: boolean,
|
||||||
|
data: any
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -26,4 +29,9 @@ export class DataService {
|
|||||||
update(index: number, username: string, password: string): Observable<void> {
|
update(index: number, username: string, password: string): Observable<void> {
|
||||||
return this.http.post<void>(this.apiUrl + '/update/' + index, {username, password});
|
return this.http.post<void>(this.apiUrl + '/update/' + index, {username, password});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line: variable-name
|
||||||
|
mail(email: string, number: number, message: string, name: string): Observable<ApiData> {
|
||||||
|
return this.http.post<ApiData>(this.apiUrl + '/mail/', {email, number, message, name});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
src/app/services/form.service.spec.ts
Normal file
12
src/app/services/form.service.spec.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FormService } from './form.service';
|
||||||
|
|
||||||
|
describe('FormService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: FormService = TestBed.get(FormService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
22
src/app/services/form.service.ts
Normal file
22
src/app/services/form.service.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class FormService {
|
||||||
|
|
||||||
|
visible = false;
|
||||||
|
number: number;
|
||||||
|
|
||||||
|
showForm(number: number) {
|
||||||
|
this.number = number;
|
||||||
|
this.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hideForm() {
|
||||||
|
this.visible = false;
|
||||||
|
this.number = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
}
|
@ -7,7 +7,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Staatliches&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Staatliches&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" type="text/css" href="//use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
|
Loading…
Reference in New Issue
Block a user