OneConversorTemplate/OnlyOneAccessTemplate/Views/Shared/_ConverterWidget.cshtml
2025-05-31 21:48:14 -03:00

271 lines
12 KiB
Plaintext

@* Views/Shared/_ConverterWidget.cshtml *@
<!-- Widget Base do Conversor - Personalizável para cada tipo -->
<div class="converter-widget">
<form id="converterForm" enctype="multipart/form-data">
<div class="row">
<!-- Input Area -->
<div class="col-md-6 mb-4">
<div class="input-section">
<label class="form-label fw-bold">@ViewBag.InputLabel</label>
<!-- File Upload (se for conversão de arquivo) -->
@if (ViewBag.ConverterType == "file")
{
<div class="upload-area border-2 border-dashed rounded-3 p-4 text-center">
<input type="file" id="fileInput" name="file" class="d-none" accept="@ViewBag.AcceptedFileTypes">
<div class="upload-placeholder">
<i class="fas fa-cloud-upload-alt fa-3x text-muted mb-3"></i>
<p class="mb-2">
<button type="button" class="btn btn-outline-primary" onclick="document.getElementById('fileInput').click()">
@ViewBag.SelectFileText
</button>
</p>
<small class="text-muted">@ViewBag.FileHelpText</small>
<div class="file-info mt-2" style="display: none;">
<small class="text-success">
<i class="fas fa-check-circle me-1"></i>
<span id="fileName"></span>
</small>
</div>
</div>
</div>
}
<!-- Text Input (se for conversão de texto) -->
@if (ViewBag.ConverterType == "text")
{
<textarea id="inputText" name="inputText" class="form-control" rows="10"
placeholder="@ViewBag.InputPlaceholder">@ViewBag.SampleInput</textarea>
<div class="form-text">@ViewBag.InputHelpText</div>
}
<!-- URL Input (se for conversão de URL) -->
@if (ViewBag.ConverterType == "url")
{
<input type="url" id="inputUrl" name="inputUrl" class="form-control"
placeholder="@ViewBag.InputPlaceholder" value="@ViewBag.SampleInput">
<div class="form-text">@ViewBag.InputHelpText</div>
}
</div>
<!-- Configurações Adicionais -->
@if (ViewBag.HasAdvancedOptions == true)
{
<div class="advanced-options mt-3">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="collapse" data-bs-target="#advancedSettings">
<i class="fas fa-cog me-1"></i> @(ViewBag.AdvancedOptionsText ?? "Opções Avançadas")
</button>
<div class="collapse mt-3" id="advancedSettings">
@{
try
{
await Html.RenderPartialAsync("_AdvancedOptions");
}
catch
{
<!-- Fallback se a partial não existir -->
<div class="alert alert-info">
<small>Opções avançadas não disponíveis para este conversor.</small>
</div>
}
}
</div>
</div>
}
</div>
<!-- Output Area -->
<div class="col-md-6 mb-4">
<div class="output-section">
<label class="form-label fw-bold">@ViewBag.OutputLabel</label>
<!-- Loading State -->
<div id="loadingState" class="text-center p-5" style="display: none;">
<div class="spinner-border text-primary mb-3" role="status">
<span class="visually-hidden">@ViewBag.LoadingText</span>
</div>
<p class="text-muted">@ViewBag.ProcessingText</p>
</div>
<!-- Output Display -->
<div id="outputArea">
@if (ViewBag.OutputType == "text")
{
<textarea id="outputText" class="form-control" rows="10" readonly
placeholder="@ViewBag.OutputPlaceholder"></textarea>
}
else if (ViewBag.OutputType == "download")
{
<div class="download-area border rounded-3 p-4 text-center" style="display: none;">
<i class="fas fa-download fa-2x text-success mb-3"></i>
<p class="mb-3">@ViewBag.DownloadReadyText</p>
<button type="button" id="downloadBtn" class="btn btn-success">
<i class="fas fa-download me-1"></i> @ViewBag.DownloadButtonText
</button>
</div>
}
else if (ViewBag.OutputType == "preview")
{
<div id="previewArea" class="preview-container border rounded-3 p-3" style="min-height: 200px;">
<div class="text-center text-muted p-4">
<i class="fas fa-eye fa-2x mb-2"></i>
<p>@ViewBag.PreviewPlaceholder</p>
</div>
</div>
}
</div>
<!-- Error Display -->
<div id="errorArea" class="alert alert-danger mt-3" style="display: none;">
<i class="fas fa-exclamation-triangle me-2"></i>
<span id="errorMessage"></span>
</div>
<!-- Success Actions -->
<div id="successActions" class="mt-3" style="display: none;">
<div class="d-flex gap-2 flex-wrap">
<button type="button" id="copyBtn" class="btn btn-sm btn-outline-primary">
<i class="fas fa-copy me-1"></i> @ViewBag.CopyButtonText
</button>
<button type="button" id="clearBtn" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-trash me-1"></i> @ViewBag.ClearButtonText
</button>
@if (ViewBag.AllowShare == true)
{
<button type="button" id="shareBtn" class="btn btn-sm btn-outline-info">
<i class="fas fa-share me-1"></i> @ViewBag.ShareButtonText
</button>
}
</div>
</div>
</div>
</div>
</div>
<!-- Convert Button -->
<div class="text-center mt-4">
<button type="submit" id="convertBtn" class="btn btn-primary btn-lg px-5">
<i class="fas fa-sync-alt me-2"></i>
@ViewBag.ConvertButtonText
</button>
</div>
</form>
<script src="~/js/converters/sentence-converter.js?v=1.0"></script>
</div>
<!-- JavaScript Base do Conversor -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('converterForm');
const convertBtn = document.getElementById('convertBtn');
const loadingState = document.getElementById('loadingState');
const outputArea = document.getElementById('outputArea');
const errorArea = document.getElementById('errorArea');
const successActions = document.getElementById('successActions');
// File input handler
const fileInput = document.getElementById('fileInput');
if (fileInput) {
fileInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
document.getElementById('fileName').textContent = file.name;
document.querySelector('.file-info').style.display = 'block';
}
});
}
// Form submission
form.addEventListener('submit', async function(e) {
e.preventDefault();
// Reset states
hideElement(errorArea);
hideElement(successActions);
showElement(loadingState);
hideElement(outputArea.querySelector('.download-area, #previewArea'));
// Disable button
convertBtn.disabled = true;
try {
const formData = new FormData(form);
// Call converter-specific function
if (typeof performConversion === 'function') {
await performConversion(formData);
} else {
throw new Error('Converter function not implemented');
}
} catch (error) {
showError(error.message || '@ViewBag.DefaultErrorMessage');
} finally {
hideElement(loadingState);
convertBtn.disabled = false;
}
});
// Utility functions
function showElement(element) {
if (element) element.style.display = 'block';
}
function hideElement(element) {
if (element) element.style.display = 'none';
}
function showError(message) {
document.getElementById('errorMessage').textContent = message;
showElement(errorArea);
}
// Copy button functionality
const copyBtn = document.getElementById('copyBtn');
if (copyBtn) {
copyBtn.addEventListener('click', function() {
const outputText = document.getElementById('outputText');
if (outputText) {
outputText.select();
document.execCommand('copy');
// Visual feedback
const originalText = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fas fa-check me-1"></i> @ViewBag.CopiedText';
setTimeout(() => {
copyBtn.innerHTML = originalText;
}, 2000);
}
});
}
// Clear button functionality
const clearBtn = document.getElementById('clearBtn');
if (clearBtn) {
clearBtn.addEventListener('click', function() {
form.reset();
hideElement(successActions);
hideElement(errorArea);
// Clear outputs
const outputText = document.getElementById('outputText');
if (outputText) outputText.value = '';
const previewArea = document.getElementById('previewArea');
if (previewArea) {
previewArea.innerHTML = `
<div class="text-center text-muted p-4">
<i class="fas fa-eye fa-2x mb-2"></i>
<p>@ViewBag.PreviewPlaceholder</p>
</div>
`;
}
// Hide file info
const fileInfo = document.querySelector('.file-info');
if (fileInfo) fileInfo.style.display = 'none';
});
}
});
</script>