Zona de administracion para agregar eventos y subir imagenes

This commit is contained in:
2020-06-16 22:44:48 -04:00
parent c09165529f
commit b943a21890
32 changed files with 1228 additions and 97 deletions

View File

@ -36,6 +36,10 @@ return [
'{urls.base}',
'eventos'
])),
'admin' => DI\string(implode('/', [
'{urls.base}',
'admin'
])),
'map' => 'https://maps.google.com/maps?hl=es&q=Avenida%20Nueva%20Providencia%201945,%20Providencia&ie=UTF8&z=16&iwloc=B&output=embed'
],
'assets' => [

View File

@ -15,5 +15,13 @@ return [
'assets' => (object) $c->get('assets')
]
);
},
ProVM\TotalSport\Common\Service\MediaLoader::class => function(Container $c) {
$obj = new ProVM\TotalSport\Common\Service\MediaLoader($c->get('folders.images'), $c->get('urls')['images']);
$obj->setFFMpeg($c->get(FFMpeg\FFMpeg::class));
return $obj;
},
FFMpeg\FFMpeg::class => function(Container $c) {
return FFMpeg\FFMpeg::create();
}
];

View File

@ -0,0 +1,126 @@
<?php
namespace ProVM\TotalSport\Common\Controller\Web\Admin;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
use ProVM\TotalSport\Common\Service\DataHandler;
use ProVM\TotalSport\Common\Service\MediaLoader;
class Eventos {
public function __invoke(Request $request, Response $response, View $view, DataHandler $handler): Response {
$eventos = $handler->load('eventos');
return $view->render($response, 'admin.eventos', compact('eventos'));
}
public function show(Request $request, Response $response, View $view, DataHandler $handler, MediaLoader $loader, $evento): Response {
$eventos = $handler->load('eventos');
$e = $eventos[$evento];
$e->id = $evento;
$imagenes = $loader->load($e);
$servicios = $handler->load('servicios');
return $view->render($response, 'admin.eventos.show', ['evento' => $e, 'imagenes' => $imagenes, 'servicios' => $servicios]);
}
public function edit(Request $request, Response $response, Container $container, DataHandler $handler, $evento): Response {
$eventos = $handler->load('eventos');
$e = $eventos[$evento];
$post = $request->getParsedBody();
$servicios = $handler->load('servicios');
$fields = ['titulo', 'empresa', 'servicio', 'descripcion'];
$changed = false;
foreach ($fields as $field) {
if ($post[$field] != $e->{$field}) {
$e->{$field} = $post[$field];
$changed = true;
}
}
if ($changed) {
$eventos[$evento] = $e;
$handler->save('eventos', $eventos);
}
return $response->withHeader('Location', implode('/', [
$container->get('urls')['admin'],
'eventos'
]));
}
public function add(Request $request, Response $response, View $view, DataHandler $handler): Response {
$servicios = $handler->load('servicios');
return $view->render($response, 'admin.eventos.add', compact('servicios'));
}
public function do_add(Request $request, Response $response, Container $container, DataHandler $handler): Response {
$post = $request->getParsedBody();
$eventos = $handler->load('eventos');
$evento = [
'titulo' => $post['titulo'],
'empresa' => $post['empresa'],
'servicio' => $post['servicio'],
'descripcion' => $post['descripcion']
];
$eventos []= $evento;
$status = $handler->save('eventos', $eventos);
return $response->withHeader('Location', implode('/', [
$container->get('urls')['admin'],
'eventos'
]));
}
public function delete(Request $request, Response $response, Container $container, DataHandler $handler, MediaLoader $loader, $evento): Response {
$eventos = $handler->load('eventos');
unset($eventos[$evento]);
$eventos = array_values($eventos);
$handler->save('eventos', $eventos);
return $response->withHeader('Location', implode('/', [
$container->get('urls')['admin'],
'eventos'
]));
}
public function addImage(Request $request, Response $response, DataHandler $handler, MediaLoader $loader, $evento): Response {
$post = $request->getParsedBody();
$files = $request->getUploadedFiles();
if (count($files) == 0) {
$output = [
'informacion' => '',
'evento' => $e,
'estado' => false
];
$response->getBody()->write(json_encode($output));
return $response
->withHeader('Content-Type', 'application/json')
->withStatus(201);
}
$file = $files['imagen'];
$eventos = $handler->load('eventos');
$e = $eventos[$evento];
if (is_array($file)) {
$status = false;
foreach ($file as $f) {
$status |= $loader->add($e, $f);
}
} else {
$status = $loader->add($e, $file);
}
$output = [
'informacion' => $file,
'evento' => $e,
'estado' => $status
];
$response->getBody()->write(json_encode($output));
return $response
->withHeader('Content-Type', 'application/json')
->withStatus(201);
}
public function deleteImage(Request $request, Response $response, DataHandler $handler, MediaLoader $loader, $evento): Response {
$post = $request->getParsedBody();
$eventos = $handler->load('eventos');
$e = $eventos[$evento];
$status = $loader->delete($e, $post['media']);
$output = [
'informacion' => $file,
'evento' => $e,
'estado' => !$status
];
$response->getBody()->write(json_encode($output));
return $response
->withHeader('Content-Type', 'application/json')
->withStatus(201);
}
}

