44 changed files with 1667 additions and 159 deletions
@ -0,0 +1,27 @@ |
|||
-----BEGIN RSA PRIVATE KEY----- |
|||
MIIEowIBAAKCAQEApNcN8cn0872DhGSdPobrIR9kBfd+qSL/Sqrgk3mywEuuzhN3 |
|||
MOYbaejwdIJacC0OjCMVgm3f2TziefYd2ssvAUjT+M9FCESUSSDHgPVxt22UDZxz |
|||
ZraasA+jdVW0QQtBv8AjyDCXAmMZxcGT1x1htKsKfG2JDxxc1DXub1BaBSkrqcZ1 |
|||
1u50UK0DBbRcUhd85z9Oivju3IktDaVow09fpwUR/tK1xO8PPsaAUQMKdN1ArGA/ |
|||
O+FFXAirQ7OD8tT4gCmJYrU2h4mAlcjKwpvmXbtHGmZ2tn4nJsaYUxL0vMPHWoTl |
|||
ymOkFbKujBDkTSdKgUdTBy7Bda9ZzAcEBJoGgQIDAQABAoIBAEGVmuO3obEUlu4n |
|||
BfUpwwVzst044nkzBnXT1PR4OCmQMyWk0whulTunRXxlnMwC8UXKc7VoN+b79XPm |
|||
+2vg6XvOWSAmf2XRu1n5I8doYG1FuOFNfRDB2HvyTOvTRJuYeflr3hC5XGvDuC5Z |
|||
XZP6CbTTVKG7BwwvEbQRHSPGyXpBiqd+OOfTpeoobrkGJJAKxvXHO0G7zgB5h/H+ |
|||
0fjSWvo4QxzOAF74f0qUmWBbvLjWL3yZhVE8mxNcVoV1HlIdXV5anMe9FURci5D4 |
|||
U8ehGky3sbHjcc7wro5IPWJYTrDAmvhI8wMMx7gbHe2HOzyWRX++ifjfP77kw2e3 |
|||
IYnwMAECgYEA05Ehmsipk4rmJeCgmDJomQVsJgMW1zjOJwIljSZ9o55+LHpma6r0 |
|||
O6sdQYgiNwQT0f//iJZkatpDAyC3U6EU9RY7Yoc0R3XK86vryKQlB/Nh1boLldt6 |
|||
9TGdL5eCzaraiYuLjGvXMGTS8LjB0ftFCGQswl2kcuOFx1YjE4WPoUECgYEAx3Wo |
|||
yenPXHCdD4kIrQ9SxPha2aobh33MjdwSYSiDliaEoBg/voWJExFmMJuvhR46xqmy |
|||
i8E0RuzzBrG4Zhbdo4kcpdF2GtAuxNw8uYvG+SQub8zAmBT7YpXzTmpGQ2TR3i8S |
|||
XzD57s7C1mSkBIwWuVJYcx3Kgm1mQNIOELU31UECgYEAhNc14HhqcaffRp06eRX9 |
|||
s0dCVsPNzalvV/LzHSOz886KrubT9HrNC8Ivhnwx75Vx1IQHMP4tYyJUvVwHgE0+ |
|||
WX1yIDWAz/XYTxP94meekNVy8r30lE3RcK+MYNujV/wVaBPktXDpFwvXnyqDGJPL |
|||
Dq/HouslXLYbw8QEFjfgrYECgYB+oSU6ozThpCEihsY6ULskj+PlwohdubEO8wO8 |
|||
KSN5RRT4Ksz1YQPIVkiBXaXOJoX8MCpJbayJxs73lgbS0Xt+4oKMh3GqzjaTBpuK |
|||
1MHK1Hyiv+QZ6WA7k6V3SCM5kB1pKItKYeabBStPP2+d725R04SR+PzjVx8O0gzZ |
|||
8KL0wQKBgC7LRztq8PMDGTHGXVxWXwZ08ZAf2MAsBvYyAU5xudS+pRqlNGDgyxiv |
|||
YQEe9n2DVu7GVsoNnKIapmXV1qx0vTU/CpKV0cpXi6m3XVnbtjBsaYtkYNNZfHVl |
|||
E++gP4qgvALKugnzaGn5oby0PPcFFhnNqRwFb5c3diihwMQhkudG |
|||
-----END RSA PRIVATE KEY----- |
@ -0,0 +1,5 @@ |
|||
#!/bin/bash |
|||
|
|||
yarn prod |
|||
rsync -avz --delete --exclude '/apis/conn.conn' --exclude '.well-known' --exclude '/uploads' -e "ssh -i ./auth/identity.pem -p2222" ./dist/dslak-website/* cdr@2.238.194.8:/www/dslak.it/ |
|||
|
@ -0,0 +1,41 @@ |
|||
<?php |
|||
@include 'conn.conn'; |
|||
$GLOBALS['conn']; |
|||
$conn = @mysqli_connect($DATAhst,$DATAusr,$DATApwd,$DATAdtb)or die("CONNECTION ERROR"); |
|||
|
|||
$content = null; |
|||
$content->status = 200; |
|||
|
|||
$data = json_decode(file_get_contents("php://input")); |
|||
|
|||
if(isset($_GET['act']) && $_GET['act'] == 'login') { |
|||
if(isset($data->usr) && $data->usr == 'admin' && isset($data->pwd) && $data->pwd == 'JohnHolmes') { |
|||
http_response_code(200); |
|||
$content->status = 200; |
|||
$content->authToken = base64_encode('admin:JohnHolmes'.date("Y-m-d")); |
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
$content->action = 'login'; |
|||
} |
|||
} else if(isset($_GET['act']) && $_GET['act'] == 'check') { |
|||
if(isset($data->token) && $data->token == base64_encode('admin:JohnHolmes'.date("Y-m-d"))) { |
|||
http_response_code(200); |
|||
$content->status = 200; |
|||
$content->authToken = base64_encode('admin:JohnHolmes'.date("Y-m-d")); |
|||
} else { |
|||
http_response_code(200); |
|||
$content->status = 401; |
|||
$content->action = 'check'; |
|||
$content->token = $data->token; |
|||
} |
|||
} |
|||
|
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: POST"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
|
|||
echo json_encode($content); |
|||
|
|||
?> |
@ -0,0 +1,80 @@ |
|||
<?php |
|||
@include 'conn.conn'; |
|||
$GLOBALS['conn']; |
|||
$conn = @mysqli_connect($DATAhst,$DATAusr,$DATApwd,$DATAdtb)or die("CONNECTION ERROR"); |
|||
|
|||
$content = null; |
|||
$data = json_decode(file_get_contents("php://input")); |
|||
|
|||
if(isset($data->token) && $data->token == base64_encode('admin:JohnHolmes'.date("Y-m-d"))) { |
|||
|
|||
if(isset($_GET['act'])) { |
|||
if($_GET['act'] == 'save') { |
|||
if(isset($data->id)) { |
|||
$q = mysqli_query($conn,"UPDATE `exhibitions` SET title = '".addslashes($data->title)."', content = '".addslashes($data->content)."', |
|||
tags = '".$data->tags."', date_from = '".$data->date_from."', date_to = '".$data->date_to."', |
|||
image = '".$data->image."', works = '".$data->works."', gallery = '".$data->gallery."', |
|||
videos = '".$data->videos."' WHERE id = ".$data->id.""); |
|||
} else { |
|||
$q = mysqli_query($conn,"INSERT INTO `exhibitions` |
|||
(`id`, `title`, `content`, `tags`, `date_from`, `date_to`, `image`, `works`, `gallery`, `videos`) |
|||
VALUES (NULL, '".addslashes($data->title)."', '".addslashes($data->content)."', '".$data->tags."', |
|||
'".$data->date_from."', '".$data->date_to."', '".$data->image."', '".$data->works."', |
|||
'".$data->gallery."', '".$data->videos."')"); |
|||
} |
|||
|
|||
if($q) { |
|||
http_response_code(201); |
|||
$content->status = 201; |
|||
} else { |
|||
http_response_code(403); |
|||
$content->status = "UPDATE `exhibitions` SET title = '".addslashes($data->title)."', content = '".addslashes($data->content)."', |
|||
tags = '".$data->tags."', date_from = '".$data->date_from."', date_to = '".$data->date_to."', |
|||
image = '".$data->image."', works = '".$data->works."', gallery = '".$data->gallery."', |
|||
videos = '".$data->videos."' WHERE id = ".$data->id.""; |
|||
} |
|||
} |
|||
|
|||
if($_GET['act'] == 'delete') { |
|||
if(isset($data->id)) { |
|||
$q = mysqli_query($conn,"DELETE FROM `exhibitions` WHERE id = ".$data->id.""); |
|||
if($q) { |
|||
http_response_code(201); |
|||
$content->status = 201; |
|||
} else { |
|||
http_response_code(403); |
|||
$content->status = 403; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if($q) { |
|||
$qe = mysqli_query($conn,"SELECT * FROM `exhibitions` ORDER BY id DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->date_from = $re['date_from']; |
|||
$item->date_to = $re['date_to']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
} |
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: POST"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
|
|||
echo json_encode($content); |
|||
|
|||
?> |
@ -1,95 +1,98 @@ |
|||
<?php |
|||
@include 'conn.conn'; |
|||
$GLOBALS['conn']; |
|||
$conn=@mysqli_connect($DATAhst,$DATAusr,$DATApwd,$DATAdtb)or die("CONNECTION ERROR"); |
|||
$conn = @mysqli_connect($DATAhst,$DATAusr,$DATApwd,$DATAdtb)or die("CONNECTION ERROR"); |
|||
|
|||
$content = null; |
|||
$content->items = array(); |
|||
|
|||
$filter = array("portfolio", "installations", "entertainment", "performances", "workshops"); |
|||
if(isset($_GET['query'])) { |
|||
|
|||
switch($_GET['query']) { |
|||
case "portfolio": |
|||
case "installations": |
|||
case "entertainment": |
|||
case "performances": |
|||
case "workshops": |
|||
if($_GET['query'] == 'portfolio') {$filter = '';} else {$filter = "WHERE type='".$_GET['query']."'";} |
|||
$qe = mysqli_query($conn,"SELECT * FROM `works` $filter ORDER BY id DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content = null; |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->type = $re['type']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
$content->items = array(); |
|||
switch($_GET['query']) { |
|||
case "portfolio": |
|||
case "installations": |
|||
case "entertainment": |
|||
case "performances": |
|||
case "workshops": |
|||
if($_GET['query'] == 'portfolio') {$filter = '';} else {$filter = "WHERE type='".$_GET['query']."'";} |
|||
$qe = mysqli_query($conn,"SELECT * FROM `works` $filter ORDER BY id DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content = null; |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->type = $re['type']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
case "exhibitions": |
|||
$qe = mysqli_query($conn,"SELECT * FROM `exhibitions` ORDER BY date_from DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content = null; |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
break; |
|||
case "exhibitions": |
|||
$qe = mysqli_query($conn,"SELECT * FROM `exhibitions` ORDER BY date_from DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content = null; |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->date_from = $re['date_from']; |
|||
$item->date_to = $re['date_to']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
} |
|||
} |
|||
break; |
|||
case "detail": |
|||
$qe = mysqli_query($conn,"SELECT * FROM `".$_GET['type']."` WHERE id=".$_GET['id']); |
|||
if(mysqli_num_rows($qe)>0) { |
|||
$content = null; |
|||
$re = mysqli_fetch_array($qe); |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->date_from = $re['date_from']; |
|||
$item->date_to = $re['date_to']; |
|||
$item->content = $re['content']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
} |
|||
} |
|||
break; |
|||
case "detail": |
|||
$qe = mysqli_query($conn,"SELECT * FROM `".$_GET['type']."` WHERE id=".$_GET['id']); |
|||
if(mysqli_num_rows($qe)>0) { |
|||
$content = null; |
|||
$re = mysqli_fetch_array($qe); |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->content = $re['content']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
if($_GET['type'] == 'exhibitions') { |
|||
$item->date_from = $re['date_from']; |
|||
$item->date_to = $re['date_to']; |
|||
$item->works = array(); |
|||
$qx = mysqli_query($conn,"SELECT id,title FROM `works` WHERE id IN (".$re['works'].")"); |
|||
while($re = mysqli_fetch_array($qx)) { |
|||
$ex = null; |
|||
$ex->id = $re['id']; |
|||
$ex->title = $re['title']; |
|||
array_push($item->works, $ex); |
|||
} |
|||
} else if($_GET['type'] == 'works') { |
|||
$item->type = $re['type']; |
|||
$item->videos = $re['videos']; |
|||
$item->gallery = $re['gallery']; |
|||
$item->exhibitions = array(); |
|||
$qx = mysqli_query($conn,"SELECT id,title FROM `exhibitions` WHERE id IN (".$re['exhibitions'].")"); |
|||
while($re = mysqli_fetch_array($qx)) { |
|||
$ex = null; |
|||
$ex->id = $re['id']; |
|||
$ex->title = $re['title']; |
|||
array_push($item->exhibitions, $ex); |
|||
if($_GET['type'] == 'exhibitions') { |
|||
$item->date_from = $re['date_from']; |
|||
$item->date_to = $re['date_to']; |
|||
$item->works = array(); |
|||
$qx = mysqli_query($conn,"SELECT id,title FROM `works` WHERE id IN (".$re['works'].")"); |
|||
while($re = mysqli_fetch_array($qx)) { |
|||
$ex = null; |
|||
$ex->id = $re['id']; |
|||
$ex->title = $re['title']; |
|||
array_push($item->works, $ex); |
|||
} |
|||
} else if($_GET['type'] == 'works') { |
|||
$item->type = $re['type']; |
|||
$item->exhibitions = array(); |
|||
$qx = mysqli_query($conn,"SELECT id,title FROM `exhibitions` WHERE id IN (".$re['exhibitions'].")"); |
|||
while($re = mysqli_fetch_array($qx)) { |
|||
$ex = null; |
|||
$ex->id = $re['id']; |
|||
$ex->title = $re['title']; |
|||
array_push($item->exhibitions, $ex); |
|||
} |
|||
} |
|||
$content->item = $item; |
|||
} |
|||
$content->item = $item; |
|||
} |
|||
break; |
|||
break; |
|||
} |
|||
} |
|||
http_response_code(200); |
|||
|
|||
|
|||
header('Access-Control-Allow-Origin: *'); |
|||
header('Content-Type: application/json'); |
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: GET"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
echo json_encode($content); |
|||
|
|||
?> |
|||
|
@ -0,0 +1,24 @@ |
|||
<?php |
|||
|
|||
$content = null; |
|||
$data = json_decode(file_get_contents("php://input")); |
|||
|
|||
if(isset($data->token) && $data->token == base64_encode('admin:JohnHolmes'.date("Y-m-d"))) { |
|||
|
|||
@unlink('..'.$data->url); |
|||
http_response_code(200); |
|||
$content->status = 200; |
|||
|
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
} |
|||
|
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: POST"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
|
|||
echo json_encode($content); |
|||
|
|||
?> |
@ -0,0 +1,35 @@ |
|||
<?php |
|||
|
|||
$content = null; |
|||
|
|||
if(isset($_POST['token']) && $_POST['token'] == base64_encode('admin:JohnHolmes'.date("Y-m-d"))) { |
|||
|
|||
if(is_uploaded_file($_FILES['file']['tmp_name'])) { |
|||
$file = $_FILES['file']['tmp_name']; |
|||
$filename = date("YmdHis").".".end((explode(".", $_FILES["file"]["name"]))); |
|||
|
|||
$path = isset($_POST['path']) ? "/uploads/".$_POST['path'] : "/uploads/"; |
|||
@move_uploaded_file($file, "..".$path."/".$filename); |
|||
|
|||
http_response_code(200); |
|||
$content->status = 200; |
|||
$content->imageUrl = $path."/".$filename; |
|||
|
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
$content->megssage = 'No file uploaded'; |
|||
} |
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
} |
|||
|
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: POST"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
|
|||
echo json_encode($content); |
|||
|
|||
?> |
@ -0,0 +1,75 @@ |
|||
<?php |
|||
@include 'conn.conn'; |
|||
$GLOBALS['conn']; |
|||
$conn = @mysqli_connect($DATAhst,$DATAusr,$DATApwd,$DATAdtb)or die("CONNECTION ERROR"); |
|||
|
|||
$content = null; |
|||
$data = json_decode(file_get_contents("php://input")); |
|||
|
|||
if(isset($data->token) && $data->token == base64_encode('admin:JohnHolmes'.date("Y-m-d"))) { |
|||
|
|||
if(isset($_GET['act'])) { |
|||
if($_GET['act'] == 'save') { |
|||
if(isset($data->id)) { |
|||
$q = mysqli_query($conn,"UPDATE `works` SET title = '".addslashes($data->title)."', content = '".addslashes($data->content)."', |
|||
type = '".$data->type."', tags = '".$data->tags."', image = '".$data->image."', |
|||
exhibitions = '".$data->exhibitions."', gallery = '".$data->gallery."', videos = '".$data->videos."' |
|||
WHERE id = ".$data->id.""); |
|||
} else { |
|||
$q = mysqli_query($conn,"INSERT INTO `works` (`id`, `title`, `content`, `type`, `tags`, `image`, `exhibitions`, `gallery`, `videos`) |
|||
VALUES (NULL, '".addslashes($data->title)."', '".addslashes($data->content)."', '".$data->type."', |
|||
'".$data->tags."', '".$data->image."', '".$data->exhibitions."', '".$data->gallery."', |
|||
'".$data->videos."')"); |
|||
} |
|||
|
|||
if($q) { |
|||
http_response_code(201); |
|||
$content->status = 201; |
|||
} else { |
|||
http_response_code(403); |
|||
$content->status = 403; |
|||
} |
|||
} |
|||
|
|||
if($_GET['act'] == 'delete') { |
|||
if(isset($data->id)) { |
|||
$q = mysqli_query($conn,"DELETE FROM `works` WHERE id = ".$data->id.""); |
|||
if($q) { |
|||
http_response_code(201); |
|||
$content->status = 201; |
|||
} else { |
|||
http_response_code(403); |
|||
$content->status = 403; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if($q) { |
|||
$qe = mysqli_query($conn,"SELECT * FROM `works` ORDER BY id DESC"); |
|||
if(mysqli_num_rows($qe) > 0) { |
|||
$content->items = array(); |
|||
while($re = mysqli_fetch_array($qe)) { |
|||
$item = null; |
|||
$item->id = $re['id']; |
|||
$item->title = $re['title']; |
|||
$item->type = $re['type']; |
|||
$item->tags = $re['tags']; |
|||
$item->image = $re['image']; |
|||
array_push($content->items, $item); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} else { |
|||
http_response_code(401); |
|||
$content->status = 401; |
|||
} |
|||
header("Access-Control-Allow-Origin: *"); |
|||
header("Content-Type: application/json; charset=UTF-8"); |
|||
header("Access-Control-Allow-Methods: POST"); |
|||
header("Access-Control-Max-Age: 3600"); |
|||
|
|||
echo json_encode($content); |
|||
|
|||
?> |
@ -0,0 +1,191 @@ |
|||
<div class="component-admin"> |
|||
<div class="row no-gutters" *ngIf="!authCheck"> |
|||
<div class="col-12 col-md-6 mx-auto"> |
|||
<form class="login-form-container" (submit)="login()"> |
|||
<div class="m-2"> |
|||
<span class="login-label">Username</span> |
|||
<input type="text" class="input-text" name="userName" [(ngModel)]="userName"> |
|||
</div> |
|||
<div class="m-2"> |
|||
<span class="login-label">Password</span> |
|||
<input type="password" class="input-text" name="password" [(ngModel)]="password"> |
|||
</div> |
|||
<div class="m-2 pt-4"> |
|||
<button type="submit" class="button">Sign-in</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row no-gutters" *ngIf="authCheck"> |
|||
<div class="col-12 col-md-3 col-lg-2"> |
|||
<div class="menu"> |
|||
<span class="section-title">Works</span> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'works-add'}" (click)="showEditor('works-add')">Add</button> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'works-modify'}" (click)="showEditor('works-modify')">Modify</button> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'works-delete'}" (click)="showEditor('works-delete')">Delete</button> |
|||
|
|||
<span class="section-title">Exhibitions</span> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'exhibitions-add'}" (click)="showEditor('exhibitions-add')">Add</button> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'exhibitions-modify'}" (click)="showEditor('exhibitions-modify')">Modify</button> |
|||
<button class="action" [ngClass]="{'active': activeEditor == 'exhibitions-delete'}" (click)="showEditor('exhibitions-delete')">Delete</button> |
|||
</div> |
|||
</div> |
|||
<div class="col px-5 py-4"> |
|||
<div class="edit-container"> |
|||
<span class="title">{{sectionTitle}}</span> |
|||
<form class="form row" *ngIf="activeEditor == 'works-modify' || activeEditor == 'works-delete'"> |
|||
<div class="col-12"> |
|||
<select class="input-select" (change)="selectWork($event.target.value)"> |
|||
<option value="">- Select work from list -</option> |
|||
<option value="{{work.id}}" *ngFor="let work of works"> |
|||
{{work.type}} | {{work.title}} |
|||
</option> |
|||
</select> |
|||
</div> |
|||
</form> |
|||
<form class="form row" *ngIf="activeEditor == 'exhibitions-modify' || activeEditor == 'exhibitions-delete'"> |
|||
<div class="col-12"> |
|||
<select class="input-select" (change)="selectExhibition($event.target.value)"> |
|||
<option value="">- Select exhibition from list -</option> |
|||
<option value="{{exhibition.id}}" *ngFor="let exhibition of exhibitions"> |
|||
{{exhibition.date_from | date}} | {{exhibition.title}} |
|||
</option> |
|||
</select> |
|||
</div> |
|||
</form> |
|||
<form class="form row" (submit)="saveData()" |
|||
*ngIf="activeEditor == 'works-add' || (activeEditor == 'works-modify' && activeModify) || |
|||
activeEditor == 'exhibitions-add' || (activeEditor == 'exhibitions-modify' && activeModify)"> |
|||
<div [ngClass]="{'col-8': activeEditor == 'works-add' || activeEditor == 'works-modify', |
|||
'col-6': activeEditor == 'exhibitions-add' || activeEditor == 'exhibitions-modify'}"> |
|||
<span class="label">Title</span> |
|||
<input type="text" class="input-text" name="title" [(ngModel)]="title"> |
|||
</div> |
|||
<div class="col-4" *ngIf="activeEditor == 'works-add' || activeEditor == 'works-modify'"> |
|||
<span class="label">Type</span> |
|||
<select class="input-select" name="type" [(ngModel)]="type"> |
|||
<option [value]="sec.section" *ngFor="let sec of workSections">{{sec.title}}</option> |
|||
</select> |
|||
</div> |
|||
<div class="col-3" *ngIf="activeEditor == 'exhibitions-add' || activeEditor == 'exhibitions-modify'"> |
|||
<span class="label">Date from</span> |
|||
<input type="date" class="input-text w-100" name="dateFrom" [(ngModel)]="dateFrom" (change)="dateTo = dateFrom"> |
|||
</div> |
|||
<div class="col-3" *ngIf="activeEditor == 'exhibitions-add' || activeEditor == 'exhibitions-modify'"> |
|||
<span class="label">Date to</span> |
|||
<input type="date" class="input-text w-100" name="dateTo" [(ngModel)]="dateTo"> |
|||
</div> |
|||
<div class="col-12"> |
|||
<span class="label">Content</span> |
|||
<angular-editor [placeholder]="'Enter text here...'" [config]="editorConfig" name="content" [(ngModel)]="content"></angular-editor> |
|||
</div> |
|||
<div class="col-12"> |
|||
<span class="label">Tags</span> |
|||
<input type="text" class="input-text" name="tags" [(ngModel)]="tags"> |
|||
</div> |
|||
<div class="col-12"> |
|||
<span class="label">Gallery</span> |
|||
<div class="gallery-container"> |
|||
|
|||
<label class="image-add" for="image-add"> |
|||
<input type="file" id="image-add" (change)="onFileChanged($event)"> |
|||
</label> |
|||
|
|||
<div class="image-box" [ngClass]="{'main': image.main}" *ngFor="let image of selectedGallery"> |
|||
<img class="image" [src]="basePath+image.url"> |
|||
<button type="button" class="remove" (click)="galleryRemove(image.url)"><span class="icon-trash-2"></span></button> |
|||
<button type="button" class="set-main" (click)="gallerySetMain(image.url)" *ngIf="!image.main"><span class="icon-check"></span></button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-6" *ngIf="activeEditor == 'works-add' || activeEditor == 'works-modify'"> |
|||
<span class="label">Exhibitions</span> |
|||
<select class="input-select" name="exhibitions" (change)="exhibitionAdd($event.target.value)"> |
|||
<option value=""></option> |
|||
<option value="{{exhibition.id}}" *ngFor="let exhibition of exhibitions"> |
|||
{{exhibition.date_from | date}} | {{exhibition.title}} |
|||
</option> |
|||
</select> |
|||
|
|||
<span class="label font-12 pt-2">Selected exhibitions</span> |
|||
<span class="selected-exhibition" *ngFor="let se of selectedExhibitions" (click)="exhibitionRemove(se.id)"> |
|||
{{se.date_from | date}} | {{se.title}} |
|||
</span> |
|||
</div> |
|||
|
|||
<div class="col-6" *ngIf="activeEditor == 'exhibitions-add' || activeEditor == 'exhibitions-modify'"> |
|||
<span class="label">Works</span> |
|||
<select class="input-select" name="works" (change)="workAdd($event.target.value)"> |
|||
<option value=""></option> |
|||
<option value="{{work.id}}" *ngFor="let work of works"> |
|||
{{work.type}} | {{work.title}} |
|||
</option> |
|||
</select> |
|||
|
|||
<span class="label font-12 pt-2">Selected works</span> |
|||
<span class="selected-work" *ngFor="let sw of selectedWorks" (click)="workRemove(sw.id)"> |
|||
{{sw.type}} | {{sw.title}} |
|||
</span> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-6"> |
|||
<span class="label">Video</span> |
|||
<div class="w-30 d-inline-block pr-2"> |
|||
<select class="input-select" name="videoType" [(ngModel)]="videoType"> |
|||
<option value="youtube">YouTube</option> |
|||
<option value="vimeo">Vimeo</option> |
|||
<option value="embed">Embed</option> |
|||
</select> |
|||
</div> |
|||
<div class="w-60 d-inline-block pr-2"> |
|||
<input type="text" class="input-text" name="videoURL" [(ngModel)]="videoURL"> |
|||
</div> |
|||
<div class="w-10 d-inline-block"> |
|||
<span class="button button-transparent icon-plus-square px-0 w-100" (click)="videoAdd()"></span> |
|||
</div> |
|||
|
|||
<span class="label font-12 pt-2">Selected Videos</span> |
|||
<span class="selected-video" *ngFor="let sv of selectedVideos" (click)="videoRemove(sv.url)"> |
|||
{{sv.type}} | {{sv.url}} |
|||
</span> |
|||
</div> |
|||
<div class="col-12 pt-5"> |
|||
<button class="button w-100" type="submit">Save</button> |
|||
</div> |
|||
</form> |
|||
|
|||
|
|||
<form class="form row" (submit)="deleteData(modifyId)" |
|||
*ngIf="(activeEditor == 'works-delete' || activeEditor == 'exhibitions-delete') && modifyId"> |
|||
<div class="col-12"> |
|||
<span class="label">Title</span> |
|||
<div class="preview-box" *ngIf="activeEditor == 'works-delete'">{{type}} | {{title}}</div> |
|||
<div class="preview-box" *ngIf="activeEditor == 'exhibitions-delete'">{{dateFrom}} | {{title}}</div> |
|||
</div> |
|||
<div class="col-12"> |
|||
<span class="label">Content</span> |
|||
<div class="preview-box" [innerHTML]="content"></div> |
|||
</div> |
|||
|
|||
<div class="col-12"> |
|||
<span class="label">Gallery</span> |
|||
<div class="gallery-container"> |
|||
<div class="image-box" [ngClass]="{'main': image.main}" *ngFor="let image of selectedGallery"> |
|||
<img class="image" [src]="basePath+image.url"> |
|||
<button type="button" class="remove" (click)="galleryRemove(image.url)"><span class="icon-trash-2"></span></button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-12 pt-5"> |
|||
<button class="button w-100" type="submit">Delete</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
@ -0,0 +1,210 @@ |
|||
@import "../../assets/scss/variables"; |
|||
|
|||
.component-admin { |
|||
|
|||
.login-form-container { |
|||
text-align: center; |
|||
padding: 30px 40px; |
|||
color: $white; |
|||
|
|||
.login-label { |
|||
font-size: $font-14; |
|||
color: $black; |
|||
padding: 8px; |
|||
} |
|||
|
|||
.button { |
|||
width: 300px; |
|||
} |
|||
} |
|||
|
|||
.edit-container { |
|||
.title { |
|||
display: block; |
|||
font-size: $font-30; |
|||
font-weight: bolder; |
|||
text-transform: uppercase; |
|||
padding: 20px 0; |
|||
} |
|||
.form { |
|||
.label { |
|||
display: block; |
|||
font-size: $font-20; |
|||
text-transform: uppercase; |
|||
padding: 20px 0 5px 0; |
|||
} |
|||
|
|||
.gallery-container { |
|||
display: flex; |
|||
background: $white; |
|||
border-radius: 4px; |
|||
width: 100%; |
|||
padding: 5px; |
|||
min-height: 100px; |
|||
|
|||
.image-add { |
|||
appearance: none; |
|||
display: inline-block; |
|||
position: relative; |
|||
border: 2px solid $light-gray; |
|||
border-radius: 4px; |
|||
height: 100px; |
|||
width: 100px; |
|||
margin: 5px; |
|||
cursor: pointer; |
|||
|
|||
&:before { |
|||
content: '\e90a'; |
|||
font-family: $font-icon; |
|||
font-size: $font-30; |
|||
color: $light-gray; |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
} |
|||
|
|||
input { |
|||
visibility: hidden; |
|||
} |
|||
} |
|||
|
|||
.image-box { |
|||
display: inline-block; |
|||
position: relative; |
|||
border: 2px solid $light-gray; |
|||
height: 100px; |
|||
width: 120px; |
|||
margin: 5px; |
|||
border-radius: 4px; |
|||
overflow: hidden; |
|||
|
|||
.image { |
|||
position: absolute; |
|||
height: 100%; |
|||
width: 100%; |
|||
object-fit: cover; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.remove, |
|||
.set-main { |
|||
position: absolute; |
|||
top: 4px; |
|||
right: 4px; |
|||
border: 0; |
|||
border-radius: 2px; |
|||
color: $black; |
|||
height: 20px; |
|||
width: 20px; |
|||
background: $white-alpha; |
|||
padding: 0; |
|||
margin: 0; |
|||
cursor: pointer; |
|||
font-size: $font-12; |
|||
z-index: 10; |
|||
} |
|||
|
|||
.remove { |
|||
color: $red; |
|||
} |
|||
.set-main { |
|||
color: $green; |
|||
right: 30px; |
|||
} |
|||
|
|||
&.main { |
|||
border: 2px solid $yellow; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.selected-exhibition, |
|||
.selected-work, |
|||
.selected-video { |
|||
display: block; |
|||
position: relative; |
|||
font-size: $font-16; |
|||
font-weight: bolder; |
|||
border-radius: 4px; |
|||
border: 2px solid $white; |
|||
background: $white-alpha; |
|||
cursor: pointer; |
|||
padding: 8px 50px 8px 15px; |
|||
margin-bottom: 5px; |
|||
|
|||
&:before { |
|||
content: '\e903'; |
|||
position: absolute; |
|||
top: 8px; |
|||
right: 10px; |
|||
font-family: $font-icon; |
|||
font-size: $font-20; |
|||
color: $gray; |
|||
} |
|||
} |
|||
|
|||
.preview-box { |
|||
border-radius: 4px; |
|||
background: $white-alpha2; |
|||
padding: 10px; |
|||
width: 100%; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.menu { |
|||
background: $dark-gray; |
|||
|
|||
.section-title { |
|||
display: block; |
|||
width: 100%; |
|||
padding: 50px 10px 10px; |
|||
font-size: $font-22; |
|||
font-weight: bolder; |
|||
text-transform: uppercase; |
|||
color: $white; |
|||
text-align: center; |
|||
border-bottom: 1px solid $black-alpha; |
|||
} |
|||
|
|||
.action { |
|||
display: block; |
|||
appearance: none; |
|||
border: none; |
|||
border-radius: 0px; |
|||
width: 100%; |
|||
padding: 10px; |
|||
font-size: $font-14; |
|||
text-transform: uppercase; |
|||
color: $white; |
|||
background: $dark-gray; |
|||
cursor: pointer; |
|||
border-bottom: 1px solid $black-alpha; |
|||
|
|||
&.active { |
|||
background: $yellow; |
|||
color: $black; |
|||
border: none; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@media (min-width: map-get($grid-breakpoints, 'md')) { |
|||
.component-admin { |
|||
.menu { |
|||
position: fixed; |
|||
height: 100vh; |
|||
width: 25%; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@media (min-width: map-get($grid-breakpoints, 'lg')) { |
|||
.component-admin { |
|||
.menu { |
|||
width: 16.66%; |
|||
} |
|||
} |
|||
} |
@ -1,20 +1,20 @@ |
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { WorkshopsComponent } from './workshops.component'; |
|||
import { AdminComponent } from './admin.component'; |
|||
|
|||
describe('WorkshopsComponent', () => { |
|||
let component: WorkshopsComponent; |
|||
let fixture: ComponentFixture<WorkshopsComponent>; |
|||
describe('AdminComponent', () => { |
|||
let component: AdminComponent; |
|||
let fixture: ComponentFixture<AdminComponent>; |
|||
|
|||
beforeEach(async(() => { |
|||
TestBed.configureTestingModule({ |
|||
declarations: [ WorkshopsComponent ] |
|||
declarations: [ AdminComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
})); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(WorkshopsComponent); |
|||
fixture = TestBed.createComponent(AdminComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
@ -0,0 +1,437 @@ |
|||
import { Component, OnInit } from '@angular/core' |
|||
import { ApisService } from '../services/apis.service' |
|||
import { AuthService } from '../services/auth.service' |
|||
import { AngularEditorConfig } from '@kolkov/angular-editor' |
|||
import { environment } from '../../environments/environment' |
|||
import { editorConfig } from '../../config/config' |
|||
|
|||
@Component({ |
|||
selector: 'app-admin', |
|||
templateUrl: './admin.component.html', |
|||
styleUrls: ['./admin.component.scss'] |
|||
}) |
|||
export class AdminComponent implements OnInit { |
|||
|
|||
private restApi = `${environment.API_URL}` |
|||
public basePath = `${environment.BASE_PATH}` |
|||
|
|||
public authCheck: boolean = false |
|||
public userName: string = '' |
|||
public password: string = '' |
|||
public activeEditor: string = '' |
|||
public sectionTitle: string = '' |
|||
public activeModify: boolean = false |
|||
public modifyId: number = null |
|||
|
|||
public exhibitions: any = [] |
|||
public works: any = [] |
|||
public selectedExhibitions: any = [] |
|||
public selectedWorks: any = [] |
|||
public selectedVideos: any = [] |
|||
public selectedGallery: any = [] |
|||
|
|||
// ngModels
|
|||
public title: string = '' |
|||
public type: string = '' |
|||
public content: string = '' |
|||
public tags: string = '' |
|||
public dateFrom: string = '' |
|||
public dateTo: string = '' |
|||
public mainImage: string = '' |
|||
public videoType: string = '' |
|||
public videoURL: string = '' |
|||
|
|||
public editorConfig: AngularEditorConfig = editorConfig |
|||
public workSections: any = [ |
|||
{title: 'Entertainment', section: 'entertainment'}, |
|||
{title: 'Installations', section: 'installations'}, |
|||
{title: 'Performances', section: 'performances'}, |
|||
{title: 'Workshops', section: 'workshops'} |
|||
] |
|||
|
|||
constructor( |
|||
private authService: AuthService, |
|||
private apisService: ApisService |
|||
) { } |
|||
|
|||
ngOnInit(): void { |
|||
|
|||
const body = { token: window.sessionStorage.getItem('authToken') } |
|||
this.authService.authCheck(body).toPromise().then((response) => { |
|||
this.authCheck = response.status && response.status == 200 |
|||
|
|||
if(this.authCheck) { |
|||
this.loadData() |
|||
} |
|||
|
|||
},(error) => { |
|||
this.authCheck = false |
|||
console.error('Auth ERROR INIT', error) |
|||
}).catch((e) => { |
|||
this.authCheck = false |
|||
console.error('Auth CATCH INIT', e) |
|||
}) |
|||
} |
|||
|
|||
login(): void { |
|||
const body = { usr: this.userName, pwd: this.password } |
|||
this.authService.login(body).toPromise().then((response) => { |
|||
this.authCheck = response.status && response.status == 200 |
|||
if(this.authCheck) { |
|||
window.sessionStorage.setItem('authToken', response.authToken) |
|||
this.loadData() |
|||
} |
|||
},(error) => { |
|||
console.error('Auth ERROR', error) |
|||
}).catch((e) => { |
|||
console.error('Auth CATCH', e) |
|||
}) |
|||
} |
|||
|
|||
loadData(): void { |
|||
this.apisService.getPortfolio('exhibitions').toPromise().then((response) => { |
|||
this.exhibitions = response.items |
|||
},(error) => { |
|||
console.error('getPortfolio ERROR', error) |
|||
}).catch((e) => { |
|||
console.error('getPortfolio CATCH', e) |
|||
}) |
|||
|
|||
this.apisService.getPortfolio('portfolio').toPromise().then((response) => { |
|||
this.works = response.items |
|||
},(error) => { |
|||
console.error('getPortfolio ERROR', error) |
|||
}).catch((e) => { |
|||
console.error('getPortfolio CATCH', e) |
|||
}) |
|||
} |
|||
|
|||
showEditor(section): void { |
|||
switch(section) { |
|||
case 'works-add': |
|||
this.sectionTitle = 'Add work' |
|||
break; |
|||
case 'works-modify': |
|||
this.sectionTitle = 'Modify work' |
|||
break; |
|||
case 'works-delete': |
|||
this.sectionTitle = 'Delete work' |
|||
break; |
|||
case 'exhibitions-add': |
|||
this.sectionTitle = 'Add exhibition' |
|||
break; |
|||
case 'exhibitions-modify': |
|||
this.sectionTitle = 'Modify exhibition' |
|||
break; |
|||
case 'exhibitions-delete': |
|||
this.sectionTitle = 'Delete exhibition' |
|||
break; |
|||
} |
|||
this.activeModify = false |
|||
this.activeEditor = section |
|||
this.modifyId = null |
|||
this.resetFields() |
|||
} |
|||
|
|||
exhibitionAdd(id): void { |
|||
this.selectedExhibitions.push( |
|||
this.exhibitions.filter(item => item.id == id)[0] |
|||
) |
|||
this.exhibitions = this.exhibitions.filter(item => item.id != id) |
|||
} |
|||
|
|||
exhibitionRemove(id): void { |
|||
this.exhibitions.push( |
|||
this.selectedExhibitions.filter(item => item.id == id)[0] |
|||
) |
|||
this.selectedExhibitions = this.selectedExhibitions.filter(item => item.id != id) |
|||
} |
|||
|
|||
workAdd(id): void { |
|||
this.selectedWorks.push( |
|||
this.works.filter(item => item.id == id)[0] |
|||
) |
|||
this.works = this.works.filter(item => item.id != id) |
|||
} |
|||
|
|||
workRemove(id): void { |
|||
this.works.push( |
|||
this.selectedWorks.filter(item => item.id == id)[0] |
|||
) |
|||
this.selectedWorks = this.selectedWorks.filter(item => item.id != id) |
|||
} |
|||
|
|||
videoAdd(): void { |
|||
this.selectedVideos.push({ |
|||
type: this.videoType, |
|||
url: this.videoURL.replace(/\"/g, "\\\"") |
|||
}) |
|||
this.videoURL = '' |
|||
} |
|||
|
|||
videoRemove(url): void { |
|||
this.selectedVideos = this.selectedVideos.filter(item => item.url != url) |
|||
} |
|||
|
|||
onFileChanged(e) { |
|||
const file = (<HTMLInputElement>e.target).files[0] |
|||
const uploadData = new FormData() |
|||
uploadData.append('token', window.sessionStorage.getItem('authToken')) |
|||
uploadData.append('path', 'assets') |
|||
uploadData.append('file', file, file.name) |
|||
this.apisService.uploadImage(uploadData).toPromise().then((response) => { |
|||
this.selectedGallery.push({ |
|||
title: response.title || '', |
|||
url: response.imageUrl |
|||
}) |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
gallerySetMain(url): void { |
|||
this.selectedGallery.forEach((e) => { |
|||
if(e.url == url) { |
|||
e.main = true |
|||
} else { |
|||
delete e.main |
|||
} |
|||
}) |
|||
} |
|||
|
|||
galleryRemove(url): void { |
|||
const body = { |
|||
token: window.sessionStorage.getItem('authToken'), |
|||
url: url |
|||
} |
|||
this.apisService.removeImage(body).toPromise().then((response) => { |
|||
this.selectedGallery = this.selectedGallery.filter(item => item.url != url) |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
selectWork(id): void { |
|||
this.activeModify = true |
|||
this.modifyId = id |
|||
this.apisService.getDetails('works', id).toPromise().then((response) => { |
|||
const detail = response.item |
|||
this.apisService.getPortfolio('exhibitions').toPromise().then((response) => { |
|||
this.exhibitions = response.items |
|||
this.title = detail.title |
|||
this.content = detail.content |
|||
this.type = detail.type |
|||
this.tags = detail.tags |
|||
this.selectedExhibitions = detail.exhibitions.length ? |
|||
this.exhibitions.filter(item => detail.exhibitions.map(a => a.id).indexOf(item.id) > -1) : [] |
|||
this.selectedGallery = detail.gallery ? JSON.parse(detail.gallery) : [] |
|||
this.selectedVideos = detail.videos ? JSON.parse(detail.videos) : [] |
|||
|
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
selectExhibition(id): void { |
|||
|
|||
this.activeModify = true |
|||
this.modifyId = id |
|||
this.apisService.getDetails('exhibitions', id).toPromise().then((response) => { |
|||
const detail = response.item |
|||
this.apisService.getPortfolio('portfolio').toPromise().then((response) => { |
|||
this.works = response.items |
|||
this.title = detail.title |
|||
this.content = detail.content |
|||
this.tags = detail.tags |
|||
this.dateFrom = detail.date_from |
|||
this.dateTo = detail.date_to |
|||
this.selectedWorks = detail.works.length ? |
|||
this.works.filter(item => detail.works.map(a => a.id).indexOf(item.id) > -1) : [] |
|||
this.selectedGallery = detail.gallery ? JSON.parse(detail.gallery) : [] |
|||
this.selectedVideos = detail.videos ? JSON.parse(detail.videos) : [] |
|||
|
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
saveData(): void { |
|||
if(this.activeEditor == 'works-add' || this.activeEditor == 'works-modify') { |
|||
this.saveWork() |
|||
} |
|||
if(this.activeEditor == 'exhibitions-add' || this.activeEditor == 'exhibitions-modify') { |
|||
this.saveExhibition() |
|||
} |
|||
} |
|||
|
|||
saveWork(): void { |
|||
let error = false |
|||
let errorMessages = [] |
|||
const mainImage = this.selectedGallery.filter(item => item.main) |
|||
|
|||
if(!this.title){ |
|||
error = true |
|||
errorMessages.push('No title') |
|||
} |
|||
if(!this.type){ |
|||
error = true |
|||
errorMessages.push('No type selected') |
|||
} |
|||
|
|||
if(this.selectedGallery.length == 0 || mainImage.length == 0){ |
|||
error = true |
|||
errorMessages.push('No main image selected') |
|||
} |
|||
|
|||
if(error) { |
|||
console.log('ERRORS:',errorMessages) |
|||
} else { |
|||
const body = { |
|||
id: this.activeModify ? this.modifyId : null, |
|||
token: window.sessionStorage.getItem('authToken'), |
|||
title: this.title, |
|||
content: this.content, |
|||
type: this.type, |
|||
tags: this.tags, |
|||
image: mainImage[0].url, |
|||
exhibitions: this.selectedExhibitions.map(a => a.id).join(','), |
|||
gallery: JSON.stringify(this.selectedGallery), |
|||
videos: JSON.stringify(this.selectedVideos) |
|||
} |
|||
|
|||
this.apisService.saveWork(body).toPromise().then((response) => { |
|||
this.resetFields() |
|||
this.works = response.items |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
} |
|||
|
|||
saveExhibition(): void { |
|||
let error = false |
|||
let errorMessages = [] |
|||
const mainImage = this.selectedGallery.filter(item => item.main) |
|||
|
|||
if(!this.title){ |
|||
error = true |
|||
errorMessages.push('No title') |
|||
} |
|||
if(!this.dateFrom){ |
|||
error = true |
|||
errorMessages.push('No date from selected') |
|||
} |
|||
if(!this.dateTo){ |
|||
error = true |
|||
errorMessages.push('No date to selected') |
|||
} |
|||
if(this.selectedGallery.length == 0 || mainImage.length == 0){ |
|||
error = true |
|||
errorMessages.push('No main image selected') |
|||
} |
|||
|
|||
if(error) { |
|||
console.log('ERRORS:',errorMessages) |
|||
} else { |
|||
const body = { |
|||
id: this.activeModify ? this.modifyId : null, |
|||
token: window.sessionStorage.getItem('authToken'), |
|||
title: this.title, |
|||
content: this.content, |
|||
date_from: this.dateFrom, |
|||
date_to: this.dateTo, |
|||
tags: this.tags, |
|||
image: mainImage[0].url, |
|||
works: this.selectedWorks.map(a => a.id).join(','), |
|||
gallery: JSON.stringify(this.selectedGallery), |
|||
videos: JSON.stringify(this.selectedVideos) |
|||
} |
|||
|
|||
this.apisService.saveExhibition(body).toPromise().then((response) => { |
|||
this.resetFields() |
|||
this.exhibitions = response.items |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
} |
|||
|
|||
deleteData(id): void { |
|||
if(this.activeEditor == 'works-delete') { |
|||
this.deleteWork(id) |
|||
} |
|||
if(this.activeEditor == 'exhibitions-delete') { |
|||
this.deleteExhibition(id) |
|||
} |
|||
} |
|||
|
|||
deleteWork(id): void { |
|||
|
|||
const body = { |
|||
id: id, |
|||
token: window.sessionStorage.getItem('authToken') |
|||
} |
|||
|
|||
this.apisService.deleteWork(body).toPromise().then((response) => { |
|||
this.resetFields() |
|||
this.works = response.items |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
deleteExhibition(id): void { |
|||
|
|||
const body = { |
|||
id: id, |
|||
token: window.sessionStorage.getItem('authToken') |
|||
} |
|||
|
|||
this.apisService.deleteExhibition(body).toPromise().then((response) => { |
|||
this.resetFields() |
|||
this.exhibitions = response.items |
|||
},(error) => { |
|||
console.error(error) |
|||
}).catch((e) => { |
|||
console.error(e) |
|||
}) |
|||
} |
|||
|
|||
resetFields(): void { |
|||
this.title = '' |
|||
this.content = '' |
|||
this.type = '' |
|||
this.tags = '' |
|||
this.dateFrom = '' |
|||
this.dateTo = '' |
|||
this.selectedExhibitions = [] |
|||
this.selectedWorks = [] |
|||
this.selectedGallery = [] |
|||
this.selectedVideos = [] |
|||
this.modifyId = null |
|||
} |
|||
} |
@ -1,4 +1,5 @@ |
|||
<app-header></app-header> |
|||
<app-header *ngIf="page != '/admin'"></app-header> |
|||
<router-outlet></router-outlet> |
|||
|
|||
<Particles class="particles" [id]="id" [options]="particlesOptions" (particlesLoaded)="particlesLoaded($event)" *ngIf="particlesEnabled"></Particles> |
|||
<Particles class="particles" *ngIf="particlesEnabled && page != '/admin'" |
|||
[id]="id" [options]="particlesOptions" (particlesLoaded)="particlesLoaded($event)"></Particles> |
|||
|
@ -0,0 +1,16 @@ |
|||
import { TestBed } from '@angular/core/testing'; |
|||
|
|||
import { AuthService } from './auth.service'; |
|||
|
|||
describe('AuthService', () => { |
|||
let service: AuthService; |
|||
|
|||
beforeEach(() => { |
|||
TestBed.configureTestingModule({}); |
|||
service = TestBed.inject(AuthService); |
|||
}); |
|||
|
|||
it('should be created', () => { |
|||
expect(service).toBeTruthy(); |
|||
}); |
|||
}); |
@ -0,0 +1,33 @@ |
|||
import { Injectable } from '@angular/core' |
|||
import { HttpClient, HttpHeaders, HttpParams, HttpRequest } from '@angular/common/http' |
|||
import { Observable, Subject, throwError } from 'rxjs' |
|||
import { catchError } from 'rxjs/operators' |
|||
import { BaseService } from './base-service' |
|||
import { environment } from '../../environments/environment' |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root' |
|||
}) |
|||
export class AuthService extends BaseService { |
|||
|
|||
private restApi = `${environment.API_URL}` |
|||
|
|||
constructor(private http: HttpClient) { |
|||
super() |
|||
} |
|||
|
|||
login(body): Observable<any> { |
|||
let urlApi = `${this.restApi}auth.php?act=login` |
|||
return this.http.post<any>(urlApi, JSON.stringify(body)).pipe( |
|||
catchError(this.handleError) |
|||
) |
|||
} |
|||
|
|||
authCheck(body): Observable<any> { |
|||
let urlApi = `${this.restApi}auth.php?act=check` |
|||
return this.http.post<any>(urlApi, JSON.stringify(body)).pipe( |
|||
catchError(this.handleError) |
|||
) |
|||
} |
|||
|
|||
} |
@ -1 +0,0 @@ |
|||
<p>workshops works!</p> |
@ -1,15 +0,0 @@ |
|||
import { Component, OnInit } from '@angular/core'; |
|||
|
|||
@Component({ |
|||
selector: 'app-workshops', |
|||
templateUrl: './workshops.component.html', |
|||
styleUrls: ['./workshops.component.scss'] |
|||
}) |
|||
export class WorkshopsComponent implements OnInit { |
|||
|
|||
constructor() { } |
|||
|
|||
ngOnInit(): void { |
|||
} |
|||
|
|||
} |
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 79 KiB |
@ -0,0 +1,90 @@ |
|||
|
|||
|
|||
input, |
|||
select, |
|||
button, |
|||
textarea { |
|||
border: none; |
|||
border-radius: 4px; |
|||
background: $white; |
|||
appearance: none; |
|||
font-family: $font-primary; |
|||
font-size: $font-20; |
|||
resize: none; |
|||
&::-ms-clear { |
|||
display: none; |
|||
} |
|||
&:focus {outline:none;} |
|||
&::-moz-focus-inner {border:0;} |
|||
} |
|||
|
|||
input[type=text], |
|||
input[type=password], |
|||
input[type=file], |
|||
select { |
|||
color: $black; |
|||
padding: 10px 20px; |
|||
width: 100%; |
|||
text-align: left; |
|||
box-sizing: border-box; |
|||
&:focus::placeholder { |
|||
color: transparent; |
|||
} |
|||
} |
|||
|
|||
.input-text { |
|||
padding: 10px 20px !important; |
|||
} |
|||
|
|||
.input-file { |
|||
padding: 6px 20px !important; |
|||
} |
|||
|
|||
.input-textarea, |
|||
.angular-editor { |
|||
border-radius: 4px; |
|||
background: $white; |
|||
padding: 10px; |
|||
width: 100%; |
|||
} |
|||
|
|||
.input-select { |
|||
padding: 9px 20px !important; |
|||
background-image: url('/assets/images/angle-down.svg'); |
|||
background-size: 28px; |
|||
background-position: right 10px top 10px; |
|||
background-repeat: no-repeat; |
|||
} |
|||
|
|||
.button { |
|||
position: relative; |
|||
appearance: none; |
|||
color: $white; |
|||
border: none; |
|||
border-radius: 4px; |
|||
background: $black; |
|||
display: inline-block; |
|||
padding: 10px 20px 10px 20px !important; |
|||
text-align: center; |
|||
font-family: $font-20; |
|||
text-transform: uppercase; |
|||
font-weight: 500; |
|||
transition: opacity .3s; |
|||
white-space: nowrap; |
|||
outline: none; |
|||
cursor: pointer; |
|||
|
|||
&:disabled { |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
&.button-white { |
|||
background: $white; |
|||
color: $black !important; |
|||
} |
|||
|
|||
&.button-transparent { |
|||
background: $white-alpha2; |
|||
color: $black !important; |
|||
} |
|||
} |
@ -0,0 +1,52 @@ |
|||
import { environment } from '../environments/environment' |
|||
import { AngularEditorConfig } from '@kolkov/angular-editor' |
|||
|
|||
export const editorConfig: AngularEditorConfig = { |
|||
editable: true, |
|||
spellcheck: true, |
|||
height: '300px', |
|||
translate: 'no', |
|||
enableToolbar: true, |
|||
showToolbar: true, |
|||
placeholder: 'Enter text here...', |
|||
defaultParagraphSeparator: 'p', |
|||
defaultFontName: '', |
|||
defaultFontSize: '', |
|||
uploadUrl: `${environment.API_URL}upload.php`, |
|||
uploadWithCredentials: false, |
|||
sanitize: true, |
|||
toolbarPosition: 'top', |
|||
toolbarHiddenButtons: [ |
|||
[ |
|||
'undo', |
|||
'redo', |
|||
//'bold',
|
|||
//'italic',
|
|||
//'underline',
|
|||
'strikeThrough', |
|||
'subscript', |
|||
'superscript', |
|||
//'justifyLeft',
|
|||
//'justifyCenter',
|
|||
//'justifyRight',
|
|||
//'justifyFull',
|
|||
'indent', |
|||
'outdent', |
|||
'insertUnorderedList', |
|||
'insertOrderedList', |
|||
'heading', |
|||
'fontName', |
|||
'fontSize', |
|||
'textColor', |
|||
'backgroundColor', |
|||
'customClasses', |
|||
//'link',
|
|||
'unlink', |
|||
//'insertImage',
|
|||
'insertVideo', |
|||
'insertHorizontalRule', |
|||
//'removeFormat',
|
|||
//'toggleEditorMode'
|
|||
] |
|||
] |
|||
} |
@ -1,5 +1,5 @@ |
|||
export const environment = { |
|||
production: true, |
|||
|
|||
API_URL: `https://apis.dslak.it/` |
|||
API_URL: `https://www.dslak.it/apis/`, |
|||
BASE_PATH: `https://www.dslak.it` |
|||
} |
|||
|
@ -1,5 +1,5 @@ |
|||
export const environment = { |
|||
production: false, |
|||
|
|||
API_URL: `http://dslakng.local/apis/` |
|||
API_URL: `http://dslakng.local/apis/`, |
|||
BASE_PATH: `http://dslakng.local` |
|||
} |
|||
|
Loading…
Reference in new issue