first commit
This commit is contained in:
commit
462ad481f1
9
.claude/settings.local.json
Normal file
9
.claude/settings.local.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(dotnet build)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
382
.gitignore
vendored
Normal file
382
.gitignore
vendored
Normal file
@ -0,0 +1,382 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/*.HxS
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these files may be disclosed. Comment the next line if you want to checkin
|
||||
# your web deploy settings, but sensitive information contained in these files may
|
||||
# be disclosed. Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.azurePubxml
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment the next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
CConvertLog*.txt
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# Custom
|
||||
appsettings.Local.json
|
||||
appsettings.Production.json
|
||||
*.Development.json
|
||||
logs/
|
||||
uploads/
|
||||
temp/
|
||||
*.env
|
||||
.env.local
|
||||
.env.production
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Database
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# Certificates
|
||||
*.pfx
|
||||
*.crt
|
||||
*.key
|
||||
51
Areas/ImageConverters/Controllers/JpgToWebpController.cs
Normal file
51
Areas/ImageConverters/Controllers/JpgToWebpController.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Webp;
|
||||
|
||||
namespace Convert_It_Online.Areas.ImageConverters.Controllers
|
||||
{
|
||||
[Area("ImageConverters")]
|
||||
public class JpgToWebpController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Convert(IFormFile jpgFile)
|
||||
{
|
||||
if (jpgFile == null || jpgFile.Length == 0)
|
||||
{
|
||||
ModelState.AddModelError("jpgFile", "Por favor, selecione um arquivo.");
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
// Validação simples do tipo de arquivo
|
||||
if (jpgFile.ContentType != "image/jpeg")
|
||||
{
|
||||
ModelState.AddModelError("jpgFile", "Arquivo inválido. Por favor, envie um arquivo JPG.");
|
||||
return View("Index");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var imageStream = jpgFile.OpenReadStream();
|
||||
using var image = await Image.LoadAsync(imageStream);
|
||||
|
||||
using var memoryStream = new MemoryStream();
|
||||
await image.SaveAsync(memoryStream, new WebpEncoder());
|
||||
memoryStream.Position = 0;
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(jpgFile.FileName) + ".webp";
|
||||
return File(memoryStream.ToArray(), "image/webp", fileName);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Log do erro (não implementado aqui)
|
||||
ModelState.AddModelError("jpgFile", "Ocorreu um erro ao processar a imagem.");
|
||||
return View("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Areas/ImageConverters/Views/JpgToWebp/Index.cshtml
Normal file
22
Areas/ImageConverters/Views/JpgToWebp/Index.cshtml
Normal file
@ -0,0 +1,22 @@
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
|
||||
@{
|
||||
ViewData["Title"] = Localizer["PageTitle"];
|
||||
}
|
||||
|
||||
<h1>@Localizer["PageTitle"]</h1>
|
||||
<p>@Localizer["PageDescription"]</p>
|
||||
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<form asp-action="Convert" method="post" enctype="multipart/form-data">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger mb-3"></div>
|
||||
<div class="mb-3">
|
||||
<label for="jpgFile" class="form-label">@Localizer["FileInputLabel"]</label>
|
||||
<input class="form-control" type="file" id="jpgFile" name="jpgFile" accept="image/jpeg" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">@Localizer["ConvertButton"]</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-CL.resx
Normal file
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-CL.resx
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertir JPG a WebP</value>
|
||||
</data>
|
||||
<data name="PageDescription" xml:space="preserve">
|
||||
<value>Sube una imagen JPG para convertirla al formato WebP.</value>
|
||||
</data>
|
||||
<data name="FileInputLabel" xml:space="preserve">
|
||||
<value>Selecciona el archivo:</value>
|
||||
</data>
|
||||
<data name="ConvertButton" xml:space="preserve">
|
||||
<value>Convertir Ahora</value>
|
||||
</data>
|
||||
</root>
|
||||
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-MX.resx
Normal file
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-MX.resx
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertir JPG a WebP</value>
|
||||
</data>
|
||||
<data name="PageDescription" xml:space="preserve">
|
||||
<value>Suba una imagen JPG para convertirla al formato WebP.</value>
|
||||
</data>
|
||||
<data name="FileInputLabel" xml:space="preserve">
|
||||
<value>Seleccione el archivo:</value>
|
||||
</data>
|
||||
<data name="ConvertButton" xml:space="preserve">
|
||||
<value>Convertir Ahora</value>
|
||||
</data>
|
||||
</root>
|
||||
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-PY.resx
Normal file
15
Areas/ImageConverters/Views/JpgToWebp/Index.es-PY.resx
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertir JPG a WebP</value>
|
||||
</data>
|
||||
<data name="PageDescription" xml:space="preserve">
|
||||
<value>Sube una imagen JPG para convertirla al formato WebP.</value>
|
||||
</data>
|
||||
<data name="FileInputLabel" xml:space="preserve">
|
||||
<value>Selecciona el archivo:</value>
|
||||
</data>
|
||||
<data name="ConvertButton" xml:space="preserve">
|
||||
<value>Convertir Ahora</value>
|
||||
</data>
|
||||
</root>
|
||||
15
Areas/ImageConverters/Views/JpgToWebp/Index.pt-BR.resx
Normal file
15
Areas/ImageConverters/Views/JpgToWebp/Index.pt-BR.resx
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Converter JPG para WebP</value>
|
||||
</data>
|
||||
<data name="PageDescription" xml:space="preserve">
|
||||
<value>Faça o upload de uma imagem JPG para convertê-la para o formato WebP.</value>
|
||||
</data>
|
||||
<data name="FileInputLabel" xml:space="preserve">
|
||||
<value>Selecione o arquivo:</value>
|
||||
</data>
|
||||
<data name="ConvertButton" xml:space="preserve">
|
||||
<value>Converter Agora</value>
|
||||
</data>
|
||||
</root>
|
||||
5
Areas/ImageConverters/Views/_ViewImports.cshtml
Normal file
5
Areas/ImageConverters/Views/_ViewImports.cshtml
Normal file
@ -0,0 +1,5 @@
|
||||
@using Convert_It_Online
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@inject IViewLocalizer Localizer
|
||||
1
Areas/ImageConverters/Views/_ViewStart.cshtml
Normal file
1
Areas/ImageConverters/Views/_ViewStart.cshtml
Normal file
@ -0,0 +1 @@
|
||||
@{ Layout = "_Layout"; }
|
||||
71
Areas/TextTools/Controllers/CaseConverterController.cs
Normal file
71
Areas/TextTools/Controllers/CaseConverterController.cs
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Convert_It_Online.Areas.TextTools.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// ViewModel para a ferramenta de conversão de texto.
|
||||
/// </summary>
|
||||
public class CaseConverterViewModel
|
||||
{
|
||||
[Display(Name = "Seu texto")]
|
||||
public string? InputText { get; set; }
|
||||
|
||||
public string? ResultText { get; set; }
|
||||
|
||||
// Usado para saber qual botão foi pressionado no formulário
|
||||
public string? ConversionType { get; set; }
|
||||
}
|
||||
|
||||
[Area("TextTools")]
|
||||
public class CaseConverterController : Controller
|
||||
{
|
||||
// Método GET: Apenas exibe a página com um formulário vazio.
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var model = new CaseConverterViewModel();
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// Método POST: Recebe o formulário, processa e retorna o resultado.
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Index([FromForm] CaseConverterViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid || string.IsNullOrEmpty(model.InputText))
|
||||
{
|
||||
// Se o modelo for inválido ou o texto estiver vazio, retorna a view sem fazer nada.
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// Executa a conversão baseada no valor do botão pressionado
|
||||
model.ResultText = model.ConversionType switch
|
||||
{
|
||||
"upper" => model.InputText.ToUpper(),
|
||||
"lower" => model.InputText.ToLower(),
|
||||
"sentence" => ToSentenceCase(model.InputText),
|
||||
_ => model.InputText // Caso padrão, não faz nada
|
||||
};
|
||||
|
||||
// Retorna a mesma view, agora com o modelo preenchido (InputText e ResultText)
|
||||
return View(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converte uma string para "Sentence case", onde a primeira letra de cada sentença é maiúscula.
|
||||
/// </summary>
|
||||
private string ToSentenceCase(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return input;
|
||||
|
||||
var lowerCase = input.ToLower();
|
||||
// Regex para encontrar o primeiro caractere da string ou o primeiro caractere após um ponto e espaço.
|
||||
var r = new Regex(@"(^[a-z])|\.\s+(.)", RegexOptions.ExplicitCapture);
|
||||
|
||||
return r.Replace(lowerCase, s => s.Value.ToUpper());
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Areas/TextTools/Views/CaseConverter/Index.cshtml
Normal file
32
Areas/TextTools/Views/CaseConverter/Index.cshtml
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
|
||||
@model Convert_It_Online.Areas.TextTools.Controllers.CaseConverterViewModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = Localizer["PageTitle"];
|
||||
}
|
||||
|
||||
<h1 class="mb-4">@Localizer["PageTitle"]</h1>
|
||||
|
||||
<form asp-action="Index" method="post">
|
||||
@Html.AntiForgeryToken()
|
||||
<div class="mb-3">
|
||||
<label asp-for="InputText" class="form-label">@Localizer["TextAreaLabel"]</label>
|
||||
<textarea asp-for="InputText" class="form-control" rows="8"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<button type="submit" name="ConversionType" value="upper" class="btn btn-primary">@Localizer["ToUpperButton"]</button>
|
||||
<button type="submit" name="ConversionType" value="lower" class="btn btn-secondary">@Localizer["ToLowerButton"]</button>
|
||||
<button type="submit" name="ConversionType" value="sentence" class="btn btn-info">@Localizer["ToSentenceCaseButton"]</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.ResultText))
|
||||
{
|
||||
<hr class="my-4" />
|
||||
<h2>@Localizer["ResultTitle"]</h2>
|
||||
<textarea asp-for="ResultText" class="form-control" rows="8" readonly="readonly"></textarea>
|
||||
}
|
||||
21
Areas/TextTools/Views/CaseConverter/Index.es-CL.resx
Normal file
21
Areas/TextTools/Views/CaseConverter/Index.es-CL.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertidor de Mayúsculas y Minúsculas</value>
|
||||
</data>
|
||||
<data name="TextAreaLabel" xml:space="preserve">
|
||||
<value>Ingresa tu texto aquí:</value>
|
||||
</data>
|
||||
<data name="ToUpperButton" xml:space="preserve">
|
||||
<value>MAYÚSCULAS</value>
|
||||
</data>
|
||||
<data name="ToLowerButton" xml:space="preserve">
|
||||
<value>minúsculas</value>
|
||||
</data>
|
||||
<data name="ToSentenceCaseButton" xml:space="preserve">
|
||||
<value>Primera Mayúscula</value>
|
||||
</data>
|
||||
<data name="ResultTitle" xml:space="preserve">
|
||||
<value>Resultado</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Areas/TextTools/Views/CaseConverter/Index.es-MX.resx
Normal file
21
Areas/TextTools/Views/CaseConverter/Index.es-MX.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertidor de Mayúsculas y Minúsculas</value>
|
||||
</data>
|
||||
<data name="TextAreaLabel" xml:space="preserve">
|
||||
<value>Ingrese su texto aquí:</value>
|
||||
</data>
|
||||
<data name="ToUpperButton" xml:space="preserve">
|
||||
<value>MAYÚSCULAS</value>
|
||||
</data>
|
||||
<data name="ToLowerButton" xml:space="preserve">
|
||||
<value>minúsculas</value>
|
||||
</data>
|
||||
<data name="ToSentenceCaseButton" xml:space="preserve">
|
||||
<value>Primera Mayúscula</value>
|
||||
</data>
|
||||
<data name="ResultTitle" xml:space="preserve">
|
||||
<value>Resultado</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Areas/TextTools/Views/CaseConverter/Index.es-PY.resx
Normal file
21
Areas/TextTools/Views/CaseConverter/Index.es-PY.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Convertidor de Mayúsculas y Minúsculas</value>
|
||||
</data>
|
||||
<data name="TextAreaLabel" xml:space="preserve">
|
||||
<value>Ingresa tu texto aquí:</value>
|
||||
</data>
|
||||
<data name="ToUpperButton" xml:space="preserve">
|
||||
<value>MAYÚSCULAS</value>
|
||||
</data>
|
||||
<data name="ToLowerButton" xml:space="preserve">
|
||||
<value>minúsculas</value>
|
||||
</data>
|
||||
<data name="ToSentenceCaseButton" xml:space="preserve">
|
||||
<value>Primera Mayúscula</value>
|
||||
</data>
|
||||
<data name="ResultTitle" xml:space="preserve">
|
||||
<value>Resultado</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Areas/TextTools/Views/CaseConverter/Index.pt-BR.resx
Normal file
21
Areas/TextTools/Views/CaseConverter/Index.pt-BR.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Conversor de Caixa de Texto</value>
|
||||
</data>
|
||||
<data name="TextAreaLabel" xml:space="preserve">
|
||||
<value>Digite seu texto aqui:</value>
|
||||
</data>
|
||||
<data name="ToUpperButton" xml:space="preserve">
|
||||
<value>MAIÚSCULAS</value>
|
||||
</data>
|
||||
<data name="ToLowerButton" xml:space="preserve">
|
||||
<value>minúsculas</value>
|
||||
</data>
|
||||
<data name="ToSentenceCaseButton" xml:space="preserve">
|
||||
<value>Primeira Maiúscula</value>
|
||||
</data>
|
||||
<data name="ResultTitle" xml:space="preserve">
|
||||
<value>Resultado</value>
|
||||
</data>
|
||||
</root>
|
||||
5
Areas/TextTools/Views/_ViewImports.cshtml
Normal file
5
Areas/TextTools/Views/_ViewImports.cshtml
Normal file
@ -0,0 +1,5 @@
|
||||
@using Convert_It_Online
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@inject IViewLocalizer Localizer
|
||||
1
Areas/TextTools/Views/_ViewStart.cshtml
Normal file
1
Areas/TextTools/Views/_ViewStart.cshtml
Normal file
@ -0,0 +1 @@
|
||||
@{ Layout = "_Layout"; }
|
||||
44
Controllers/HomeController.cs
Normal file
44
Controllers/HomeController.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Convert_It_Online.Controllers
|
||||
{
|
||||
// ViewModel para representar uma ferramenta no menu da Home
|
||||
public class ToolViewModel
|
||||
{
|
||||
public required string TitleKey { get; set; }
|
||||
public required string DescriptionKey { get; set; }
|
||||
public required string Area { get; set; }
|
||||
public required string Controller { get; set; }
|
||||
public required string IconClass { get; set; } // Propriedade para o ícone
|
||||
public string Action { get; set; } = "Index";
|
||||
}
|
||||
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
var availableTools = new List<ToolViewModel>
|
||||
{
|
||||
new ToolViewModel
|
||||
{
|
||||
TitleKey = "TextToolsTitle",
|
||||
DescriptionKey = "TextToolsDescription",
|
||||
Area = "TextTools",
|
||||
Controller = "CaseConverter",
|
||||
IconClass = "bi-fonts"
|
||||
},
|
||||
new ToolViewModel
|
||||
{
|
||||
TitleKey = "ImageToolsTitle",
|
||||
DescriptionKey = "ImageToolsDescription",
|
||||
Area = "ImageConverters",
|
||||
Controller = "JpgToWebp",
|
||||
IconClass = "bi-image-alt"
|
||||
}
|
||||
};
|
||||
|
||||
return View(availableTools);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Convert-It.csproj
Normal file
14
Convert-It.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>Convert_It_Online</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
25
Convert-It.sln
Normal file
25
Convert-It.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36414.22 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Convert-It", "Convert-It.csproj", "{D8E3BC66-82F6-0019-7082-DF2342D15CEC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D8E3BC66-82F6-0019-7082-DF2342D15CEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D8E3BC66-82F6-0019-7082-DF2342D15CEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D8E3BC66-82F6-0019-7082-DF2342D15CEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D8E3BC66-82F6-0019-7082-DF2342D15CEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DD63E0A6-3BE6-4B90-8606-3F4BDEB89264}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
64
Program.cs
Normal file
64
Program.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.AspNetCore.Localization.Routing;
|
||||
|
||||
// 1. Builder e Serviços
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
builder.Services.AddControllersWithViews()
|
||||
.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// 2. Configuração de Localização (RequestLocalizationOptions)
|
||||
var supportedCultures = new[] { "pt-BR", "es-MX", "es-CL", "es-PY" };
|
||||
|
||||
var localizationOptions = new RequestLocalizationOptions
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture("pt-BR"),
|
||||
SupportedCultures = supportedCultures.Select(c => new CultureInfo(c)).ToList(),
|
||||
SupportedUICultures = supportedCultures.Select(c => new CultureInfo(c)).ToList()
|
||||
};
|
||||
|
||||
localizationOptions.RequestCultureProviders.Clear();
|
||||
localizationOptions.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
|
||||
|
||||
// 3. Pipeline de Middlewares (na ordem correta)
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRequestLocalization(localizationOptions);
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
// 4. Mapeamento de Rotas (com cultura)
|
||||
app.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
pattern: "{culture:length(2,5)}/{area:exists}/{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{culture:length(2,5)}/{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.MapFallback(async context =>
|
||||
{
|
||||
context.Response.Redirect("/pt-BR");
|
||||
await Task.CompletedTask;
|
||||
});
|
||||
|
||||
// 5. Execução
|
||||
app.Run();
|
||||
12
Properties/launchSettings.json
Normal file
12
Properties/launchSettings.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Convert-It": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:59345;http://localhost:59346"
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Views/Home/Index.cshtml
Normal file
39
Views/Home/Index.cshtml
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
|
||||
@model List<Convert_It_Online.Controllers.ToolViewModel>
|
||||
|
||||
@{
|
||||
ViewData["Title"] = Localizer["PageTitle"];
|
||||
}
|
||||
|
||||
<div class="text-center mb-5">
|
||||
<h1 class="display-4">@Localizer["PageTitle"]</h1>
|
||||
<p class="lead text-muted">@Localizer["Subtitle"]</p>
|
||||
</div>
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2 g-4">
|
||||
@foreach (var tool in Model)
|
||||
{
|
||||
<div class="col">
|
||||
@* A tag de link envolve todo o card e usa os Tag Helpers para a rota *@
|
||||
<a asp-area="@tool.Area"
|
||||
asp-controller="@tool.Controller"
|
||||
asp-action="@tool.Action"
|
||||
asp-route-culture="@ViewContext.RouteData.Values["culture"]"
|
||||
class="text-decoration-none">
|
||||
|
||||
<div class="card h-100 text-center border-secondary">
|
||||
<div class="card-body p-4">
|
||||
<div class="feature-icon-1 bg-primary bg-gradient text-white fs-1 rounded-3 mb-4 mt-n4">
|
||||
<i class="@tool.IconClass"></i>
|
||||
</div>
|
||||
<h2 class="fs-4 fw-bold">@Localizer[tool.TitleKey]</h2>
|
||||
<p class="mb-0 text-muted">@Localizer[tool.DescriptionKey]</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
21
Views/Home/Index.es-CL.resx
Normal file
21
Views/Home/Index.es-CL.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Tus Herramientas de Conversión</value>
|
||||
</data>
|
||||
<data name="Subtitle" xml:space="preserve">
|
||||
<value>Soluciones rápidas y fáciles para tu día a día</value>
|
||||
</data>
|
||||
<data name="TextToolsTitle" xml:space="preserve">
|
||||
<value>Herramientas de Texto</value>
|
||||
</data>
|
||||
<data name="TextToolsDescription" xml:space="preserve">
|
||||
<value>Convierte, formatea y manipula textos fácilmente.</value>
|
||||
</data>
|
||||
<data name="ImageToolsTitle" xml:space="preserve">
|
||||
<value>Convertidores de Imagen</value>
|
||||
</data>
|
||||
<data name="ImageToolsDescription" xml:space="preserve">
|
||||
<value>Optimiza y convierte imágenes a cualquier formato.</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Views/Home/Index.es-MX.resx
Normal file
21
Views/Home/Index.es-MX.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Sus Herramientas de Conversión</value>
|
||||
</data>
|
||||
<data name="Subtitle" xml:space="preserve">
|
||||
<value>Soluciones rápidas y fáciles para su día a día</value>
|
||||
</data>
|
||||
<data name="TextToolsTitle" xml:space="preserve">
|
||||
<value>Herramientas de Texto</value>
|
||||
</data>
|
||||
<data name="TextToolsDescription" xml:space="preserve">
|
||||
<value>Convierta, formatee y manipule textos fácilmente.</value>
|
||||
</data>
|
||||
<data name="ImageToolsTitle" xml:space="preserve">
|
||||
<value>Convertidores de Imagen</value>
|
||||
</data>
|
||||
<data name="ImageToolsDescription" xml:space="preserve">
|
||||
<value>Optimice y convierta imágenes para cualquier formato.</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Views/Home/Index.es-PY.resx
Normal file
21
Views/Home/Index.es-PY.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Tus Herramientas de Conversión</value>
|
||||
</data>
|
||||
<data name="Subtitle" xml:space="preserve">
|
||||
<value>Soluciones rápidas y fáciles para tu día a día</value>
|
||||
</data>
|
||||
<data name="TextToolsTitle" xml:space="preserve">
|
||||
<value>Herramientas de Texto</value>
|
||||
</data>
|
||||
<data name="TextToolsDescription" xml:space="preserve">
|
||||
<value>Convierte, formatea y manipula textos fácilmente.</value>
|
||||
</data>
|
||||
<data name="ImageToolsTitle" xml:space="preserve">
|
||||
<value>Convertidores de Imagen</value>
|
||||
</data>
|
||||
<data name="ImageToolsDescription" xml:space="preserve">
|
||||
<value>Optimiza y convierte imágenes a cualquier formato.</value>
|
||||
</data>
|
||||
</root>
|
||||
21
Views/Home/Index.pt-BR.resx
Normal file
21
Views/Home/Index.pt-BR.resx
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="PageTitle" xml:space="preserve">
|
||||
<value>Suas Ferramentas de Conversão</value>
|
||||
</data>
|
||||
<data name="Subtitle" xml:space="preserve">
|
||||
<value>Soluções rápidas e fáceis para o seu dia a dia</value>
|
||||
</data>
|
||||
<data name="TextToolsTitle" xml:space="preserve">
|
||||
<value>Ferramentas de Texto</value>
|
||||
</data>
|
||||
<data name="TextToolsDescription" xml:space="preserve">
|
||||
<value>Converta, formate e manipule textos facilmente.</value>
|
||||
</data>
|
||||
<data name="ImageToolsTitle" xml:space="preserve">
|
||||
<value>Conversores de Imagem</value>
|
||||
</data>
|
||||
<data name="ImageToolsDescription" xml:space="preserve">
|
||||
<value>Otimize e converta imagens para qualquer formato.</value>
|
||||
</data>
|
||||
</root>
|
||||
90
Views/Shared/_Layout.cshtml
Normal file
90
Views/Shared/_Layout.cshtml
Normal file
@ -0,0 +1,90 @@
|
||||
@using Microsoft.AspNetCore.Localization
|
||||
@using Microsoft.Extensions.Options
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
|
||||
@inject IOptions<RequestLocalizationOptions> LocOptions
|
||||
@inject IViewLocalizer Localizer
|
||||
|
||||
@{
|
||||
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
|
||||
var supportedCultures = LocOptions.Value.SupportedCultures;
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="@requestCulture?.RequestCulture.UICulture.Name" data-bs-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - Convert-It Online</title>
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.3/dist/cyborg/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index" asp-route-culture="@requestCulture?.RequestCulture.UICulture.Name">Convert-It Online</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarColor01">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" asp-area="" asp-controller="Home" asp-action="Index" asp-route-culture="@requestCulture?.RequestCulture.UICulture.Name">@Localizer["HomeLink"]</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="languageDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-translate me-2"></i>
|
||||
@requestCulture?.RequestCulture.UICulture.NativeName
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="languageDropdown">
|
||||
@foreach (var culture in supportedCultures!)
|
||||
{
|
||||
<li>
|
||||
<a class="dropdown-item"
|
||||
asp-controller="@ViewContext.RouteData.Values["controller"]"
|
||||
asp-action="@ViewContext.RouteData.Values["action"]"
|
||||
asp-all-route-data="@Context.Request.Query.ToDictionary(p => p.Key, p => p.Value.ToString())"
|
||||
asp-route-culture="@culture.Name">
|
||||
@culture.NativeName
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<div class="ad-placeholder ad-top d-none d-lg-flex">
|
||||
<span>Ad Placeholder (Top)</span>
|
||||
</div>
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
<div class="col-lg-3 d-none d-lg-block">
|
||||
<div class="ad-placeholder ad-side">
|
||||
<span>Ad Placeholder (Side)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-dark">
|
||||
<div class="container text-center">
|
||||
<span class="text-muted">@Localizer["FooterText"]</span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
9
Views/Shared/_Layout.es-CL.resx
Normal file
9
Views/Shared/_Layout.es-CL.resx
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="HomeLink" xml:space="preserve">
|
||||
<value>Inicio</value>
|
||||
</data>
|
||||
<data name="FooterText" xml:space="preserve">
|
||||
<value>© 2025 - Convert-It Online</value>
|
||||
</data>
|
||||
</root>
|
||||
9
Views/Shared/_Layout.es-MX.resx
Normal file
9
Views/Shared/_Layout.es-MX.resx
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="HomeLink" xml:space="preserve">
|
||||
<value>Inicio</value>
|
||||
</data>
|
||||
<data name="FooterText" xml:space="preserve">
|
||||
<value>© 2025 - Convert-It Online</value>
|
||||
</data>
|
||||
</root>
|
||||
9
Views/Shared/_Layout.es-PY.resx
Normal file
9
Views/Shared/_Layout.es-PY.resx
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="HomeLink" xml:space="preserve">
|
||||
<value>Inicio</value>
|
||||
</data>
|
||||
<data name="FooterText" xml:space="preserve">
|
||||
<value>© 2025 - Convert-It Online</value>
|
||||
</data>
|
||||
</root>
|
||||
9
Views/Shared/_Layout.pt-BR.resx
Normal file
9
Views/Shared/_Layout.pt-BR.resx
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="HomeLink" xml:space="preserve">
|
||||
<value>Início</value>
|
||||
</data>
|
||||
<data name="FooterText" xml:space="preserve">
|
||||
<value>© 2025 - Convert-It Online</value>
|
||||
</data>
|
||||
</root>
|
||||
5
Views/_ViewImports.cshtml
Normal file
5
Views/_ViewImports.cshtml
Normal file
@ -0,0 +1,5 @@
|
||||
@using Convert_It_Online
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@inject IViewLocalizer Localizer
|
||||
3
Views/_ViewStart.cshtml
Normal file
3
Views/_ViewStart.cshtml
Normal file
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
224
wwwroot/css/site.css
Normal file
224
wwwroot/css/site.css
Normal file
@ -0,0 +1,224 @@
|
||||
/* ========== TEMA ESCURO PERSONALIZADO ========== */
|
||||
:root {
|
||||
--primary-gradient: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.05);
|
||||
--card-border: rgba(255, 255, 255, 0.1);
|
||||
--text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
--box-shadow: 0 8px 32px rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
|
||||
/* ========== LAYOUT PRINCIPAL ========== */
|
||||
body {
|
||||
background: linear-gradient(135deg, #0a1929 0%, #1a2332 100%);
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background: var(--primary-gradient) !important;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 4px 20px rgba(0, 123, 255, 0.2);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
text-shadow: var(--text-shadow);
|
||||
}
|
||||
|
||||
/* ========== CARDS MODERNOS ========== */
|
||||
.card {
|
||||
background: var(--card-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid var(--card-border);
|
||||
box-shadow: var(--box-shadow);
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 12px 40px rgba(0, 123, 255, 0.25);
|
||||
border-color: rgba(0, 123, 255, 0.3);
|
||||
}
|
||||
|
||||
.card a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.card a:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* ========== ÍCONES DOS CARDS ========== */
|
||||
.feature-icon-1 {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 4rem;
|
||||
width: 4rem;
|
||||
background: var(--primary-gradient) !important;
|
||||
box-shadow: 0 8px 16px rgba(0, 123, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.feature-icon-1::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
transition: all 0.6s ease;
|
||||
transform: rotate(45deg);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.card:hover .feature-icon-1::before {
|
||||
opacity: 1;
|
||||
animation: shimmer 1s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { transform: translateX(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) rotate(45deg); }
|
||||
}
|
||||
|
||||
/* ========== TÍTULOS E TEXTOS ========== */
|
||||
.display-4 {
|
||||
font-weight: 800;
|
||||
background: var(--primary-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-shadow: none;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.lead {
|
||||
font-size: 1.25rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.card p {
|
||||
opacity: 0.85;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ========== DROPDOWN DE IDIOMAS ========== */
|
||||
.dropdown-toggle {
|
||||
background: rgba(255, 255, 255, 0.1) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.dropdown-toggle:hover {
|
||||
background: rgba(255, 255, 255, 0.2) !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background: rgba(33, 37, 41, 0.95) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: rgba(0, 123, 255, 0.2) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/* ========== FOOTER ========== */
|
||||
.footer {
|
||||
background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%) !important;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* ========== PLACEHOLDERS DE ANÚNCIO ========== */
|
||||
.ad-placeholder {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 2px dashed rgba(255, 255, 255, 0.1);
|
||||
border-radius: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 1rem;
|
||||
backdrop-filter: blur(5px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.ad-placeholder:hover {
|
||||
border-color: rgba(0, 123, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.ad-top {
|
||||
min-height: 90px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.ad-side {
|
||||
min-height: 600px;
|
||||
position: sticky;
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
/* ========== RESPONSIVIDADE ========== */
|
||||
@media (max-width: 768px) {
|
||||
.display-4 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.lead {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.feature-icon-1 {
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== ANIMAÇÕES SUAVES ========== */
|
||||
* {
|
||||
transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.container {
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user