View File

@ -6,10 +6,10 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
use ProVM\TotalSport\Common\Service\DataHandler;
use ProVM\TotalSport\Common\Service\ImageLoader;
use ProVM\TotalSport\Common\Service\MediaLoader;
class Eventos {
public function __invoke(Request $request, Response $response, View $view, DataHandler $handler, ImageLoader $loader, $evento): Response {
public function __invoke(Request $request, Response $response, View $view, DataHandler $handler, MediaLoader $loader, $evento): Response {
$eventos = $handler->load('eventos');
$e = $eventos[$evento];
$imagenes = $loader->load($e);

View File

@ -6,10 +6,10 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
use ProVM\TotalSport\Common\Service\DataHandler;
use ProVM\TotalSport\Common\Service\ImageLoader;
use ProVM\TotalSport\Common\Service\MediaLoader;
class Home {
public function __invoke(Request $request, Response $response, Container $container, View $view, DataHandler $handler, ImageLoader $loader): Response {
public function __invoke(Request $request, Response $response, Container $container, View $view, DataHandler $handler, MediaLoader $loader): Response {
$banner = (object) [
'title' => 'BUSCAMOS LA MEJOR EXPERIENCA',
'contenido' => 'Eventos hechos a tu medida'
@ -28,10 +28,10 @@ class Home {
$eventos = $handler->load('eventos');
foreach ($eventos as &$evento) {
if (!isset($evento->imagen)) {
$evento->imagen = '#';
$evento->imagen = '<img src="#" alt="Imagen no encontrada" title="Imagen no encontrada" />';
$imagenes = $loader->load($evento);
if ($imagenes !== false) {
$evento->imagen = $imagenes[0];
$evento->imagen = array_values($imagenes)[0]->thumb->html;
}
}
if (!isset($evento->servicio)) {

View File

@ -15,4 +15,11 @@ class DataHandler {
]);
return json_decode(json_encode(Spyc::YAMLLoad($filename)));
}
public function save(string $file_name, $data) {
$filename = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$file_name . '.yml'
]);
return (file_put_contents($filename, Spyc::YAMLDump($data)) !== false);
}
}

View File

@ -10,8 +10,8 @@ class ImageLoader {
$this->folder = $images_folder;
$this->assets_folder = $images_assets_folder;
}
public function load($event) {
$folder = implode(DIRECTORY_SEPARATOR, [
protected function getFolder($event) {
return implode(DIRECTORY_SEPARATOR, [
$this->folder,
'eventos',
s($event->servicio)->removeLeft('Eventos '),
@ -20,6 +20,9 @@ class ImageLoader {
$event->empresa
]), ', ')
]);
}
public function load($event) {
$folder = $this->getFolder($event);
if (!file_exists($folder)) {
return false;
}
@ -29,6 +32,18 @@ class ImageLoader {
if ($file->isDir()) {
continue;
}
$name = $file->getBasename('.' . $file->getExtension());
$org = false;
$thumb = false;
if (strpos($name, '_') !== false) {
$name = explode('_', $name)[0];
if (strpos($name, '_org') !== false) {
$org = true;
}
if (strpos($name, '_thumb') !== false) {
$thumb = true;
}
}
$images []= implode('/', [
$this->assets_folder,
'eventos',
@ -42,4 +57,28 @@ class ImageLoader {
}
return $images;
}
public function add($event, $file) {
$folder = $this->getFolder($event);
if (!file_exists($folder)) {
mkdir($folder);
chmod($folder, 777);
}
$images = $this->load($event);
$base_name = '01';
if ($images !== false and count($images) > 0) {
$base_name = str_pad(count($images), 2, '0', \STR_PAD_LEFT);
}
$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
implode('_', [
$base_name,
'org'
]),
$extension
])
]);
$file->moveTo($filename);
}
}

View File

@ -0,0 +1,303 @@
<?php
namespace ProVM\TotalSport\Common\Service;
use function Stringy\create as s;
use FFMpeg\FFMpeg;
class MediaLoader {
protected $folder;
protected $media_url;
public function __construct(string $media_folder, string $media_assets_url) {
$this->folder = $media_folder;
$this->media_url = $media_assets_url;
}
protected $ffmpeg;
public function setFFMpeg(FFMpeg $ffmpeg) {
$this->ffmpeg = $ffmpeg;
}
protected function getFolder($event) {
return implode(DIRECTORY_SEPARATOR, [
$this->folder,
'eventos',
s($event->servicio)->removeLeft('Eventos '),
rtrim(implode(', ', [
$event->titulo,
$event->empresa
]), ', ')
]);
}
protected function buildHtml($file, $filename) {
switch ($file->getExtension()) {
default:
return implode('', [
'<img src="',
$filename,
'" class="media" />'
]);
case 'mkv':
case 'mp4':
case 'mov':
case 'avi':
case 'ogg':
case 'webm':
return implode(PHP_EOL, [
'<video class="media" controls="controls">',
implode('', [
'<source src="',
$filename,
'" type="video/',
$file->getExtension(),
'" />'
]),
'No se soporta el elemento de video para HTML5 en este navegador.',
'</video>'
]);
}
}
public function load($event) {
$folder = $this->getFolder($event);
if (!file_exists($folder)) {
return false;
}
$files = new \DirectoryIterator($folder);
$medias = [];
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$name = $file->getBasename('.' . $file->getExtension());
$type = 'media';
if (strpos($name, '_') !== false) {
if (strpos($name, '_org') !== false) {
$type = 'original';
}
if (strpos($name, '_thumb') !== false) {
$type = 'thumb';
}
$name = explode('_', $name)[0];
}
$filename = implode('/', [
$this->media_url,
'eventos',
s($event->servicio)->removeLeft('Eventos '),
($event->empresa != '') ?
rtrim(implode(', ', [
$event->titulo,
$event->empresa
]), ', ') :
$event->titulo,
$file->getFilename()
]);
$obj = (object) [
'n' => $name,
'filename' => $filename,
'type' => $type,
'html' => $this->buildHtml($file, $filename)
];
if (!isset($medias[$name])) {
$medias[$name] = (object) [
'media' => null,
'thumb' => null,
'original' => null
];
}
$medias[$name]->{$type} = $obj;
}
array_walk($medias, function(&$item) {
if ($item->thumb === null) {
$item->thumb = $item->media;
}
});
return $medias;
}
public function add($event, $file) {
$folder = $this->getFolder($event);
if (!file_exists($folder)) {
mkdir($folder);
chmod($folder, 777);
}
$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
switch ($extension) {
default:
return $this->addImage($event, $file);
case 'mkv':
case 'mp4':
case 'mov':
case 'avi':
case 'ogg':
case 'webm':
return $this->addVideo($event, $file);
}
}
public function addImage($event, $file) {
$folder = $this->getFolder($event);
$medias = $this->load($event);
$base_name = '01';
if ($medias !== false and count($medias) > 0) {
$base_name = str_pad(count($medias) + 1, 2, '0', \STR_PAD_LEFT);
}
$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
implode('_', [
$base_name,
'org'
]),
$extension
])
]);
$file->moveTo($filename);
$thumb = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
implode('_', [
$base_name,
'thumb'
]),
'jpg'
])
]);
$this->copyResize($filename, $thumb, 50, 300);
$media = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
$base_name,
'jpg'
])
]);
$this->copyResize($filename, $media, 75, 1024);
return file_exists($filename);
}
protected function resize_image($source, $w, $h, $crop = FALSE) {
list($width, $height) = getimagesize($source);
$r = $width / $height;
if ($crop) {
if ($width > $height) {
$width = ceil($width-($width*abs($r-$w/$h)));
} else {
$height = ceil($height-($height*abs($r-$w/$h)));
}
$newwidth = $w;
$newheight = $h;
} else {
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
}
$src = imagecreatefromjpeg($file);
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
return $dst;
}
protected function copyResize($source, $destination, $quality, $w, $h = 0) {
$info = getimagesize($source);
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($source);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($source);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($source);
}
list($width, $height) = getimagesize($source);
$r = $width / $height;
if ($h == 0) {
$h = $w * $r;
}
if ($crop) {
if ($width > $height) {
$width = ceil($width-($width*abs($r-$w/$h)));
} else {
$height = ceil($height-($height*abs($r-$w/$h)));
}
$newwidth = $w;
$newheight = $h;
} else {
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
}
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagejpeg($dst, $destination, $quality);
}
public function addVideo($event, $file) {
$folder = $this->getFolder($event);
$medias = $this->load($event);
$base_name = '01';
if ($medias !== false and count($medias) > 0) {
$base_name = str_pad(count($medias) + 1, 2, '0', \STR_PAD_LEFT);
}
$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
implode('_', [
$base_name,
'org'
]),
$extension
])
]);
$file->moveTo($filename);
$thumb = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
implode('_', [
$base_name,
'thumb'
]),
'jpg'
])
]);
$video
->filters()
->resize(new FFMpeg\Coordinate\Dimension(320, 240))
->synchronize();
$video
->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(1))
->save($thumb);
$media = implode(DIRECTORY_SEPARATOR, [
$folder,
implode('.', [
$base_name,
$extension
])
]);
$video
->save(new FFMpeg\Format\Video\X264(), $media);
}
public function delete($event, $filename) {
$folder = $this->getFolder($event);
$media = implode(DIRECTORY_SEPARATOR, [
$folder,
$filename . '*.*'
]);
$files = glob($media);
foreach ($files as $filename) {
unlink($filename);
}
if (count(scandir($folder)) <= 2) {
rmdir($folder);
}
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
$filename . '.jpg'
]);
return file_exists($filename);
}
}

