generated from ricardo/MVCLogin
339 lines
15 KiB
Plaintext
339 lines
15 KiB
Plaintext
@model List<Postall.Models.ChannelVideosViewModel>
|
|
@{
|
|
ViewData["Title"] = "Gerenciador de Vídeos";
|
|
}
|
|
|
|
<style>
|
|
/* Estilos para cards de vídeo na página principal */
|
|
.card-title-truncate {
|
|
width: 100%;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.card-desc-truncate {
|
|
height: 60px;
|
|
overflow: hidden;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* Garantir que o thumbnail tenha tamanho consistente */
|
|
.video-thumbnail {
|
|
width: 100%;
|
|
height: 100px;
|
|
object-fit: cover;
|
|
}
|
|
|
|
/* Garantir altura consistente para os cards */
|
|
.video-card {
|
|
height: 100%;
|
|
}
|
|
|
|
/* Estilo para o botão ler mais */
|
|
.read-more-btn {
|
|
font-size: 0.8rem;
|
|
color: #007bff;
|
|
cursor: pointer;
|
|
display: inline-block;
|
|
margin-top: 3px;
|
|
}
|
|
|
|
.read-more-btn:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Estilo para o conteúdo expandido em largura total */
|
|
.description-expanded {
|
|
max-height: 150px;
|
|
overflow-y: auto;
|
|
padding: 10px;
|
|
background-color: #f8f9fa;
|
|
border-radius: 0 0 4px 4px;
|
|
border-top: 1px solid #dee2e6;
|
|
margin: 10px 5px 5px 5px; /* Margem negativa para alinhar com os limites do card */
|
|
display: none;
|
|
position: relative;
|
|
z-index: 5;
|
|
}
|
|
|
|
/* Ajuste na posição do botão Fechar */
|
|
.card-body {
|
|
padding-bottom: 5px;
|
|
}
|
|
|
|
/* Ajuste para cards com descrição expandida */
|
|
.card-with-expanded-desc {
|
|
overflow: visible;
|
|
}
|
|
</style>
|
|
|
|
<div class="container mt-4">
|
|
<div class="row mb-4">
|
|
<div class="col-md-8">
|
|
<h2>Meus Vídeos</h2>
|
|
<p class="text-muted">Gerencie seus vídeos do YouTube por canal</p>
|
|
</div>
|
|
<div class="col-md-4 text-right">
|
|
<a href="@Url.Action("Index", "Channels")" class="btn btn-outline-primary mr-2">
|
|
<i class="bi bi-collection"></i> Gerenciar Canais
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
@if (TempData["Message"] != null)
|
|
{
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
@TempData["Message"]
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (TempData["Error"] != null)
|
|
{
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
@TempData["Error"]
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
}
|
|
|
|
@if (Model == null || !Model.Any())
|
|
{
|
|
<div class="alert alert-info">
|
|
<i class="bi bi-info-circle"></i> Você não possui nenhum canal com vídeos.
|
|
<a href="@Url.Action("Index", "Channels")">Clique aqui</a> para adicionar um canal primeiro.
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="accordion" id="channelsAccordion">
|
|
@foreach (var channelVideos in Model)
|
|
{
|
|
<div class="card mb-4">
|
|
<div class="card-header" id="heading-@channelVideos.Channel.Id">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div class="d-flex align-items-center">
|
|
<img src="@channelVideos.Channel.ThumbnailUrl" alt="@channelVideos.Channel.Title" class="img-thumbnail mr-3" style="width: 50px; height: 50px;">
|
|
<h5 class="mb-0">@channelVideos.Channel.Title</h5>
|
|
</div>
|
|
<div>
|
|
<button class="btn btn-link" type="button" data-toggle="collapse"
|
|
data-target="#collapse-@channelVideos.Channel.Id" aria-expanded="true"
|
|
aria-controls="collapse-@channelVideos.Channel.Id">
|
|
<i class="bi bi-chevron-down"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-primary btn-sm"
|
|
onclick="loadChannelVideos('@channelVideos.Channel.ChannelId')"
|
|
data-toggle="modal" data-target="#addVideosModal">
|
|
<i class="bi bi-plus-circle"></i> Adicionar Vídeos
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="collapse-@channelVideos.Channel.Id" class="collapse show"
|
|
aria-labelledby="heading-@channelVideos.Channel.Id" data-parent="#channelsAccordion">
|
|
<div class="card-body">
|
|
@if (channelVideos.Videos != null && channelVideos.Videos.Any())
|
|
{
|
|
<div class="row">
|
|
@foreach (var video in channelVideos.Videos)
|
|
{
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card video-card">
|
|
<div class="card-header bg-transparent">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h5 class="card-title-truncate">@video.Title</h5>
|
|
<button class="btn btn-sm btn-link" type="button" data-toggle="collapse"
|
|
data-target="#videoCollapse-@video.Id" aria-expanded="true">
|
|
<i class="bi bi-chevron-down"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-5">
|
|
<img src="@video.ThumbnailUrl" alt="@video.Title" class="img-fluid rounded video-thumbnail">
|
|
</div>
|
|
<div class="col-md-7">
|
|
<div>
|
|
<p class="card-desc-truncate mb-0">@video.Description</p>
|
|
<span class="read-more-btn" data-target="main-desc-@video.Id">Ler mais</span>
|
|
</div>
|
|
<p class="text-muted small mt-2">Publicado em: @video.PublishedAt.ToString("dd/MM/yyyy")</p>
|
|
</div>
|
|
</div>
|
|
<div id="main-desc-@video.Id" class="description-expanded">
|
|
<p><b>@video.Title</b></p>
|
|
@video.Description
|
|
</div>
|
|
</div>
|
|
<div class="collapse show" id="videoCollapse-@video.Id">
|
|
<div class="card-footer bg-white">
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
<a href="@video.VideoUrl" target="_blank" class="btn btn-sm btn-outline-primary">
|
|
<i class="bi bi-youtube"></i> Ver no YouTube
|
|
</a>
|
|
</div>
|
|
<div>
|
|
<button class="btn btn-sm btn-outline-danger"
|
|
onclick="removeVideo('@video.Id', '@channelVideos.Channel.Id')">
|
|
<i class="bi bi-trash"></i> Remover
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="alert alert-info">
|
|
<i class="bi bi-info-circle"></i> Este canal não possui vídeos adicionados.
|
|
Clique em "Adicionar Vídeos" para começar.
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<!-- Modal para adicionar vídeos -->
|
|
<div class="modal fade" id="addVideosModal" tabindex="-1" role="dialog" aria-labelledby="addVideosModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="addVideosModalLabel">Adicionar Vídeos do Canal</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="channelVideosContainer">
|
|
<div class="text-center">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="sr-only">Carregando...</span>
|
|
</div>
|
|
<p class="mt-2">Carregando vídeos...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
|
|
<button type="button" class="btn btn-primary" id="btnAddSelectedVideos">Adicionar Selecionados</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Formulário oculto para remover vídeos -->
|
|
<form id="removeVideoForm" method="post" action="@Url.Action("Remove", "Videos")">
|
|
<input type="hidden" id="videoIdToRemove" name="id">
|
|
<input type="hidden" id="channelIdForRemove" name="channelId">
|
|
</form>
|
|
|
|
@section Scripts {
|
|
<script type="text/javascript">
|
|
// Variável para armazenar o ID do canal atual
|
|
let currentChannelId = '';
|
|
|
|
// Função para carregar os vídeos do canal
|
|
function loadChannelVideos(channelId) {
|
|
currentChannelId = channelId;
|
|
|
|
$.ajax({
|
|
url: '@Url.Action("GetChannelVideos", "Videos")',
|
|
type: 'GET',
|
|
data: { channelId: channelId },
|
|
success: function (result) {
|
|
$('#channelVideosContainer').html(result);
|
|
|
|
// Inicializa os botões "Ler mais" após carregar o conteúdo
|
|
setTimeout(function() {
|
|
initReadMoreButtons();
|
|
}, 200);
|
|
},
|
|
error: function (error) {
|
|
$('#channelVideosContainer').html('<div class="alert alert-danger">Erro ao carregar vídeos. Tente novamente.</div>');
|
|
console.error('Erro:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Função para remover um vídeo
|
|
function removeVideo(videoId, channelId) {
|
|
if (confirm('Tem certeza que deseja remover este vídeo?')) {
|
|
$('#videoIdToRemove').val(videoId);
|
|
$('#channelIdForRemove').val(channelId);
|
|
$('#removeVideoForm').submit();
|
|
}
|
|
}
|
|
|
|
// Função para inicializar os botões "Ler mais"
|
|
function initReadMoreButtons() {
|
|
$('.read-more-btn').off('click').on('click', function() {
|
|
var targetId = $(this).data('target');
|
|
$('#' + targetId).slideToggle(200);
|
|
|
|
// Alternar texto do botão
|
|
var btnText = $(this).text() === 'Ler mais' ? 'Fechar' : 'Ler mais';
|
|
$(this).text(btnText);
|
|
});
|
|
}
|
|
|
|
$(function () {
|
|
// Inicializar botões "Ler mais" na carga da página
|
|
initReadMoreButtons();
|
|
|
|
// Reinicializar botões quando um accordion é aberto
|
|
$('.collapse').on('shown.bs.collapse', function () {
|
|
initReadMoreButtons();
|
|
});
|
|
|
|
// Manipula o clique no botão de adicionar vídeos selecionados
|
|
$('#btnAddSelectedVideos').click(function () {
|
|
var selectedVideos = [];
|
|
|
|
// Coleta todos os checkboxes selecionados
|
|
$('.video-checkbox:checked').each(function () {
|
|
selectedVideos.push($(this).val());
|
|
});
|
|
|
|
if (selectedVideos.length === 0) {
|
|
alert('Selecione pelo menos um vídeo para adicionar.');
|
|
return;
|
|
}
|
|
|
|
// Cria um formulário para enviar os IDs dos vídeos selecionados
|
|
var form = $('<form action="@Url.Action("AddVideos", "Videos")" method="post"></form>');
|
|
|
|
// Adiciona o ID do canal
|
|
form.append('<input type="hidden" name="channelId" value="' + currentChannelId + '">');
|
|
|
|
// Adiciona inputs ocultos para cada vídeo selecionado
|
|
selectedVideos.forEach(function (videoId) {
|
|
form.append('<input type="hidden" name="selectedVideos" value="' + videoId + '">');
|
|
});
|
|
|
|
// Adiciona o formulário ao corpo do documento e o submete
|
|
$('body').append(form);
|
|
form.submit();
|
|
});
|
|
});
|
|
</script>
|
|
} |