Fix birthday -1 bug
Add lite configuration Add registration deletion Add favicon Add dynamic title
This commit is contained in:
parent
504f0293ac
commit
bb6751c649
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
header("Content-Type: application/json; charset=UTF-8");
|
||||||
|
header("Access-Control-Allow-Methods: POST");
|
||||||
|
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||||
|
|
||||||
|
require_once('../../utils/config.php');
|
||||||
|
require_once('../../utils/db.php');
|
||||||
|
require_once('../../utils/strings.php');
|
||||||
|
|
||||||
|
$authorization = $_SERVER["HTTP_AUTHORIZATION"];
|
||||||
|
if(strcmp($authorization, INTERNAL_API_KEY) !== 0) {
|
||||||
|
echo 'STOP TRYING TO STEAL MY DATA!';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
|
if ('POST' === $method) {
|
||||||
|
parse_str(file_get_contents('php://input'), $_POST);
|
||||||
|
}
|
||||||
|
|
||||||
|
$connection = connect();
|
||||||
|
|
||||||
|
$rid = intval($_POST["rid"]);
|
||||||
|
|
||||||
|
$querystr = "DELETE FROM li_registrations WHERE rid=${rid}";
|
||||||
|
|
||||||
|
mysqli_query($connection, $querystr);
|
||||||
|
|
||||||
|
echo json_encode('{ "result": "true" }');
|
||||||
|
?>
|
|
@ -199,7 +199,7 @@ function sendRegistrationMail($data) {
|
||||||
$message = "
|
$message = "
|
||||||
<html><head><title>Neue Anmeldung bei Li-Dance</title></head><body>
|
<html><head><title>Neue Anmeldung bei Li-Dance</title></head><body>
|
||||||
<p>{$data->firstname} {$data->lastname} aus {$data->city} hat sich angemeldet.</p>
|
<p>{$data->firstname} {$data->lastname} aus {$data->city} hat sich angemeldet.</p>
|
||||||
<p>Btte bearbeite diese möglichst schnell: <a href='" . REGISTRATION_URL . "'>Zur Anmeldung</a></p>
|
<p>Btte bearbeite diese möglichst schnell: <a href='" . REGISTRATION_URL . "'>Zur Anmeldung</a></p>
|
||||||
</body></html>";
|
</body></html>";
|
||||||
|
|
||||||
$header[] = 'MIME-Version: 1.0';
|
$header[] = 'MIME-Version: 1.0';
|
||||||
|
|
|
@ -58,6 +58,27 @@
|
||||||
],
|
],
|
||||||
"outputHashing": "all"
|
"outputHashing": "all"
|
||||||
},
|
},
|
||||||
|
"lite": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "2mb",
|
||||||
|
"maximumError": "2mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.lite.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputHashing": "all"
|
||||||
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"buildOptimizer": false,
|
"buildOptimizer": false,
|
||||||
"optimization": false,
|
"optimization": false,
|
||||||
|
|
|
@ -5,8 +5,13 @@ import { VisitsComponent } from './components/visits/visits.component';
|
||||||
import { VisitsDatetimeComponent } from './components/visits/visits-datetime/visits-datetime.component';
|
import { VisitsDatetimeComponent } from './components/visits/visits-datetime/visits-datetime.component';
|
||||||
import { RegistrationWizardComponent } from './components/registrations/registration-wizard/registration-wizard.component';
|
import { RegistrationWizardComponent } from './components/registrations/registration-wizard/registration-wizard.component';
|
||||||
import { RegistrationListComponent } from './components/registrations/registration-list/registration-list.component';
|
import { RegistrationListComponent } from './components/registrations/registration-list/registration-list.component';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
const routes: Routes = [
|
const publicRoutes: Routes = [
|
||||||
|
{ path: '**', component: RegistrationWizardComponent },
|
||||||
|
];
|
||||||
|
|
||||||
|
const internalRoutes: Routes = [
|
||||||
{ path: 'students', component: StudentListComponent },
|
{ path: 'students', component: StudentListComponent },
|
||||||
{ path: 'visits', component: VisitsComponent },
|
{ path: 'visits', component: VisitsComponent },
|
||||||
{ path: 'registrations', component: RegistrationListComponent },
|
{ path: 'registrations', component: RegistrationListComponent },
|
||||||
|
@ -16,6 +21,9 @@ const routes: Routes = [
|
||||||
{ path: '**', redirectTo: 'students' },
|
{ path: '**', redirectTo: 'students' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
//const routes: Routes = publicRoutes;
|
||||||
|
const routes: Routes = environment.lite ? publicRoutes : internalRoutes;
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { MatIconRegistry } from '@angular/material/icon';
|
import { MatIconRegistry } from '@angular/material/icon';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'li-root',
|
selector: 'li-root',
|
||||||
|
@ -9,12 +11,14 @@ import { MatIconRegistry } from '@angular/material/icon';
|
||||||
|
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private matIconReg: MatIconRegistry
|
private matIconReg: MatIconRegistry,
|
||||||
|
private titleService: Title
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
title = 'li-dance-backoffice';
|
title = 'li-dance-backoffice';
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.matIconReg.setDefaultFontSetClass('material-symbols-outlined');
|
this.matIconReg.setDefaultFontSetClass('material-symbols-outlined');
|
||||||
|
this.titleService.setTitle(environment.appTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,11 +23,17 @@
|
||||||
|
|
||||||
<ng-container matColumnDef="Gender">
|
<ng-container matColumnDef="Gender">
|
||||||
<mat-header-cell *matHeaderCellDef> Geschlecht </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef> Geschlecht </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let element">{{element.gender}}</mat-cell>
|
<mat-cell *matCellDef="let element">{{element | gender}}</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="Address">
|
||||||
|
<mat-header-cell *matHeaderCellDef> Adresse </mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let element">{{element | address}}</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="Actions">
|
<ng-container matColumnDef="Actions">
|
||||||
<mat-header-cell *matHeaderCellDef></mat-header-cell>
|
<mat-header-cell *matHeaderCellDef></mat-header-cell>
|
||||||
<mat-cell *matCellDef="let element" class="actions"><mat-icon>delete</mat-icon></mat-cell>
|
<mat-cell *matCellDef="let element" class="actions"><mat-icon (click)="delete(element)">delete</mat-icon></mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<mat-header-row
|
<mat-header-row
|
||||||
|
@ -36,6 +42,7 @@
|
||||||
'Lastname',
|
'Lastname',
|
||||||
'Birthday',
|
'Birthday',
|
||||||
'Gender',
|
'Gender',
|
||||||
|
'Address',
|
||||||
'Actions'
|
'Actions'
|
||||||
]"></mat-header-row>
|
]"></mat-header-row>
|
||||||
<mat-row
|
<mat-row
|
||||||
|
@ -46,6 +53,7 @@
|
||||||
'Lastname',
|
'Lastname',
|
||||||
'Birthday',
|
'Birthday',
|
||||||
'Gender',
|
'Gender',
|
||||||
|
'Address',
|
||||||
'Actions'
|
'Actions'
|
||||||
]
|
]
|
||||||
"></mat-row>
|
"></mat-row>
|
||||||
|
|
|
@ -41,6 +41,10 @@ export class RegistrationListComponent implements OnInit {
|
||||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delete(registration: StudentRegistration): void {
|
||||||
|
this.registrationsService.del(registration).subscribe(_ => this.getData());
|
||||||
|
}
|
||||||
|
|
||||||
private getData() {
|
private getData() {
|
||||||
this.registrationsService.get().subscribe({
|
this.registrationsService.get().subscribe({
|
||||||
next: registrations => {
|
next: registrations => {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { Student } from '../models/student';
|
import { Student } from '../models/student';
|
||||||
|
import { StudentRegistration } from '../models/student-registration';
|
||||||
|
|
||||||
@Pipe({ name: 'address' })
|
@Pipe({ name: 'address' })
|
||||||
export class AddressPipe implements PipeTransform {
|
export class AddressPipe implements PipeTransform {
|
||||||
transform(student: Student): string {
|
transform(student: Student | StudentRegistration): string {
|
||||||
let result = `${student.street} ${student.house}${student.house_suffix}, ${student.zip} ${student.city}`;
|
let result = `${student.street} ${student.house}, ${student.zip} ${student.city}`;
|
||||||
return result.trim() === '0,' ? '' : result;
|
return result.trim() === '0,' ? '' : result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
import { Student } from '../models/student';
|
import { Student } from '../models/student';
|
||||||
|
import { StudentRegistration } from '../models/student-registration';
|
||||||
|
|
||||||
@Pipe({ name: 'gender' })
|
@Pipe({ name: 'gender' })
|
||||||
export class GenderPipe implements PipeTransform {
|
export class GenderPipe implements PipeTransform {
|
||||||
transform(student: Student): string {
|
transform(student: Student | StudentRegistration): string {
|
||||||
|
console.log(student);
|
||||||
switch (Number(student.gender)) {
|
switch (Number(student.gender)) {
|
||||||
case 0:
|
case 0:
|
||||||
return 'M';
|
return 'M';
|
||||||
case 1:
|
case 1:
|
||||||
return 'W';
|
return 'W';
|
||||||
|
case 2:
|
||||||
|
return 'D';
|
||||||
default:
|
default:
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,28 +3,28 @@ import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||||
import { StudentRegistration } from "../../models/student-registration";
|
import { StudentRegistration } from "../../models/student-registration";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class RegistrationsService {
|
export class RegistrationsService {
|
||||||
private readonly serviceName = 'registrations';
|
private readonly serviceName = 'registrations';
|
||||||
private readonly headers = { headers: new HttpHeaders({ "Authorization": environment.apiKeyPublic })};
|
private readonly publicHeaders = { headers: new HttpHeaders({ "Authorization": environment.apiKeyPublic })};
|
||||||
|
private readonly internalHeaders = { headers: new HttpHeaders({ "Authorization": environment.apiKeyInternal })};
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
public get(): Observable<StudentRegistration[]> {
|
public get(): Observable<StudentRegistration[]> {
|
||||||
return this.http.get<StudentRegistration[]>(
|
return this.http.get<StudentRegistration[]>(
|
||||||
`${environment.apiUrl}${this.serviceName}/get.php`, this.headers
|
`${environment.apiUrl}${this.serviceName}/get.php`, this.internalHeaders
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public set(registration: StudentRegistration): Observable<void> {
|
public set(registration: StudentRegistration): Observable<void> {
|
||||||
const formatDate = (date: Date): string => date.toISOString().split('T')[0];
|
|
||||||
|
|
||||||
const payload = `firstname=${encodeURIComponent(registration.firstName)}&` +
|
const payload = `firstname=${encodeURIComponent(registration.firstName)}&` +
|
||||||
`lastname=${encodeURIComponent(registration.lastName)}&` +
|
`lastname=${encodeURIComponent(registration.lastName)}&` +
|
||||||
`birthday=${encodeURIComponent(formatDate(registration.birthday))}&` +
|
`birthday=${encodeURIComponent(moment(registration.birthday).format('YYYY-MM-DD'))}&` +
|
||||||
`gender=${encodeURIComponent(registration.gender)}&` +
|
`gender=${encodeURIComponent(registration.gender)}&` +
|
||||||
`street=${encodeURIComponent(registration.street)}&` +
|
`street=${encodeURIComponent(registration.street)}&` +
|
||||||
`house=${encodeURIComponent(registration.house)}&` +
|
`house=${encodeURIComponent(registration.house)}&` +
|
||||||
|
@ -43,11 +43,20 @@ export class RegistrationsService {
|
||||||
`returnDebitConsent=${encodeURIComponent(registration.returnDebitConsent)}&` +
|
`returnDebitConsent=${encodeURIComponent(registration.returnDebitConsent)}&` +
|
||||||
`dataStorageConsent=${encodeURIComponent(registration.dataStorageConsent)}&` +
|
`dataStorageConsent=${encodeURIComponent(registration.dataStorageConsent)}&` +
|
||||||
`multimediaConsent=${encodeURIComponent(registration.multimediaConsent)}`;
|
`multimediaConsent=${encodeURIComponent(registration.multimediaConsent)}`;
|
||||||
|
|
||||||
|
|
||||||
return this.http.post<void>(`${environment.apiUrl}${this.serviceName}/set.php`,
|
return this.http.post<void>(`${environment.apiUrl}${this.serviceName}/set.php`,
|
||||||
payload,
|
payload,
|
||||||
this.headers
|
this.publicHeaders
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public del(registration: StudentRegistration): Observable<void> {
|
||||||
|
const payload = `rid=${registration.rid}`;
|
||||||
|
|
||||||
|
return this.http.post<void>(
|
||||||
|
`${environment.apiUrl}${this.serviceName}/del.php`,
|
||||||
|
payload,
|
||||||
|
this.internalHeaders
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const environment = {
|
||||||
|
production: true,
|
||||||
|
lite: true,
|
||||||
|
appTitle: 'Li-Dance Registration',
|
||||||
|
apiUrl: 'https://li-dance.de/plan/api/',
|
||||||
|
apiKeyPublic: '754259b6-caf0-4eca-a1f6-812731adae79',
|
||||||
|
apiKeyInternal: '',
|
||||||
|
};
|
|
@ -1,5 +1,7 @@
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: true,
|
production: true,
|
||||||
|
lite: false,
|
||||||
|
appTitle: 'Li-Dance Backoffice Suite',
|
||||||
apiUrl: 'https://li-dance.de/plan/api/',
|
apiUrl: 'https://li-dance.de/plan/api/',
|
||||||
apiKeyPublic: '754259b6-caf0-4eca-a1f6-812731adae79',
|
apiKeyPublic: '754259b6-caf0-4eca-a1f6-812731adae79',
|
||||||
apiKeyInternal: '1ca6fc7d-d5b8-473c-a44d-a8c9098e2940',
|
apiKeyInternal: '1ca6fc7d-d5b8-473c-a44d-a8c9098e2940',
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
|
lite: false,
|
||||||
|
appTitle: 'Li-Dance Backoffice Suite',
|
||||||
apiUrl: 'https://li-dance.de/plan/api/',
|
apiUrl: 'https://li-dance.de/plan/api/',
|
||||||
apiKeyPublic: '754259b6-caf0-4eca-a1f6-812731adae79',
|
apiKeyPublic: '754259b6-caf0-4eca-a1f6-812731adae79',
|
||||||
apiKeyInternal: '1ca6fc7d-d5b8-473c-a44d-a8c9098e2940',
|
apiKeyInternal: '1ca6fc7d-d5b8-473c-a44d-a8c9098e2940',
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 948 B |
|
@ -2,10 +2,11 @@
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Li-Dance Backoffice</title>
|
<title></title>
|
||||||
<base href="/" />
|
<base href="./" />
|
||||||
<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="shortcut icon" href="/files/cto_layout/img/favicon-32x32.png" type="image/x-icon">
|
||||||
|
<link rel="apple-touch-icon" href="/files/cto_layout/img/favicon-32x32.png">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
|
||||||
|
|
Loading…
Reference in New Issue