View File

@ -17,7 +17,8 @@
"rubellum/slim-blade-view": "^0.1.1",
"mustangostang/spyc": "^0.6.3",
"voku/stringy": "^6.2",
"vlucas/phpdotenv": "^4.1"
"vlucas/phpdotenv": "^4.1",
"php-ffmpeg/php-ffmpeg": "^0.16.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5",

View File

@ -11,6 +11,7 @@
}
#banner .header {
font-family: inherit;
line-height: 2rem;
}
#servicios {
@ -87,6 +88,19 @@
background-color: white;
padding: 0;
}
#eventos .segment .image {
height: 14rem;
overflow: hidden;
}
#eventos .segment .image img {
height: 100%;
max-width: none !important;
}
#eventos .segment .header {
margin-top: 0;
padding-top: 1rem;
height: 7rem;
}
#contacto {
padding-top: 4rem;

View File

@ -1,68 +1,171 @@
- titulo: Activación Olimpiadas del Seguro 2019
---
-
titulo: Activación Olimpiadas del Seguro 2019
empresa: Consorcio
servicio: Eventos Calidad de Vida
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Día del niño 2017
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Día del niño 2017
empresa: Fresenius Kabi
servicio: Eventos Calidad de Vida
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Fiestras patrias 2019
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Fiestras patrias 2019
empresa: Consorcio
servicio: Eventos Calidad de Vida
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Olimpiadas del Seguro 2019
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Olimpiadas del Seguro 2019
empresa: Intervención Chilena Consolidada
servicio: Eventos Calidad de Vida
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Pausas Activas 2018
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Pausas Activas 2018
empresa: Dimeiggs
servicio: Eventos Calidad de Vida
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Campeonato baby Futbol 2018
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Campeonato baby Futbol 2018
empresa: AZA
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Campeonato Futbol Varones 2019
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Campeonato Futbol Varones 2019
empresa: Chilena Consolidada
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Campeonato Voleibol 2019
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Campeonato Voleibol 2019
empresa: Dimerc
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Campeonato Futbolito 2017
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Campeonato Futbolito 2017
empresa: Dimerc
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Final Nacional Campeonato Futbolito 2012
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Final Nacional Campeonato Futbolito 2012
empresa: Gildemeister
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Futbol Varones senior 2019
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Futbol Varones senior 2019
empresa: Olimpiadas del Seguro
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Liga Consumidores
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Liga Consumidores
empresa: ""
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Liga Futbar
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Liga Futbar
empresa: ""
servicio: Eventos Deportivos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: 2da Corrida Familiar Inclusiva
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: 2da Corrida Familiar Inclusiva
empresa: DIMERC
servicio: Eventos Recreativos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Dia de la Familia
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Dia de la Familia
empresa: BUPA
servicio: Eventos Recreativos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Fiestas Patrias
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Fiestas Patrias
empresa: CONSORCIO
servicio: Eventos Recreativos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
- titulo: Pausas Activas
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos
-
titulo: Pausas Activas
empresa: DIMEIGGS
servicio: Eventos Recreativos
descripcion: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nos"
descripcion: >
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nos

