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}', '{urls.base}',
'eventos' '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' 'map' => 'https://maps.google.com/maps?hl=es&q=Avenida%20Nueva%20Providencia%201945,%20Providencia&ie=UTF8&z=16&iwloc=B&output=embed'
], ],
'assets' => [ 'assets' => [

View File

@ -15,5 +15,13 @@ return [
'assets' => (object) $c->get('assets') '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 Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View; use Slim\Views\Blade as View;
use ProVM\TotalSport\Common\Service\DataHandler; use ProVM\TotalSport\Common\Service\DataHandler;
use ProVM\TotalSport\Common\Service\ImageLoader; use ProVM\TotalSport\Common\Service\MediaLoader;
class Eventos { 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'); $eventos = $handler->load('eventos');
$e = $eventos[$evento]; $e = $eventos[$evento];
$imagenes = $loader->load($e); $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 Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View; use Slim\Views\Blade as View;
use ProVM\TotalSport\Common\Service\DataHandler; use ProVM\TotalSport\Common\Service\DataHandler;
use ProVM\TotalSport\Common\Service\ImageLoader; use ProVM\TotalSport\Common\Service\MediaLoader;
class Home { 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) [ $banner = (object) [
'title' => 'BUSCAMOS LA MEJOR EXPERIENCA', 'title' => 'BUSCAMOS LA MEJOR EXPERIENCA',
'contenido' => 'Eventos hechos a tu medida' 'contenido' => 'Eventos hechos a tu medida'
@ -28,10 +28,10 @@ class Home {
$eventos = $handler->load('eventos'); $eventos = $handler->load('eventos');
foreach ($eventos as &$evento) { foreach ($eventos as &$evento) {
if (!isset($evento->imagen)) { if (!isset($evento->imagen)) {
$evento->imagen = '#'; $evento->imagen = '<img src="#" alt="Imagen no encontrada" title="Imagen no encontrada" />';
$imagenes = $loader->load($evento); $imagenes = $loader->load($evento);
if ($imagenes !== false) { if ($imagenes !== false) {
$evento->imagen = $imagenes[0]; $evento->imagen = array_values($imagenes)[0]->thumb->html;
} }
} }
if (!isset($evento->servicio)) { if (!isset($evento->servicio)) {

View File

@ -15,4 +15,11 @@ class DataHandler {
]); ]);
return json_decode(json_encode(Spyc::YAMLLoad($filename))); 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->folder = $images_folder;
$this->assets_folder = $images_assets_folder; $this->assets_folder = $images_assets_folder;
} }
public function load($event) { protected function getFolder($event) {
$folder = implode(DIRECTORY_SEPARATOR, [ return implode(DIRECTORY_SEPARATOR, [
$this->folder, $this->folder,
'eventos', 'eventos',
s($event->servicio)->removeLeft('Eventos '), s($event->servicio)->removeLeft('Eventos '),
@ -20,6 +20,9 @@ class ImageLoader {
$event->empresa $event->empresa
]), ', ') ]), ', ')
]); ]);
}
public function load($event) {
$folder = $this->getFolder($event);
if (!file_exists($folder)) { if (!file_exists($folder)) {
return false; return false;
} }
@ -29,6 +32,18 @@ class ImageLoader {
if ($file->isDir()) { if ($file->isDir()) {
continue; 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('/', [ $images []= implode('/', [
$this->assets_folder, $this->assets_folder,
'eventos', 'eventos',
@ -42,4 +57,28 @@ class ImageLoader {
} }
return $images; 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", "rubellum/slim-blade-view": "^0.1.1",
"mustangostang/spyc": "^0.6.3", "mustangostang/spyc": "^0.6.3",
"voku/stringy": "^6.2", "voku/stringy": "^6.2",
"vlucas/phpdotenv": "^4.1" "vlucas/phpdotenv": "^4.1",
"php-ffmpeg/php-ffmpeg": "^0.16.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^8.5", "phpunit/phpunit": "^8.5",

View File

@ -11,6 +11,7 @@
} }
#banner .header { #banner .header {
font-family: inherit; font-family: inherit;
line-height: 2rem;
} }
#servicios { #servicios {
@ -87,6 +88,19 @@
background-color: white; background-color: white;
padding: 0; 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 { #contacto {
padding-top: 4rem; 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 empresa: Consorcio
servicio: Eventos Calidad de Vida 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" descripcion: >
- titulo: Día del niño 2017 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 empresa: Fresenius Kabi
servicio: Eventos Calidad de Vida 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" descripcion: >
- titulo: Fiestras patrias 2019 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 empresa: Consorcio
servicio: Eventos Calidad de Vida 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" descripcion: >
- titulo: Olimpiadas del Seguro 2019 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 empresa: Intervención Chilena Consolidada
servicio: Eventos Calidad de Vida 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" descripcion: >
- titulo: Pausas Activas 2018 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 empresa: Dimeiggs
servicio: Eventos Calidad de Vida 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" descripcion: >
- titulo: Campeonato baby Futbol 2018 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 empresa: AZA
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Campeonato Futbol Varones 2019 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 empresa: Chilena Consolidada
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Campeonato Voleibol 2019 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 empresa: Dimerc
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Campeonato Futbolito 2017 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 empresa: Dimerc
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Final Nacional Campeonato Futbolito 2012 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 empresa: Gildemeister
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Futbol Varones senior 2019 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 empresa: Olimpiadas del Seguro
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Liga Consumidores 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: "" empresa: ""
servicio: Eventos Deportivos 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" descripcion: >
- titulo: Liga Futbar 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: "" empresa: ""
servicio: Eventos Deportivos 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" descripcion: >
- titulo: 2da Corrida Familiar Inclusiva 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 empresa: DIMERC
servicio: Eventos Recreativos 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: >
- titulo: Dia de la Familia 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 empresa: BUPA
servicio: Eventos Recreativos 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: >
- titulo: Fiestas Patrias 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 empresa: CONSORCIO
servicio: Eventos Recreativos 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: >
- titulo: Pausas Activas 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 empresa: DIMEIGGS
servicio: Eventos Recreativos 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 container">
<div class="ui two columns stackable grid"> <div class="ui two columns stackable grid">
<div class="column"> <div class="column">
<div class="ui image"> <div class="ui image" id="seleccionada">
<img src="{{$imagenes[0]}}" id="seleccionada" /> @if ($imagenes !== false)
{!!array_values($imagenes)[0]->media->html!!}
@else
Imagen no encontrada.
@endif
</div> </div>
</div> </div>
<div class="column"> <div class="column">
@ -25,13 +29,19 @@
{{$evento->descripcion}} {{$evento->descripcion}}
</p> </p>
<div class="ui four column grid"> <div class="ui four column grid">
@foreach ($imagenes as $imagen) @if ($imagenes !== false)
<div class="column"> @foreach (array_values($imagenes) as $i => $imagen)
<div class="ui image" class="imagen"> <div class="column">
<img src="{{$imagen}}" class="imagen" /> <div class="ui image imagen" data-id="{{$i}}">
{!!$imagen->thumb->html!!}
</div>
</div> </div>
@endforeach
@else
<div class="column">
No hay imagenes.
</div> </div>
@endforeach @endif
</div> </div>
</div> </div>
</div> </div>
@ -45,10 +55,16 @@
@push('scripts') @push('scripts')
<script type="text/javascript"> <script type="text/javascript">
var media = [
@foreach ($imagenes as $media)
'{!!$media->media->html!!}',
@endforeach
]
$(document).ready(function() { $(document).ready(function() {
$('.imagen').css('cursor', 'pointer').click(function() { $('.imagen').css('cursor', 'pointer').click(function() {
var src = $(this).attr('src') var id = $(this).attr('data-id')
$('#seleccionada').attr('src', src) var src = media[id]
$('#seleccionada').html(src)
}) })
}) })
</script> </script>

View File

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