View File

@ -0,0 +1,9 @@
- evento: Activación Olimpiadas del Seguro 2019, Consorcio
imagenes:
- P1040997.JPG
- P1040998.JPG
- P1040999.JPG
- P1050003.JPG
- P1050006.JPG
- P1050008.JPG
- P1050010.JPG

View File

@ -0,0 +1,16 @@
<?php
$app->group('/admin', function($app) {
$folder = implode(DIRECTORY_SEPARATOR, [
__DIR__,
'admin'
]);
if (file_exists($folder)) {
$files = new DirectoryIterator($folder);
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
include_once $file->getRealPath();
}
}
});

View File

@ -0,0 +1,17 @@
<?php
use ProVM\TotalSport\Common\Controller\Web\Admin\Eventos;
$app->group('/eventos', function($app) {
$app->group('/add', function($app) {
$app->get('[/]', [Eventos::class, 'add']);
$app->post('[/]', [Eventos::class, 'do_add']);
});
$app->get('[/]', Eventos::class);
});
$app->group('/evento/{evento}', function($app) {
$app->post('/edit', [Eventos::class, 'edit']);
$app->post('/add', [Eventos::class, 'addImage']);
$app->get('/delete', [Eventos::class, 'delete']);
$app->post('/image/delete', [Eventos::class, 'deleteImage']);
$app->get('[/]', [Eventos::class, 'show']);
});

View File

@ -0,0 +1,46 @@
@extends('admin.layout.base')
@section('page_content')
<div class="ui container">
<div class="ui header">
Eventos
</div>
<table class="ui collapsing table">
<thead>
<tr>
<th colspan="3" class="right aligned">
<a href="{{$urls->admin}}/eventos/add">
<button class="ui blue button">
Agregar
</button>
</a>
</th>
</tr>
<tr>
<th>Evento</th>
<th>Editar</th>
<th>Borrar</th>
</tr>
</thead>
<tbody>
@foreach ($eventos as $i => $evento)
<tr>
<td>
{{($evento->empresa != '') ? implode(', ', [$evento->titulo, $evento->empresa]) : $evento->titulo}}
</td>
<td>
<a href="{{$urls->admin}}/evento/{{$i}}">
<i class="edit icon"></i>
</a>
</td>
<td>
<a href="{{$urls->admin}}/evento/{{$i}}/delete">
<i class="trash icon"></i>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection

View File

@ -0,0 +1,77 @@
@extends('admin.layout.base')
@section('page_content')
<div class="ui container">
<h1 class="ui header">
Evento
</h1>
<br />
<form class="ui form" method="post" action="{{$urls->admin}}/eventos/add">
<div class="ui grid">
<div class="row">
<div class="two wide column">
<div class="ui header">
Titulo
</div>
</div>
<div class="ten wide column">
<div class="ui fluid input">
<input type="text" name="titulo" value="{{$evento->titulo}}" />
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<div class="ui header">
Empresa
</div>
</div>
<div class="six wide column">
<div class="ui fluid input">
<input type="text" name="empresa" value="{{$evento->empresa}}" />
</div>
</div>
<div class="two wide column">
</div>
<div class="six wide column">
<div class="ui selection dropdown" id="servicio">
<input type="hidden" name="servicio" value="{{$evento->servicio}}" />
<i class="dropdown icon"></i>
<div class="default text">Servicio</div>
<div class="menu">
@foreach ($servicios as $servicio)
<div class="item" data-value="{{$servicio->titulo}}">{{$servicio->titulo}}</div>
@endforeach
</div>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<div class="ui header">
Descripcion
</div>
</div>
<div class="eight wide column">
<div class="ui fluid input">
<textarea name="descripcion">{{$evento->descripcion}}</textarea>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<button class="ui fluid button">Guardar</button>
</div>
</div>
</div>
</form>
</div>
@endsection
@push('scripts')
<script type="text/javascript">
$(document).ready(() => {
$('#servicio').dropdown()
})
</script>
@endpush

View File

@ -0,0 +1,190 @@
@extends('admin.layout.base')
@section('page_content')
<div class="ui container">
<h1 class="ui header">
Evento
</h1>
<br />
<form class="ui form" method="post" action="{{$urls->admin}}/evento/{{$evento->id}}/edit">
<div class="ui grid">
<div class="row">
<div class="two wide column">
<div class="ui header">
Titulo
</div>
</div>
<div class="ten wide column">
<div class="ui fluid input">
<input type="text" name="titulo" value="{{$evento->titulo}}" />
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<div class="ui header">
Empresa
</div>
</div>
<div class="six wide column">
<div class="ui fluid input">
<input type="text" name="empresa" value="{{$evento->empresa}}" />
</div>
</div>
<div class="two wide column">
</div>
<div class="six wide column">
<div class="ui selection dropdown" id="servicio">
<input type="hidden" name="servicio" value="{{$evento->servicio}}" />
<i class="dropdown icon"></i>
<div class="default text">Servicio</div>
<div class="menu">
@foreach ($servicios as $servicio)
<div class="item" data-value="{{$servicio->titulo}}">{{$servicio->titulo}}</div>
@endforeach
</div>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<div class="ui header">
Descripcion
</div>
</div>
<div class="eight wide column">
<div class="ui fluid input">
<textarea name="descripcion">{{$evento->descripcion}}</textarea>
</div>
</div>
</div>
<div class="row">
<div class="two wide column">
<button class="ui fluid button">Guardar</button>
</div>
</div>
</div>
</form>
<div class="ui header">
Media
</div>
<table class="ui collapsing table" id="imagenes">
<thead>
<tr>
<th colspan="2" class="right aligned">
<i class="plus icon" id="agregar_imagen"></i>
</th>
</tr>
<tr>
<th>Archivo</th>
<th>Borrar</th>
</tr>
</thead>
<tbody>
@if ($imagenes)
@foreach (array_values($imagenes) as $i => $imagen)
<tr>
<td>{{$imagen->media->n}}</td>
<td>
<i class="trash icon" data-media="{{$i}}"></i>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
</div>
@endsection
@push('scripts')
<script type="text/javascript">
var imagenes = {
imagenes: [
@if ($imagenes)
@foreach (array_values($imagenes) as $imagen)
'{{$imagen->media->n}}',
@endforeach
@endif
],
setup: () => {
$('#agregar_imagen').css('cursor', 'pointer').click(() => {
imagenes.add()
})
$('.trash.icon').css('cursor', 'pointer').click(function() {
let i = $(this).attr('data-media')
imagenes.deleteImage(i)
})
},
add: () => {
var imgs = $('#imagenes')
var div = imgs.next('.modal')
if (div.length > 0) {
div.remove()
}
div = $('<div></div>').attr('class', 'ui modal').append(
$('<i></i>').attr('class', 'inside close icon')
)
if (imagenes.imagenes.length >= 12) {
div.append(
$('<div></div>').attr('class', 'header').html('Media')
).append(
$('<div></div>').attr('class', 'content').html('Se ha llegado al máximo de media.')
)
imgs.after(div)
div.modal('show')
return
}
div.append(
$('<div></div>').attr('class', 'header').html('Media')
).append(
$('<div></div>').attr('class', 'content').append(
$('<form></form>').attr('class', 'ui form').attr('id', 'add_image').append(
$('<div></div>').attr('class', 'ui fluid input').append(
$('<input />').attr('type', 'file').attr('name', 'imagen[]').attr('multiple', 'multiple')
)
).append(
$('<button></button>').attr('class', 'ui button').html('Agregar')
)
)
)
imgs.after(div)
div.modal('show')
div.find('form').submit((e) => {
e.preventDefault()
imagenes.addImage()
return false
})
},
addImage: () => {
let form = $('#add_image')
let data = new FormData(form[0])
let url = '{{$urls->admin}}/evento/{{$evento->id}}/add'
$.ajax({
url: url,
data: data,
processData: false,
contentType: false,
type: 'POST',
success: (output) => {
if (output.estado) {
window.location.reload()
}
}
})
},
deleteImage: (i) => {
let media = imagenes.imagenes[i]
let url = '{{$urls->admin}}/evento/{{$evento->id}}/image/delete'
$.post(url, {media: media}, (output) => {
if (output.estado) {
window.location.reload()
}
})
}
}
$(document).ready(() => {
$('#servicio').dropdown()
imagenes.setup()
})
</script>
@endpush

View File

@ -0,0 +1,5 @@
<!DOCTYPE html>
<html lang="es">
@include('admin.layout.head')
@include('admin.layout.body')
</html>

View File

@ -0,0 +1,6 @@
<body>
@include('admin.layout.header')
@yield('page_content')
<br />
@include('admin.layout.footer')
</body>

View File

@ -0,0 +1,21 @@
<footer class="ui fixed">
<div class="dark-grey">
<div class="ui inverted container main">
<div class="ui stackable grid">
<div class="three columns row">
<div class="middle aligned column">
@include('layout.footer.contacto')
</div>
<div class="middle aligned column">
@include('layout.footer.ubicacion')
</div>
<div class="middle aligned column">
@include('layout.footer.redes')
</div>
</div>
</div>
</div>
</div>
@include('admin.layout.footer.menu')
</footer>
@include('admin.layout.scripts')

View File

@ -0,0 +1,15 @@
<div style="text-align: center;">
<a href="{{$urls->base}}/#contacto">
<i class="big icon icon-contacto"></i>
<p>
<strong>
CONTACTO
</strong>
</p>
</a>
<p>
<a href="tel:56 9 9334 3645">+56 9 9334 3645</a>
<br />
<a href="mailto:mauriciogonzalez@totalsport.cl">mauriciogonzalez@totalsport.cl</a>
</p>
</div>

View File

@ -0,0 +1,24 @@
<div class="grey">
<nav class="ui container attached text stackable menu">
<a class="item" href="{{$urls->base}}/#servicios">
Servicios
</a>
<a class="item" href="{{$urls->base}}/#nosotros">
Nosotros
</a>
<a class="item" href="{{$urls->base}}/#clientes">
Clientes
</a>
<a class="item" href="{{$urls->base}}/#eventos">
Eventos
</a>
<a class="item" href="{{$urls->base}}/#contacto">
Contacto
</a>
<div class="right menu">
<div class="item">
Copyright Todos los derechos reservados a ProVM&copy;
</div>
</div>
</nav>
</div>

View File

@ -0,0 +1,17 @@
<div class="ui five columns center aligned grid">
<div class="column">
<i class="youtube big icon"></i>
</div>
<div class="column">
<i class="instagram big icon"></i>
</div>
<div class="column">
<i class="facebook big icon"></i>
</div>
<div class="column">
<i class="linkedin big icon"></i>
</div>
<div class="column">
<i class="twitter big icon"></i>
</div>
</div>

View File

@ -0,0 +1,17 @@
<div style="text-align: center;">
<a href="{{$urls->base}}/#contacto">
<i class="big icon icon-ubicacion"></i>
<p>
<strong>
UBICACI&Oacute;N
</strong>
</p>
</a>
<a href="{{$urls->base}}/#contacto">
<p>
Av. Nueva Providencia 1945, Of. 919,
<br />
Las Condes.
</p>
</a>
</div>

View File

@ -0,0 +1,8 @@
<head>
<meta charset="utf-8" />
<title>
Total Sport
@yield('page_title')
</title>
@include('admin.layout.styles')
</head>

View File

@ -0,0 +1,3 @@
<div class="ui container">
@include('admin.layout.menu')
</div>

View File

@ -0,0 +1,13 @@
<nav class="ui massive stackable center aligned text three item grey menu">
<div class="left three item menu">
<a class="item" href="{{$urls->admin}}/eventos">Eventos</a>
</div>
<a class="item" href="{{$urls->admin}}">
<div class="ui header" id="page_logo">
Total<span class="brand">Sport</span>
</div>
</a>
<div class="right two item menu">
<a class="item" href="{{$urls->base}}">Salir</a>
</div>
</nav>

View File

@ -0,0 +1,7 @@
@if (isset($assets->scripts))
@foreach ($assets->scripts as $script)
<script type="text/javascript" src="{{$script}}"></script>
@endforeach
@endif
@stack('scripts')

View File

@ -0,0 +1,14 @@
@if (isset($assets->styles))
@foreach ($assets->styles as $style)
<link rel="stylesheet" type="text/css" href="{{$style}}" />
@endforeach
@endif
@if (isset($assets->fonts))
@foreach ($assets->fonts as $type => $fs)
@foreach ($fs as $font)
<link type="{{$type}}" href="{{$font}}" />
@endforeach
@endforeach
@endif
@stack('styles')

View File

@ -5,8 +5,12 @@
<div class="ui container">
<div class="ui two columns stackable grid">
<div class="column">
<div class="ui image">
<img src="{{$imagenes[0]}}" id="seleccionada" />
<div class="ui image" id="seleccionada">
@if ($imagenes !== false)
{!!array_values($imagenes)[0]->media->html!!}
@else
Imagen no encontrada.
@endif
</div>
</div>
<div class="column">
@ -25,13 +29,19 @@
{{$evento->descripcion}}
</p>
<div class="ui four column grid">
@foreach ($imagenes as $imagen)
<div class="column">
<div class="ui image" class="imagen">
<img src="{{$imagen}}" class="imagen" />
@if ($imagenes !== false)
@foreach (array_values($imagenes) as $i => $imagen)
<div class="column">
<div class="ui image imagen" data-id="{{$i}}">
{!!$imagen->thumb->html!!}
</div>
</div>
@endforeach
@else
<div class="column">
No hay imagenes.
</div>
@endforeach
@endif
</div>
</div>
</div>
@ -45,10 +55,16 @@
@push('scripts')
<script type="text/javascript">
var media = [
@foreach ($imagenes as $media)
'{!!$media->media->html!!}',
@endforeach
]
$(document).ready(function() {
$('.imagen').css('cursor', 'pointer').click(function() {
var src = $(this).attr('src')
$('#seleccionada').attr('src', src)
var id = $(this).attr('data-id')
var src = media[id]
$('#seleccionada').html(src)
})
})
</script>

View File

@ -19,7 +19,7 @@
<div class="ui basic segment">
<a href="{{$urls->base}}/evento/{{$i}}">
<div class="ui image">
<img src="{{$evento->imagen}}" />
{!!$evento->imagen!!}
</div>
<div class="ui center aligned header">
{{$evento->titulo}}
@ -36,56 +36,61 @@
@push('scripts')
<script type="text/javascript">
var eventos = [
@foreach ($eventos as $evento)
{
titulo: '{{$evento->titulo}}',
image: '{{$evento->imagen}}',
empresa: '{{$evento->empresa}}',
servicio: '{{$evento->servicio}}'
},
@endforeach
];
function changeEventos(filter) {
var grid = $('#eventos_cards')
grid.html('')
$.each(eventos, function(i, el) {
if (filter != 'none' && el.servicio != filter) {
return
}
grid.append(
$('<div></div>').attr('class', 'eight wide tablet four wide computer column').append(
$('<div></div>').attr('class', 'ui basic segment').append(
$('<a></a>').attr('href', '{{$urls->base}}/evento/' + i).append(
$('<div></div>').attr('class', 'ui image').append(
$('<img />').attr('src', el.image)
var eventos = {
eventos: [
@foreach ($eventos as $evento)
{
titulo: '{{$evento->titulo}}',
image: '{!!$evento->imagen!!}',
empresa: '{{$evento->empresa}}',
servicio: '{{$evento->servicio}}'
},
@endforeach
],
current_tab: 'none',
changeEventos: (filter) => {
var grid = $('#eventos_cards')
grid.html('')
$.each(eventos.eventos, function(i, el) {
if (filter != 'none' && el.servicio != filter) {
return
}
grid.append(
$('<div></div>').attr('class', 'eight wide tablet four wide computer column').append(
$('<div></div>').attr('class', 'ui basic segment').append(
$('<a></a>').attr('href', '{{$urls->base}}/evento/' + i).append(
$('<div></div>').attr('class', 'ui image').append(
$('<img />').attr('src', el.image)
)
).append(
$('<div></div>').attr('class', 'ui center aligned header').append(el.titulo).append(
$('<br />')
).append(el.empresa)
)
).append(
$('<div></div>').attr('class', 'ui center aligned header').append(el.titulo).append(
$('<br />')
).append(el.empresa)
)
)
)
)
})
}
var current_tab = 'none'
function changeTab(filter) {
$('.servicio.active').removeClass('active')
$(".servicio[data-filter='" + filter + "']").addClass('active')
current_tab = filter
})
},
changeTab: (filter) => {
$('.servicio.active').removeClass('active')
$(".servicio[data-filter='" + filter + "']").addClass('active')
eventos.current_tab = filter
},
setup: () => {
$('.servicio').click(function(e) {
e.preventDefault()
var filter = $(this).attr('data-filter')
if (filter == eventos.current_tab) {
return
}
eventos.changeTab(filter)
eventos.changeEventos(filter)
})
}
}
$(document).ready(function() {
$('.servicio').click(function(e) {
e.preventDefault()
var filter = $(this).attr('data-filter')
if (filter == current_tab) {
return
}
changeTab(filter)
changeEventos(filter)
})
eventos.setup()
})
</script>
@endpush