Primeiro commit com arquivos do projeto #1

Merged
ricardo merged 1 commits from master into main 2025-01-25 13:44:52 +00:00
2201 changed files with 92605 additions and 6 deletions

4
.gitignore vendored
View File

@ -1,4 +1,3 @@
# ---> VisualStudio
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
## ##
@ -396,5 +395,4 @@ FodyWeavers.xsd
*.msp *.msp
# JetBrains Rider # JetBrains Rider
*.sln.iml *.sln.iml

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Enrichers.Context" Version="4.6.5" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="8.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\vcart.me\vcart.back\Struct.ValueObjects\BaseDomain.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
public class BusinessAreas
{
public BusinessAreas() { }
public string Name { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
internal class BusinessAres
{
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
public class LinkBio
{
/// <summary>
/// Ordem de exibição
/// </summary>
public int OrderNum { get; set; }
/// <summary>
/// Parte customizada do link
/// </summary>
public string UrlData { get; set; }
/// <summary>
/// Parte fixa do link (obter do service links quando cadastrar)
/// </summary>
public string ServiceUrl { get; set; }
/// <summary>
/// Url/caminho do PNG do link
/// </summary>
public string ServiceIcon { get; set; }
/// <summary>
/// Exibir/nao exibir
/// </summary>
public bool IsVisible { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
public class PageBio
{
public int Id { get; set; }
public string UrlParte1 { get; set; }
public string UrlParte2 { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<LinkBio>? Links { get; set; }
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ChatMvc.Domain.ValueObjects;
namespace ChatMvc.Domain.Entities
{
public class PersonUser
{
public Id id { get; private set; }
public Username Username { get; private set; }
public Name Name { get; private set; }
public string FirstName => Name.FirstName;
public string LastName => Name.LastName;
public Email Email { get; private set; }
public DateChanged DateChanged { get; private set; }
public bool IsProfileCompleted { get; private set; }
public int CountryId { get; private set; }
public int BusinessAreaId { get; private set; }
public string DesiredName { get; private set; }
public DateTime CreatedAt { get; private set; }
public UserPlan? Plano { get; private set; }
public List<UserPlan>? PastPlans { get; private set; }
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
public class ServiceLinkPart
{
public int OrderNum { get; set; }
public string Name { get; set; }
public string VariableName { get; set; }
public string Value { get; set; }
public bool CanUserEdit { get; set; }
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
/// <summary>
/// Vai ler uma lista estatica do BD com os links dos serviços
/// </summary>
public class ServiceLink
{
/// <summary>
/// Id do serviço
/// </summary>
public string Id { get; set; }
/// <summary>
/// Nome do serviço
/// </summary>
public string Name { get; set; }
/// <summary>
/// Guarda a primeira parta da url do serviço
/// </summary>
public string FirstPart { get; set; }
/// <summary>
/// Guarda outras partes/parametros da url (indicando partes customizaveis)
/// </summary>
public List<ServiceLinkPart> Parts { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.Entities
{
public class UserPlan
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string UserPlanId { get; set; }
public string IdPagto { get; private set; }
public string EmailPagto { get; private set; }
public DateTime? DatePagto { get; private set; }
public DateTime? DateUntil { get; private set; }
}
}

View File

@ -0,0 +1,65 @@
using BaseDomain;
using System;
using System.Diagnostics.Metrics;
using System.IO;
using System.Reflection.Emit;
namespace ChatMvc.Domain
{
public class DateBirth : AValueObject
{
public DateTime Value { get; private set; }
public DateBirth(string dateOfBirth)
{
DateTime dateAsDate;
if (dateOfBirth!=null && (DateTime.TryParse(dateOfBirth, out dateAsDate) || dateAsDate > DateTime.Now))
{
this.Value = dateAsDate;
this.IsValid = true;
}
else
{
this.IsValid = false;
}
}
public DateBirth(DateTime dateOfBirth)
{
if (dateOfBirth > DateTime.Now)
{
this.IsValid = false;
}
this.Value = dateOfBirth;
}
public int YearsOld {
get
{
var age = DateTime.Now.Year - this.Value.Year;
if (this.Value.Date > DateTime.Now.AddYears(-age)) age--;
return age;
}
}
public static implicit operator string(DateBirth d) => d.Value.ToString("pt-BR");
public static explicit operator DateBirth(DateTime b) => new DateBirth(b);
public static explicit operator DateBirth(string b) => new DateBirth(b);
protected override IEnumerable<object> GetEqualityComponents()
{
yield return Value;
}
public override bool GetValidationExpression()
{
if (this.Value > DateTime.Now)
{
this.IsValid = false;
}
return this.IsValid;
}
}
}

View File

@ -0,0 +1,45 @@

using BaseDomain;
using System.Globalization;
namespace ChatMvc.Domain
{
public class DateChanged : AValueObject
{
public DateChanged()
{
this.Value = DateTime.Now;
}
public DateChanged(DateTime dateTime)
{
this.Value = dateTime;
}
public DateChanged(string dateTime)
{
this.Value = Convert.ToDateTime(dateTime, new CultureInfo("pt-BR"));
}
public DateTime? Value { get; private set; }
public override bool GetValidationExpression()
{
IsValid = true;
if (Value == null)
{
IsValid = false;
}
return IsValid;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return Value;
}
public static implicit operator string(DateChanged d) => d.Value.Value.ToString("pt-BR");
public static explicit operator DateChanged(DateTime b) => new DateChanged(b);
public static explicit operator DateChanged(string b) => new DateChanged(b);
}
}

View File

@ -0,0 +1,44 @@
using BaseDomain;
using System.Net.Mail;
namespace ChatMvc.Domain
{
public class Email : AValueObject
{
public Email(string email)
{
this.Value = email;
}
public string Value { get; private set; }
public static implicit operator string(Email e) => e.Value;
public static explicit operator Email(string email) => new Email(email);
public override bool GetValidationExpression()
{
return IsEMailValid(this.Value);
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return this.Value;
}
private bool IsEMailValid(string email)
{
var valid = true;
try
{
var emailAddress = new MailAddress(email);
}
catch
{
valid = false;
}
return valid;
}
}
}

View File

@ -0,0 +1,22 @@
using BaseDomain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.ValueObjects
{
public class Id : AValueObject
{
public override bool GetValidationExpression()
{
throw new NotImplementedException();
}
protected override IEnumerable<object> GetEqualityComponents()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,45 @@
using BaseDomain;
namespace ChatMvc.Domain
{
public class Name : AValueObject
{
public Name(string fullName)
{
this.FullName = fullName;
var names = fullName.Split(' ');
if (names.Length >= 2)
{
this.FirstName = names[0];
this.LastName = names[names.Length-1];
}
}
public string FullName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public override bool GetValidationExpression()
{
return this.IsValid = this.IsValidName(FullName);
}
public override string ToString()
{
return this.FullName;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return this.FullName;
}
private bool IsValidName(string fullName)
{
return fullName.Contains(' ');
}
public static implicit operator string(Name name) => name.FullName;
public static explicit operator Name(string fullname) => new Name(fullname);
}
}

View File

@ -0,0 +1,34 @@
using BaseDomain;
using System.Text.RegularExpressions;
namespace ChatMvc.Domain
{
public class Phone : AValueObject
{
public string Value { get; set; }
public Phone(string phone)
{
this.IsPhoneValid(this.Value);
Value = phone;
}
public override bool GetValidationExpression()
{
return this.IsPhoneValid(this.Value);
}
public bool IsPhoneValid(string phone)
{
var pattern = "^\\s*(\\d{2}|\\d{0})[-. ]?(\\d{5}|\\d{4})[-. ]?(\\d{4})[-. ]?\\s*$";
return this.IsValid = Regex.IsMatch(Value, pattern);
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return this.Value;
}
public static implicit operator string(Phone name) => name.Value;
public static explicit operator Phone(string phone) => new Phone(phone);
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ChatMvc.Domain.ValueObjects
{
public class Username
{
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Bson" Version="2.28.0" />
<PackageReference Include="MongoDB.Driver" Version="2.28.0" />
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Enrichers.Context" Version="4.6.5" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="8.3.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
namespace ChatMvc.Infra.MongoDB
{
public class MongoDbContext
{
private readonly IMongoDatabase _database;
public MongoDbContext(string connectionString, string databaseName)
{
var client = new MongoClient(connectionString);
_database = client.GetDatabase(databaseName);
}
public IMongoCollection<PersonUser> Users => _database.GetCollection<PersonUser>("Users");
}
}

View File

@ -0,0 +1,34 @@
using global::MongoDB.Bson.Serialization.Attributes;
using global::MongoDB.Bson;
namespace ChatMvc.Infra.MongoDB
{
public class PersonUser
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("Nome")]
public string Nome { get; set; }
[BsonElement("Email")]
public string Email { get; set; }
[BsonElement("País")]
public string Pais { get; set; }
[BsonElement("AreaDeNegocio")]
public string AreaDeNegocio { get; set; }
[BsonElement("Completado")]
public bool Completado { get; set; }
[BsonElement("Valido")]
public bool Valido { get; set; }
[BsonElement("DataHoraCriacao")]
public DateTime DataHoraCriacao { get; set; }
}
}

25
Chat/.dockerignore Normal file
View File

@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

43
Chat/Chat.sln Normal file
View File

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34031.279
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatMvc", "ChatMvc.csproj", "{51C3E6BC-4BBC-429F-9A7F-8C8A14E14DF4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaseDomain", "..\..\vcart.me\vcart.back\Struct.ValueObjects\BaseDomain.csproj", "{083273D7-7AE9-48A0-A59F-7CC03E1B4C30}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Chat.Domain", "..\Chat.Domain\Chat.Domain.csproj", "{6B28F2CF-D64C-46F6-AD33-0FFFA9451431}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Chat.Infra", "..\Chat.Infra\Chat.Infra.csproj", "{46CE585C-876C-4060-9EF1-92BAA301D1E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{51C3E6BC-4BBC-429F-9A7F-8C8A14E14DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51C3E6BC-4BBC-429F-9A7F-8C8A14E14DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51C3E6BC-4BBC-429F-9A7F-8C8A14E14DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51C3E6BC-4BBC-429F-9A7F-8C8A14E14DF4}.Release|Any CPU.Build.0 = Release|Any CPU
{083273D7-7AE9-48A0-A59F-7CC03E1B4C30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{083273D7-7AE9-48A0-A59F-7CC03E1B4C30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{083273D7-7AE9-48A0-A59F-7CC03E1B4C30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{083273D7-7AE9-48A0-A59F-7CC03E1B4C30}.Release|Any CPU.Build.0 = Release|Any CPU
{6B28F2CF-D64C-46F6-AD33-0FFFA9451431}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B28F2CF-D64C-46F6-AD33-0FFFA9451431}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B28F2CF-D64C-46F6-AD33-0FFFA9451431}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B28F2CF-D64C-46F6-AD33-0FFFA9451431}.Release|Any CPU.Build.0 = Release|Any CPU
{46CE585C-876C-4060-9EF1-92BAA301D1E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46CE585C-876C-4060-9EF1-92BAA301D1E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46CE585C-876C-4060-9EF1-92BAA301D1E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46CE585C-876C-4060-9EF1-92BAA301D1E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EC4AB36F-49CB-4819-ACA4-3A14CB1D9B50}
EndGlobalSection
EndGlobal

57
Chat/ChatMvc.csproj Normal file
View File

@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>61881b6e-e2bb-4a8a-b8d2-23b733cdaea3</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<Content Remove="wwwroot\js\notif.js" />
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="wwwroot\js\notif.js" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="8.0.7" />
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Enrichers.Context" Version="4.6.5" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Grafana.Loki" Version="8.3.0" />
<PackageReference Include="Stripe.net" Version="45.13.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\img\" />
</ItemGroup>
<ItemGroup>
<None Include="wwwroot\js\notif.js" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resource.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resource.pt-BR.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resource.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
namespace ChatMvc.Controllers
{
public class CartHomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

View File

@ -0,0 +1,138 @@
using ChatMvc.Models;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Authorization;
namespace ChatMvc.Controllers
{
[Authorize]
public class ChatController : Controller
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
private readonly IAntiforgery _antiforgery;
public ChatController(IHttpClientFactory httpClientFactory, IConfiguration configuration, IAntiforgery antiforgery)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
_antiforgery = antiforgery;
}
public IActionResult Index()
{
var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
return View();
}
[HttpGet("chat/proxy-response")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ProxyResponse(string sessionId, string message)
{
try
{
if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
{
return BadRequest("Requisição inválida");
}
var client = _httpClientFactory.CreateClient();
var baseUrl = _configuration["ExternalApiBaseUrl"];
var token = Request.Headers["Authorization"].ToString();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
var response = await client.GetAsync(
$"{baseUrl}/chat/response?sessionId={sessionId}&message={message}");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return Ok(content);
}
catch (Exception ex)
{
return BadRequest($"Erro ao processar mensagem: {ex.Message}");
}
}
[HttpPost("chat/authenticate")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Authenticate([FromBody] AuthenticateRequest request)
{
try
{
if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
{
return BadRequest("Requisição inválida");
}
var client = _httpClientFactory.CreateClient();
var baseUrl = _configuration["ExternalApiBaseUrl"];
// Primeira requisição - newclient
var newClientRequest = new
{
localId = request.UserId,
companyTenant = request.Company,
name = request.Name
};
var newClientResponse = await client.PostAsync(
$"{baseUrl}/login/newclient",
new StringContent(JsonConvert.SerializeObject(newClientRequest),
Encoding.UTF8, "application/json"));
newClientResponse.EnsureSuccessStatusCode();
var clientContent = await newClientResponse.Content.ReadAsStringAsync();
var clientResult = JsonConvert.DeserializeObject<NewClientResponse>(clientContent);
// Segunda requisição - token
var tokenRequest = new
{
clientId = request.UserId,
clientName = request.Name,
clientSecret = clientResult.Secret
};
var tokenResponse = await client.PostAsync(
$"{baseUrl}/login/token",
new StringContent(JsonConvert.SerializeObject(tokenRequest),
Encoding.UTF8, "application/json"));
tokenResponse.EnsureSuccessStatusCode();
var tokenContent = await tokenResponse.Content.ReadAsStringAsync();
var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(tokenContent);
return Ok(new { token = tokenResult.Token });
}
catch (Exception ex)
{
return BadRequest($"Erro na autenticação: {ex.Message}");
}
}
}
public class AuthenticateRequest
{
public string UserId { get; set; }
public string Company { get; set; }
public string Name { get; set; }
}
public class NewClientResponse
{
public string Secret { get; set; }
}
public class TokenResponse
{
public string Token { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ChatMvc.Models;
namespace ChatMvc.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> logger;
public HomeController(ILogger<HomeController> logger)
{
this.logger = logger;
}
public IActionResult Index()
{
this.logger.LogInformation("Home carregada!");
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

View File

@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Mvc;
using System.Globalization;
namespace ChatMvc.Controllers
{
public class LanguageController : Controller
{
public ActionResult ChangeLanguage(string lang)
{
if (!string.IsNullOrEmpty(lang))
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
}
Response.Cookies.Append("Language", lang, new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });
return Redirect(Request.Headers["Referer"].ToString());
}
}
}

View File

@ -0,0 +1,129 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Stripe;
namespace ChatMvc.Controllers
{
public class LoginController : Controller
{
private readonly ILogger<LoginController> logger;
private readonly IHttpClientFactory httpClientFactory;
private readonly StripeClient _stripeClient;
public LoginController(ILogger<LoginController> logger, IHttpClientFactory httpClientFactory)
{
this.logger = logger;
this.httpClientFactory = httpClientFactory;
}
public IActionResult Index()
{
return View("~/Views/Login/Index.cshtml");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
var redirectUrl = Url.Action("ExternalLoginCallback", "Login", new { ReturnUrl = returnUrl });
var properties = new AuthenticationProperties { RedirectUri = "https://localhost:7078" + redirectUrl };
return Challenge(properties, "Microsoft");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ExternalLoginGoogle(string provider, string returnUrl)
{
var redirectUrl = Url.Action("ExternalLoginCallback", "Login", new { ReturnUrl = returnUrl });
var properties = new AuthenticationProperties { RedirectUri = "https://localhost:7078" + redirectUrl };
return Challenge(properties, "Google");
}
[AllowAnonymous]
[HttpGet]
public async Task<ActionResult> ExternalLoginCallback(string code="")
{
//TODO: Temporário
var emailExist = HttpContext.User.FindFirst(ClaimTypes.Email).Value;
if (emailExist != null)
{
List<Claim> claims = null;
if (HttpContext.User.FindFirst(ClaimTypes.GivenName) != null)
{
claims = new List<Claim>
{
new Claim(ClaimTypes.Email, emailExist),
new Claim("FirstName", HttpContext.User.FindFirst(ClaimTypes.GivenName).Value),
new Claim("FullName", HttpContext.User.FindFirst(ClaimTypes.GivenName).Value + " " + HttpContext.User.FindFirst(ClaimTypes.Surname).Value),
new Claim(ClaimTypes.Role, "User"),
};
}
else if (HttpContext.User.FindFirst(ClaimTypes.Name)!=null)
{
var name = HttpContext.User.FindFirst(ClaimTypes.Name).Value;
var firstName = name.Split(' ')[0];
claims = new List<Claim>
{
new Claim(ClaimTypes.Email, emailExist),
new Claim("FirstName", firstName),
new Claim("FullName", name),
new Claim(ClaimTypes.Role, "User"),
};
}
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme
);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return RedirectToAction("Index", "Chat");
}
ViewBag.ErrorTitle = $"Email claim not received from: Microsoft";
ViewBag.ErrorMessage = "Please contact support on info@dotnettutorials.net";
return View("Error");
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Index", "Home");
}
}
}

View File

@ -0,0 +1,73 @@
using Microsoft.AspNetCore.Mvc;
using Stripe;
using Stripe.Checkout;
namespace ChatMvc.Controllers
{
[Route("Pay")]
public class PayController : Controller
{
private string domain = "";
public PayController()
{
domain = "http://192.168.0.27:5094/";
}
public IActionResult Index()
{
return View();
}
[HttpPost("createbio")]
public ActionResult CreateBio()
{
StripeConfiguration.ApiKey = "sk_test_51PvIzkBk8jHwC3c0sGuWDUO8MV9KeOdSkir3Ulo2RZWmUhJLBIAgzxQScuomVi2l333MNmi0yr3FgeFv7OZnCJ0j00hD94yGx1";
var options = new SessionCreateOptions
{
UiMode = "embedded",
LineItems = new List<SessionLineItemOptions>
{
new SessionLineItemOptions
{
// Provide the exact Price ID (for example, pr_1234) of the product you want to sell
Price = "price_1Q1CXGBk8jHwC3c0YwypjEVd",
Quantity = 1,
},
},
Mode = "subscription",
ReturnUrl = domain + "/Plans/OrderView?SessionId={CHECKOUT_SESSION_ID}",
};
var service = new SessionService();
Session session = service.Create(options);
return Json(new { clientSecret = session.ClientSecret });
}
[HttpPost("createcatalogo")]
public ActionResult CreateCatalogo()
{
StripeConfiguration.ApiKey = "sk_test_51PvIzkBk8jHwC3c0sGuWDUO8MV9KeOdSkir3Ulo2RZWmUhJLBIAgzxQScuomVi2l333MNmi0yr3FgeFv7OZnCJ0j00hD94yGx1";
var options = new SessionCreateOptions
{
UiMode = "embedded",
LineItems = new List<SessionLineItemOptions>
{
new SessionLineItemOptions
{
// Provide the exact Price ID (for example, pr_1234) of the product you want to sell
Price = "price_1Q1CjvBk8jHwC3c03D82tbH8",
Quantity = 1,
},
},
Mode = "subscription",
ReturnUrl = domain + "/Plans/OrderView?SessionId={CHECKOUT_SESSION_ID}",
};
var service = new SessionService();
Session session = service.Create(options);
return Json(new { clientSecret = session.ClientSecret });
}
}
}

View File

@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Stripe;
using Stripe.Checkout;
using ChatMvc.Models;
namespace ChatMvc.Controllers
{
public class PlansController : Controller
{
private string domain = "";
public PlansController()
{
domain = "http://192.168.0.27:5094/";
}
public IActionResult Index()
{
return View();
}
public IActionResult Pay(string ammount)
{
return View();
}
public IActionResult OrderView([FromQuery] string SessionId)
{
var sessionService = new SessionService();
Session session = sessionService.Get(SessionId);
ViewBag.Status = session.RawJObject["status"];
ViewBag.CustomerEmail = session.RawJObject["customer_details"]["email"];
//return Json(new { status = session.RawJObject["status"], customer_email = session.RawJObject["customer_details"]["email"] });
return View();
}
}
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace ChatMvc.Controllers
{
[Route("signin-microsoft")]
public class SignInController : Controller
{
[HttpGet]
public IActionResult Index()
{
Debug.WriteLine(string.Join(',', HttpContext.Request.Form.Keys));
return View();
}
[HttpPost]
public IActionResult IndexPost()
{
Debug.WriteLine(string.Join(',', HttpContext.Request.Form.Keys));
return View();
}
}
}

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
namespace ChatMvc.Controllers
{
public class StartupController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

22
Chat/Dockerfile Normal file
View File

@ -0,0 +1,22 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["Blinks.csproj", "."]
RUN dotnet restore "./Blinks.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Blinks.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Blinks.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Blinks.dll"]

View File

@ -0,0 +1,12 @@
//using Serilog.Sinks.Loki;
//namespace ChatMvc.LogConfig
//{
// public class LogCredentials : LokiCredentials
// {
// public LogCredentials(string url)
// {
// this.Url = url;
// }
// }
//}

View File

@ -0,0 +1,27 @@
//using Serilog.Sinks.Loki.Labels;
namespace ChatMvc.LogConfig
{
//public class LogLabelProvider : ILogLabelProvider
//{
// public IList<LokiLabel> GetLabels()
// {
// return new List<LokiLabel>
// {
// new LokiLabel("app", "blinks"),
// new LokiLabel("namespace", "test")
// };
// }
// public IList<string> PropertiesAsLabels { get; set; } = new List<string>
// {
// "level", // Since 3.0.0, you need to explicitly add level if you want it!
// "MyLabelPropertyName"
// };
// public IList<string> PropertiesToAppend { get; set; } = new List<string>
// {
// "MyAppendPropertyName"
// };
// //public LokiFormatterStrategy FormatterStrategy { get; set; } = LokiFormatterStrategy.SpecificPropertiesAsLabelsOrAppended;
//}
}

View File

@ -0,0 +1,29 @@
namespace ChatMvc.Middle
{
using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;
public class RequestLocalizationMiddleware
{
private readonly RequestDelegate _next;
public RequestLocalizationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var cookie = context.Request.Cookies["Language"];
if (!string.IsNullOrEmpty(cookie))
{
var culture = new CultureInfo(cookie);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
await _next(context);
}
}
}

View File

@ -0,0 +1,7 @@
namespace ChatMvc.Models
{
public class ChangeViewModel
{
public string ChargeId { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ChatMvc.Models
{
public class ChatMessage
{
public int UserId { get; set; }
public string Message { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace ChatMvc.Models
{
public class ChatResponse
{
public string Message { get; set; }
public DateTime Timestamp { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace ChatMvc.Models
{
public class ErrorViewModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

9
Chat/Models/Payment.cs Normal file
View File

@ -0,0 +1,9 @@
namespace ChatMvc.Models
{
public class Payment
{
public int Amount { get; set; }
public string Currency { get; set; }
public string Description { get; set; }
}
}

View File

@ -0,0 +1,118 @@
{
"settings": {
"components": {
"code": true,
"binaries": false
},
"targetId": "",
"targetDisplayName": ".NET 8.0"
},
"analysisStartTime": "2024-07-29T13:32:41.4251125Z",
"analysisEndTime": "2024-07-29T13:32:58.6631961Z",
"privacyModeHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2270980",
"stats": {
"summary": {
"projects": 2,
"issues": 2,
"incidents": 2,
"effort": 2
},
"charts": {
"severity": {
"Mandatory": 2,
"Optional": 0,
"Potential": 0,
"Information": 0
},
"category": {
"NuGet": 1,
"Project": 1
}
}
},
"projects": [
{
"path": "Blinks.csproj",
"startingProject": true,
"issues": 1,
"storyPoints": 1,
"ruleInstances": [
{
"incidentId": "1161414d-b2e4-4447-9d34-e811b563e1c5",
"ruleId": "NuGet.0001",
"projectPath": "Blinks.csproj",
"state": "Active",
"location": {
"snippetModel": {
"unrestricted": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets, 1.19.4\n\nRecommendation:\n\nNo supported version found",
"protected": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets, 1.19.4\n\nRecommendation:\n\nNo supported version found"
},
"kind": "File",
"path": "Blinks.csproj",
"snippet": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets, 1.19.4\n\nRecommendation:\n\nNo supported version found",
"protectedSnippet": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets, 1.19.4\n\nRecommendation:\n\nNo supported version found",
"label": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets 1.19.4"
}
}
]
},
{
"path": "C:\\vscode\\Blinks.me.mvc\\Blinks.Domain\\Blinks.Domain.csproj",
"startingProject": true,
"issues": 1,
"storyPoints": 1,
"ruleInstances": [
{
"incidentId": "2fdd89a6-9f8d-4428-8845-41d048dcaf73",
"ruleId": "Project.0002",
"projectPath": "C:\\vscode\\Blinks.me.mvc\\Blinks.Domain\\Blinks.Domain.csproj",
"state": "Active",
"location": {
"snippetModel": {
"unrestricted": "Current: net7.0\nNew: net8.0",
"protected": "Current: net7.0\nNew: net8.0"
},
"kind": "File",
"path": "C:\\vscode\\Blinks.me.mvc\\Blinks.Domain\\Blinks.Domain.csproj",
"snippet": "Current: net7.0\nNew: net8.0",
"protectedSnippet": "Current: net7.0\nNew: net8.0"
}
}
]
}
],
"rules": {
"NuGet.0001": {
"id": "NuGet.0001",
"description": "NuGet package is incompatible with selected target framework.\n\nPackage needs to be upgraded to a version supporting selected project target framework. If there no new package versions supporting new target framework, different package needs to be used and all code needs to be upgraded to new API.",
"label": "NuGet package is incompatible",
"severity": "Mandatory",
"effort": 1,
"links": [
{
"url": "https://go.microsoft.com/fwlink/?linkid=2262529",
"isCustom": false
}
]
},
"Project.0002": {
"id": "Project.0002",
"description": "Project\u0027s target framework(s) needs to be changed to the new target framework that you selected for this upgrade.\n\nDuring upgrade target framework will be adjusted to correspinding platform when applicable. In some cases project would result in multiple target frameworks after the upgrade if it was using features that now have their own platforms in moderrn .NET frameworks (windows, iOS, Android etc).",
"label": "Project\u0027s target framework(s) needs to be changed",
"severity": "Mandatory",
"effort": 1,
"links": [
{
"title": "Overview of porting from .NET Framework to .NET",
"url": "https://go.microsoft.com/fwlink/?linkid=2265227",
"isCustom": false
},
{
"title": ".NET project SDKs",
"url": "https://go.microsoft.com/fwlink/?linkid=2265226",
"isCustom": false
}
]
}
}
}

130
Chat/Program.cs Normal file
View File

@ -0,0 +1,130 @@
using ChatMvc.LogConfig;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Options;
using Serilog;
using Serilog.Sinks.Grafana.Loki;
using Stripe;
using Stripe.Forwarding;
using System.Globalization;
using System.Security.Policy;
var builder = WebApplication.CreateBuilder(args);
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.Enrich.WithProperty("app", "blinks")
.WriteTo.Console()
.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
builder.Host.UseSerilog();
var config = builder.Configuration;
//builder.Services.AddAuthentication()
builder.Services.AddAuthentication(
options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = MicrosoftAccountDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Forbidden/";
})
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = config.GetSection("Authentication:Google:ClientId").Value;
googleOptions.ClientSecret = config.GetSection("Authentication:Google:ClientSecret").Value;
})
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = config.GetSection("Microsoft_ClientId").Value;
//microsoftOptions.ClientSecret = "2a7cb1bd-037a-49fa-9e5e-2b2655431af9";
microsoftOptions.ClientSecret = config.GetSection("Microsoft_ClientSecret").Value;
})
;
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
;
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("pt-BR"),
new CultureInfo("en")
};
options.DefaultRequestCulture = new RequestCulture("pt-BR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
StripeConfiguration.ApiKey = builder.Configuration["Stripe:SecretKey"];
builder.Services.AddControllersWithViews();
builder.Services.AddHttpClient();
builder.Services.AddSerilog();
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN";
options.Cookie.Name = "XSRF-TOKEN";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
var app = builder.Build();
var locOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
app.UseMiddleware<RequestLocalizationMiddleware>();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Desabilita HTTPS redirection em desenvolvimento
// app.UseHsts();
// app.UseHttpsRedirection();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.UseSerilogRequestLogging();
app.UseRequestLocalization();
app.Run();

View File

@ -0,0 +1,47 @@
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5094"
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7078;http://localhost:5094"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"environmentVariables": {
"ASPNETCORE_URLS": "https://+:443;http://+:80"
},
"publishAllPorts": true,
"useSSL": true
}
},
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:4083",
"sslPort": 44377
}
}
}

3
Chat/Readme.md Normal file
View File

@ -0,0 +1,3 @@
Obter temas para o bootstrap:
https://www.bootpress.org/bootstrap.html?page=2of13

414
Chat/Resource.Designer.cs generated Normal file
View File

@ -0,0 +1,414 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ChatMvc {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resource {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resource() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChatMvc.Resource", typeof(Resource).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Food and Drink.
/// </summary>
public static string BU_Alimentacao {
get {
return ResourceManager.GetString("BU_Alimentacao", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Beauty.
/// </summary>
public static string BU_Beleza {
get {
return ResourceManager.GetString("BU_Beleza", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Construction.
/// </summary>
public static string BU_Construção {
get {
return ResourceManager.GetString("BU_Construção", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Education.
/// </summary>
public static string BU_Educacao {
get {
return ResourceManager.GetString("BU_Educacao", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Green businesses.
/// </summary>
public static string BU_Empreendedorismo {
get {
return ResourceManager.GetString("BU_Empreendedorismo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Health &amp; Care.
/// </summary>
public static string BU_Saúde {
get {
return ResourceManager.GetString("BU_Saúde", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PET and Animals.
/// </summary>
public static string BU_SetorPET {
get {
return ResourceManager.GetString("BU_SetorPET", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Information tecnology.
/// </summary>
public static string BU_TI {
get {
return ResourceManager.GetString("BU_TI", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Logistics.
/// </summary>
public static string BU_TransporteLogistica {
get {
return ResourceManager.GetString("BU_TransporteLogistica", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clothes.
/// </summary>
public static string BU_Vestuário {
get {
return ResourceManager.GetString("BU_Vestuário", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Business Area.
/// </summary>
public static string BusinessAreaLabel {
get {
return ResourceManager.GetString("BusinessAreaLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enter business area.
/// </summary>
public static string BusinessAreaPlaceholder {
get {
return ResourceManager.GetString("BusinessAreaPlaceholder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Change language to find your country..
/// </summary>
public static string ChangeLanguage {
get {
return ResourceManager.GetString("ChangeLanguage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Angola.
/// </summary>
public static string Country_Angola_Label {
get {
return ResourceManager.GetString("Country_Angola_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Australia.
/// </summary>
public static string Country_Australia_Label {
get {
return ResourceManager.GetString("Country_Australia_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Brazil.
/// </summary>
public static string Country_Brasil_Label {
get {
return ResourceManager.GetString("Country_Brasil_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cabo Verde.
/// </summary>
public static string Country_CaboVerde_Label {
get {
return ResourceManager.GetString("Country_CaboVerde_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Canada.
/// </summary>
public static string Country_Canada_Label {
get {
return ResourceManager.GetString("Country_Canada_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to USA.
/// </summary>
public static string Country_EUA_Label {
get {
return ResourceManager.GetString("Country_EUA_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Philipinas.
/// </summary>
public static string Country_Filipinas_Label {
get {
return ResourceManager.GetString("Country_Filipinas_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Gana.
/// </summary>
public static string Country_Gana_Label {
get {
return ResourceManager.GetString("Country_Gana_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Guine Bissau.
/// </summary>
public static string Country_GuineBissau_Label {
get {
return ResourceManager.GetString("Country_GuineBissau_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to India.
/// </summary>
public static string Country_India_Label {
get {
return ResourceManager.GetString("Country_India_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Moçambique.
/// </summary>
public static string Country_Mocambique_Label {
get {
return ResourceManager.GetString("Country_Mocambique_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Niger.
/// </summary>
public static string Country_Nigeria_Label {
get {
return ResourceManager.GetString("Country_Nigeria_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Paquistan.
/// </summary>
public static string Country_Paquistao_Label {
get {
return ResourceManager.GetString("Country_Paquistao_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Portugal.
/// </summary>
public static string Country_Portugal_Label {
get {
return ResourceManager.GetString("Country_Portugal_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Quenia.
/// </summary>
public static string Country_Quenia_Label {
get {
return ResourceManager.GetString("Country_Quenia_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Timor Leste.
/// </summary>
public static string Country_TimorLeste_Label {
get {
return ResourceManager.GetString("Country_TimorLeste_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to United Kingdom.
/// </summary>
public static string Country_UK_Label {
get {
return ResourceManager.GetString("Country_UK_Label", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Country.
/// </summary>
public static string CountryLabel {
get {
return ResourceManager.GetString("CountryLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enter country.
/// </summary>
public static string CountryPlaceholder {
get {
return ResourceManager.GetString("CountryPlaceholder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Email.
/// </summary>
public static string EmailLabel {
get {
return ResourceManager.GetString("EmailLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Company / Group.
/// </summary>
public static string GroupNameLabel {
get {
return ResourceManager.GetString("GroupNameLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Desired group name.
/// </summary>
public static string GroupPlaceHolder {
get {
return ResourceManager.GetString("GroupPlaceHolder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Primary Data.
/// </summary>
public static string InitialFormTitle {
get {
return ResourceManager.GetString("InitialFormTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nome.
/// </summary>
public static string NameLabel {
get {
return ResourceManager.GetString("NameLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Phone number.
/// </summary>
public static string PhoneNumberLabel {
get {
return ResourceManager.GetString("PhoneNumberLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save.
/// </summary>
public static string SaveButton {
get {
return ResourceManager.GetString("SaveButton", resourceCulture);
}
}
}
}

117
Chat/Resource.pt-BR.Designer.cs generated Normal file
View File

@ -0,0 +1,117 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ChatMvc {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resource___Copy {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resource___Copy() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VCart.Resource - Copy", typeof(Resource___Copy).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string BusinessAreaLabel {
get {
return ResourceManager.GetString("BusinessAreaLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string CountryLabel {
get {
return ResourceManager.GetString("CountryLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string EmailLabel {
get {
return ResourceManager.GetString("EmailLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string GroupNameLabel {
get {
return ResourceManager.GetString("GroupNameLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string PhoneNumberLabel {
get {
return ResourceManager.GetString("PhoneNumberLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
public static string SaveButton {
get {
return ResourceManager.GetString("SaveButton", resourceCulture);
}
}
}
}

237
Chat/Resource.pt-BR.resx Normal file
View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BusinessAreaLabel" xml:space="preserve">
<value>Área de negócio</value>
</data>
<data name="BusinessAreaPlaceholder" xml:space="preserve">
<value>Area de negócio</value>
</data>
<data name="BU_Alimentacao" xml:space="preserve">
<value>Alimentacao e bebidas</value>
</data>
<data name="BU_Beleza" xml:space="preserve">
<value>Beleza</value>
</data>
<data name="BU_Construção" xml:space="preserve">
<value>Construção</value>
</data>
<data name="BU_Educacao" xml:space="preserve">
<value>Educação</value>
</data>
<data name="BU_Empreendedorismo" xml:space="preserve">
<value>Empreendedorismo verde</value>
</data>
<data name="BU_Saúde" xml:space="preserve">
<value>Saúde e bem-estar</value>
</data>
<data name="BU_SetorPET" xml:space="preserve">
<value>Setor Pet</value>
</data>
<data name="BU_TI" xml:space="preserve">
<value>Tecnologia da informação &amp; Informática</value>
</data>
<data name="BU_TransporteLogistica" xml:space="preserve">
<value>Transporte e logística</value>
</data>
<data name="BU_Vestuário" xml:space="preserve">
<value>Vestuário e calçados</value>
</data>
<data name="ChangeLanguage" xml:space="preserve">
<value>Troque o idioma para verificar seu país.</value>
</data>
<data name="CountryLabel" xml:space="preserve">
<value>País</value>
</data>
<data name="CountryPlaceholder" xml:space="preserve">
<value>Selecione seu país</value>
</data>
<data name="Country_Angola_Label" xml:space="preserve">
<value>Angola</value>
</data>
<data name="Country_Australia_Label" xml:space="preserve">
<value>Australia</value>
</data>
<data name="Country_Brasil_Label" xml:space="preserve">
<value>Brazil</value>
</data>
<data name="Country_CaboVerde_Label" xml:space="preserve">
<value>Cabo Verde</value>
</data>
<data name="Country_Canada_Label" xml:space="preserve">
<value>Canada</value>
</data>
<data name="Country_EUA_Label" xml:space="preserve">
<value>EUA</value>
</data>
<data name="Country_Filipinas_Label" xml:space="preserve">
<value>Philipinas</value>
</data>
<data name="Country_Gana_Label" xml:space="preserve">
<value>Gana</value>
</data>
<data name="Country_GuineBissau_Label" xml:space="preserve">
<value>Guine Bissau</value>
</data>
<data name="Country_India_Label" xml:space="preserve">
<value>India</value>
</data>
<data name="Country_Mocambique_Label" xml:space="preserve">
<value>Moçambique</value>
</data>
<data name="Country_Nigeria_Label" xml:space="preserve">
<value>Niger</value>
</data>
<data name="Country_Paquistao_Label" xml:space="preserve">
<value>Paquistan</value>
</data>
<data name="Country_Portugal_Label" xml:space="preserve">
<value>Portugal</value>
</data>
<data name="Country_Quenia_Label" xml:space="preserve">
<value>Quenia</value>
</data>
<data name="Country_TimorLeste_Label" xml:space="preserve">
<value>Timor Leste</value>
</data>
<data name="Country_UK_Label" xml:space="preserve">
<value>United Kingdom</value>
</data>
<data name="EmailLabel" xml:space="preserve">
<value>Email</value>
</data>
<data name="GroupNameLabel" xml:space="preserve">
<value>Nome desejado para sua bio/página</value>
</data>
<data name="GroupPlaceHolder" xml:space="preserve">
<value>Nome desejado na sua bio/página</value>
</data>
<data name="InitialFormTitle" xml:space="preserve">
<value>Dados iniciais</value>
</data>
<data name="NameLabel" xml:space="preserve">
<value>Nome</value>
</data>
<data name="PhoneNumberLabel" xml:space="preserve">
<value>Telefone</value>
</data>
<data name="SaveButton" xml:space="preserve">
<value>Gravar</value>
</data>
</root>

237
Chat/Resource.resx Normal file
View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BusinessAreaLabel" xml:space="preserve">
<value>Business Area</value>
</data>
<data name="BusinessAreaPlaceholder" xml:space="preserve">
<value>Enter business area</value>
</data>
<data name="BU_Alimentacao" xml:space="preserve">
<value>Food and Drink</value>
</data>
<data name="BU_Beleza" xml:space="preserve">
<value>Beauty</value>
</data>
<data name="BU_Construção" xml:space="preserve">
<value>Construction</value>
</data>
<data name="BU_Educacao" xml:space="preserve">
<value>Education</value>
</data>
<data name="BU_Empreendedorismo" xml:space="preserve">
<value>Green businesses</value>
</data>
<data name="BU_Saúde" xml:space="preserve">
<value>Health &amp; Care</value>
</data>
<data name="BU_SetorPET" xml:space="preserve">
<value>PET and Animals</value>
</data>
<data name="BU_TI" xml:space="preserve">
<value>Information tecnology</value>
</data>
<data name="BU_TransporteLogistica" xml:space="preserve">
<value>Logistics</value>
</data>
<data name="BU_Vestuário" xml:space="preserve">
<value>Clothes</value>
</data>
<data name="ChangeLanguage" xml:space="preserve">
<value>Change language to find your country.</value>
</data>
<data name="CountryLabel" xml:space="preserve">
<value>Country</value>
</data>
<data name="CountryPlaceholder" xml:space="preserve">
<value>Enter country</value>
</data>
<data name="Country_Angola_Label" xml:space="preserve">
<value>Angola</value>
</data>
<data name="Country_Australia_Label" xml:space="preserve">
<value>Australia</value>
</data>
<data name="Country_Brasil_Label" xml:space="preserve">
<value>Brazil</value>
</data>
<data name="Country_CaboVerde_Label" xml:space="preserve">
<value>Cabo Verde</value>
</data>
<data name="Country_Canada_Label" xml:space="preserve">
<value>Canada</value>
</data>
<data name="Country_EUA_Label" xml:space="preserve">
<value>USA</value>
</data>
<data name="Country_Filipinas_Label" xml:space="preserve">
<value>Philipinas</value>
</data>
<data name="Country_Gana_Label" xml:space="preserve">
<value>Gana</value>
</data>
<data name="Country_GuineBissau_Label" xml:space="preserve">
<value>Guine Bissau</value>
</data>
<data name="Country_India_Label" xml:space="preserve">
<value>India</value>
</data>
<data name="Country_Mocambique_Label" xml:space="preserve">
<value>Moçambique</value>
</data>
<data name="Country_Nigeria_Label" xml:space="preserve">
<value>Niger</value>
</data>
<data name="Country_Paquistao_Label" xml:space="preserve">
<value>Paquistan</value>
</data>
<data name="Country_Portugal_Label" xml:space="preserve">
<value>Portugal</value>
</data>
<data name="Country_Quenia_Label" xml:space="preserve">
<value>Quenia</value>
</data>
<data name="Country_TimorLeste_Label" xml:space="preserve">
<value>Timor Leste</value>
</data>
<data name="Country_UK_Label" xml:space="preserve">
<value>United Kingdom</value>
</data>
<data name="EmailLabel" xml:space="preserve">
<value>Email</value>
</data>
<data name="GroupNameLabel" xml:space="preserve">
<value>Company / Group</value>
</data>
<data name="GroupPlaceHolder" xml:space="preserve">
<value>Desired group name</value>
</data>
<data name="InitialFormTitle" xml:space="preserve">
<value>Primary Data</value>
</data>
<data name="NameLabel" xml:space="preserve">
<value>Nome</value>
</data>
<data name="PhoneNumberLabel" xml:space="preserve">
<value>Phone number</value>
</data>
<data name="SaveButton" xml:space="preserve">
<value>Save</value>
</data>
</root>

View File

@ -0,0 +1,192 @@
@{
ViewData["Title"] = "Chat";
}
@section Styles{
<link href="~/css/chat_index.css" rel="stylesheet" />
}
<div class="container-fluid bg-light">
<div class="row h-100">
<div class="col-md-10 mx-auto">
<div class="card shadow-sm my-4" style="background-color: #f8fff8;">
@*
<div class="card-header bg-success text-white">
<h5 class="mb-0">Chat</h5>
</div>
*@
<div class="card-body">
<div id="chat-messages" class="mb-4" style="height: 350px; overflow-y: auto;">
<!-- Mensagens serão inseridas aqui -->
</div>
<form id="chat-form" class="mt-3">
@Html.AntiForgeryToken()
<div class="input-group">
<textarea id="message-input" class="form-control"
placeholder="Digite sua mensagem... Use **texto** para negrito"
rows="3" required></textarea>
<button type="button" class="btn btn-success" id="send-message">
Enviar
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@section Scripts {
<script>
const firstName = '@User.FindFirst("FirstName")';
const name = firstName.split(':')[1];
const id = name + '_Web';
const company = 'Domvs iT';
const baseUrl = window.location.origin;
var token = '';
// Aguarda todos os recursos serem carregados
window.addEventListener('load', async function () {
const userId = 1;
const chatMessages = $('#chat-messages');
const messageInput = $('#message-input');
const chatForm = $('#chat-form');
token = await autenticar(id, company, name);
// Configuração do Marked
marked.setOptions({
breaks: true,
gfm: true
});
const msgInit = `Olá! Eu sou uma IA desenvolvida para atuar internamente na Domvs iT. Você pode:
- Fazer perguntas sobre os serviços da Domvs iT
- Abrir uma solicitação ao RH no Pipefy
- Ou simplesmente perguntar qualquer coisa.
Use **negrito** para destacar texto importante.
Para código, use \\\`\\\`\\\`linguagem
seu código
\\\`\\\`\\\``;
function appendMessage(message, isUser = true) {
const messageDiv = $('<div>').addClass('chat-message ' + (isUser ? 'user-message' : 'bot-message'));
const messageContent = $('<div>').addClass('message-bubble');
try {
const htmlContent = marked(message);
const cleanHtml = DOMPurify.sanitize(htmlContent);
messageContent.html(cleanHtml);
} catch (error) {
console.error('Erro ao processar mensagem:', error);
messageContent.text(message);
}
messageDiv.append(messageContent);
chatMessages.append(messageDiv);
chatMessages.scrollTop(chatMessages[0].scrollHeight);
// Highlight de código
Prism.highlightAllUnder(messageDiv[0]);
}
function appendMessageX(message, isUser = true) {
const messageDiv = $('<div>').addClass('mb-3');
const messageContent = $('<div>')
.addClass('p-3 rounded-3')
.css({
'max-width': '90%',
'display': 'inline-block',
'white-space': 'pre-wrap',
'word-wrap': 'break-word'
});
if (isUser) {
messageDiv.addClass('text-end');
messageContent
.addClass('bg-success text-white')
.css('float', 'right');
} else {
messageContent
.addClass('bg-light border')
.css('float', 'left');
}
try {
const htmlContent = marked(message);
const cleanHtml = DOMPurify.sanitize(htmlContent);
messageContent.html(cleanHtml);
} catch (error) {
console.error('Erro ao processar mensagem:', error);
messageContent.text(message);
}
messageDiv.append(messageContent);
chatMessages.append(messageDiv);
chatMessages.scrollTop(chatMessages[0].scrollHeight);
// Highlight de código
Prism.highlightAllUnder(messageDiv[0]);
}
// Exibe mensagem inicial
appendMessage(msgInit, false);
$('#send-message').on('click', function (e) {
e.preventDefault();
const message = messageInput.val().trim();
if (!message) return;
appendMessage(message);
messageInput.val('');
$.ajax({
url: baseUrl + '/chat/proxy-response', // Novo endpoint no controller
type: 'GET',
headers: {
"X-CSRF-TOKEN": $('input[name="__RequestVerificationToken"]').val(),
'Authorization': 'Bearer ' + token
},
data: {
sessionId: id,
message: message
},
success: function (response) {
appendMessage(response, false);
},
error: function (xhr, status, error) {
console.error('Erro na requisição do cliente:', error);
console.error('Status:', xhr.status);
console.error('Response:', xhr.responseText);
appendMessage('Erro ao processar cliente: ' + error, false);
}
});
});
async function autenticar(userId, company, name) {
try {
// Agora fazemos apenas uma requisição para o novo endpoint
const response = await $.ajax({
url: baseUrl + '/chat/authenticate',
type: 'POST',
headers: {
"X-CSRF-TOKEN": $('input[name="__RequestVerificationToken"]').val()
},
contentType: 'application/json',
data: JSON.stringify({
userId: userId,
company: company,
name: name
})
});
return response.token;
} catch (error) {
appendMessage('Erro ao processar mensagem: ' + error, false);
throw error;
}
}
});
</script>
}

View File

@ -0,0 +1,171 @@
@{
ViewData["Title"] = "Home Page";
}
@section Scripts {
<script type="text/javascript">
$(document).ready(function(){
var clickEvent = false;
$('#myCarousel').carousel({
interval: 4000
}).on('click', '.list-group li', function() {
clickEvent = true;
$('.list-group li').removeClass('active');
$(this).addClass('active');
}).on('slid.bs.carousel', function(e) {
if(!clickEvent) {
var count = $('.list-group').children().length -1;
var current = $('.list-group li.active');
current.removeClass('active').next().addClass('active');
var id = parseInt(current.data('slide-to'));
if(count == id) {
$('.list-group li').first().addClass('active');
}
}
clickEvent = false;
});
})
$(window).on('load', function () {
// var boxheight = $('#myCarousel .carousel-inner').innerHeight();
// var itemlength = $('#myCarousel .item').length;
// var triggerheight = Math.round(boxheight/itemlength+1);
// $('#myCarousel .list-group-item').outerHeight(triggerheight);
setTriggerHeight();
});
$(window).on('resize', function () {
setTriggerHeight();
});
// $(window).load(function () {
// setTriggerHeight();
// });
function setTriggerHeight() {
var boxheight = $('#myCarousel .carousel-inner').innerHeight();
var itemlength = $('#myCarousel .item').length;
var triggerheight = Math.round(boxheight / itemlength + 81);
$('#myCarousel .list-group-item').outerHeight(triggerheight);
}
</script>
}
<div>
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="http://placehold.it/760x400/cccccc/ffffff">
<div class="carousel-caption">
<h4><a href="#">Lorem ipsum dolor sit amet consetetur sadipscing</a></h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. <a class="label label-primary" href="http://sevenx.de/demo/bootstrap-carousel/" target="_blank">Free Bootstrap Carousel Collection</a></p>
</div>
</div><!-- End Item -->
<div class="item">
<img src="http://placehold.it/760x400/999999/cccccc">
<div class="carousel-caption">
<h4><a href="#">consetetur sadipscing elitr, sed diam nonumy eirmod</a></h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. <a class="label label-primary" href="http://sevenx.de/demo/bootstrap-carousel/" target="_blank">Free Bootstrap Carousel Collection</a></p>
</div>
</div><!-- End Item -->
<div class="item">
<img src="http://placehold.it/760x400/dddddd/333333">
<div class="carousel-caption">
<h4><a href="#">tempor invidunt ut labore et dolore</a></h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. <a class="label label-primary" href="http://sevenx.de/demo/bootstrap-carousel/" target="_blank">Free Bootstrap Carousel Collection</a></p>
</div>
</div><!-- End Item -->
<div class="item">
<img src="http://placehold.it/760x400/999999/cccccc">
<div class="carousel-caption">
<h4><a href="#">magna aliquyam erat, sed diam voluptua</a></h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. <a class="label label-primary" href="http://sevenx.de/demo/bootstrap-carousel/" target="_blank">Free Bootstrap Carousel Collection</a></p>
</div>
</div><!-- End Item -->
<div class="item">
<img src="http://placehold.it/760x400/dddddd/333333">
<div class="carousel-caption">
<h4><a href="#">tempor invidunt ut labore et dolore magna aliquyam erat</a></h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. <a class="label label-primary" href="http://sevenx.de/demo/bootstrap-carousel/" target="_blank">Free Bootstrap Carousel Collection</a></p>
</div>
</div><!-- End Item -->
</div><!-- End Carousel Inner -->
<ul class="list-group col-sm-4">
<li data-target="#myCarousel" data-slide-to="0" class="list-group-item active"><h4>Lorem ipsum dolor sit amet consetetur sadipscing</h4></li>
<li data-target="#myCarousel" data-slide-to="1" class="list-group-item"><h4>consetetur sadipscing elitr, sed diam nonumy eirmod</h4></li>
<li data-target="#myCarousel" data-slide-to="2" class="list-group-item"><h4>tempor invidunt ut labore et dolore</h4></li>
<li data-target="#myCarousel" data-slide-to="3" class="list-group-item"><h4>magna aliquyam erat, sed diam voluptua</h4></li>
<li data-target="#myCarousel" data-slide-to="4" class="list-group-item"><h4>tempor invidunt ut labore et dolore magna aliquyam erat</h4></li>
</ul>
<!-- Controls -->
<div class="carousel-controls">
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</div><!-- End Carousel -->
</div>
@section Styles {
<style>
body { padding-top: 50px; }
#myCarousel .carousel-caption {
left:0;
right:0;
bottom:0;
text-align:left;
padding:10px;
background:rgba(0,0,0,0.6);
text-shadow:none;
}
#myCarousel .list-group {
position:absolute;
top:0;
right:0;
}
#myCarousel .list-group-item {
border-radius:0px;
cursor:pointer;
}
#myCarousel .list-group .active {
background-color:#eee;
}
#myCarousel .item {
height: 50px;
}
@@media (min-width: 992px) {
#myCarousel {padding-right:33.3333%;}
#myCarousel .carousel-controls {display:none;}
}
@@media (max-width: 991px) {
.carousel-caption p,
#myCarousel .list-group {display:none;}
}
</style>
}

View File

@ -0,0 +1,80 @@
@{
ViewData["Title"] = "Home Page";
}
@section Scripts {
<script type="text/javascript">
</script>
}
@section Styles {
<link href="~/css/home_index.css" rel="stylesheet" />
<style type="text/css">
.text-responsive {
font-size: calc(100% + 1vw + 1vh);
}
</style>
}
<div class="div-body">
<div class="container">
<div id="myCarousel" class="carousel slide" data-ride="carousel" style="min-height: 500px">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
<li data-target="#myCarousel" data-slide-to="3"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="carousel-item active">
<img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
<div class="container">
<div class="carousel-caption d-md-block text-left">
<h1 class="text-responsive">Example headline.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a></p>
</div>
</div>
</div>
<div class="carousel-item">
<img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
<div class="container">
<div class="carousel-caption d-md-block">
<h1 class="text-responsive">Another example headline.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a></p>
</div>
</div>
</div>
<div class="carousel-item">
<img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
<div class="container">
<div class="carousel-caption d-md-block text-right">
<h1 class="text-responsive">One more for good measure.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a></p>
</div>
</div>
</div>
<div class="carousel-item">
<img class="fourth-slide" src="/img/teste1.png" alt="Fourth slide">
<div class="container">
<div class="carousel-caption d-md-block text-right text-dark">
<h1 class="text-responsive">One more for good measure.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a></p>
</div>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Anterior</span>
</a>
<a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Próximo</span>
</a>
</div>
</div>
</div>

View File

@ -0,0 +1,102 @@
.btn-primary {
background-color: darkgreen;
color: white;
}
.btn-red {
background-color: darkred;
color: white;
}
.div-body {
padding-top: 3rem;
padding-bottom: 3rem;
color: #5a5a5a;
}
.bg-inverse {
background-color: #292b2c !important;
}
/* CUSTOMIZE THE CAROUSEL
-------------------------------------------------- */
/* Carousel base class */
.carousel {
margin-bottom: 4rem;
}
/* Since positioning the image, we need to help out the caption */
.carousel-caption {
z-index: 10;
bottom: 3rem;
}
/* Declare heights because of positioning of img element */
.carousel-item {
height: 32rem;
background-color: #777;
}
.carousel-item > img {
position: absolute;
top: 0;
left: 0;
min-width: 100%;
height: 32rem;
}
/* MARKETING CONTENT
-------------------------------------------------- */
/* Center align the text within the three columns below the carousel */
.marketing .col-lg-4 {
margin-bottom: 1.5rem;
text-align: center;
}
.marketing h2 {
font-weight: normal;
}
.marketing .col-lg-4 p {
margin-right: .75rem;
margin-left: .75rem;
}
/* Featurettes
------------------------- */
.featurette-divider {
margin: 5rem 0; /* Space out the Bootstrap <hr> more */
}
/* Thin out the marketing headings */
.featurette-heading {
font-weight: 300;
line-height: 1;
letter-spacing: -.05rem;
}
/* RESPONSIVE CSS
-------------------------------------------------- */
@media (min-width: 40em) {
/* Bump up size of carousel content */
.carousel-caption p {
margin-bottom: 1.25rem;
font-size: 1.25rem;
line-height: 1.4;
}
.featurette-heading {
font-size: 50px;
}
}
@media (min-width: 62em) {
.featurette-heading {
margin-top: 7rem;
}
}

View File

@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

@ -0,0 +1,56 @@
@{
ViewBag.Title = "Login";
}
<div class="container">
<div class="row justify-content-center align-items-center min-vh-100">
<div class="col-md-6">
<div class="card shadow-lg">
<div class="card-body text-center p-5">
<h2 class="card-title mb-4">Bem-vindo</h2>
<p class="card-text text-muted mb-4">
Faça login com sua conta Microsoft para acessar o chat.
</p>
@using (Html.BeginForm("ExternalLogin", "Login", new { provider = "Microsoft" }, FormMethod.Post, true, new { id = "externalLoginForm" }))
{
@Html.AntiForgeryToken()
<button type="submit" class="btn btn-primary btn-lg w-75">
<i class="fab fa-microsoft mr-2"></i>
Login with Microsoft
</button>
}
</div>
</div>
</div>
</div>
</div>
@section Styles {
<style>
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.card {
border: none;
border-radius: 15px;
}
.btn-primary {
background-color: #2f2f2f;
border: none;
padding: 12px;
transition: all 0.3s;
}
.btn-primary:hover {
background-color: #404040;
transform: translateY(-2px);
}
</style>
}
@section Scripts {
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
}

View File

@ -0,0 +1,45 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
@section Scripts {
<script src="https://js.stripe.com/v3/"></script>
<script>
// This is your test secret API key.
const stripe = Stripe("pk_test_51PvIzkBk8jHwC3c0efDBJMY9dBwNqs0SDAHP0vIQr17G9iYg4GQtIrCOh2N9teJoYDXUHTWe6iEHnUylMntwhbin00R7y6lQOV");
initialize();
// Create a Checkout Session
async function initialize() {
const payPlan = get('plan');
const fetchClientSecret = async () => {
const response = await fetch("/Pay/create" + payPlan, {
method: "POST",
});
const { clientSecret } = await response.json();
return clientSecret;
};
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret,
});
// Mount Checkout
checkout.mount('#checkout');
}
function get(name) {
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search))
return decodeURIComponent(name[1]);
}
</script>
}
<br />
<br />
<div id="checkout">
<!-- Checkout will insert the payment form here -->
</div>

View File

@ -0,0 +1,109 @@
@{
ViewBag.Title = "Planos";
}
<div class="row db-padding-btm db-attached">
<div class="col-4 col-xs-4 col-sm-4 col-md-4 col-lg-4">
<div class="db-wrapper">
<div class="db-pricing-eleven db-bk-color-one">
<div class="price text-price-responsive">
<sup>R$</sup> 0,00
<small>para sempre!</small>
</div>
<div class="type text-type-responsive">
Básico
</div>
<ul class="text-responsive">
<li><i class="bi bi-plus-square-fill text-success"></i>1 Bio/Links <span class="hide-in-cell">pessoal virtual</span></li>
<li><i class="bi bi-plus-square-fill text-success"></i><span class="hide-in-cell">Exibir imagem </span>Whatsapp *</li>
<li><i class="bi bi-plus-square-fill text-success"></i>Até 3 links </li>
<li><i class="bi bi-square text-success"></i><span class="hide-in-cell">Sem página de</span> Produtos</li>
<li><i class="bi bi-square text-success"></i><span class="hide-in-cell">Sem contador de </span>Visualizações</span></li>
</ul>
<div class="pricing-footer">
@if (User.Identity.IsAuthenticated)
{
<div class="btn db-button-color-square btn-lg">Plano Inicial</div>
}
else
{
<div class="btn db-button-color-square btn-lg">Comece com este!</div>
}
</div>
</div>
</div>
</div>
<div class="col-4 col-xs-4 col-sm-4 col-md-4 col-lg-4">
<div class="db-wrapper">
<div class="db-pricing-eleven db-bk-color-two popular">
<div class="price text-price-responsive">
<sup>R$</sup>13
<small>por mês</small>
</div>
<div class="type text-type-responsive">
BIO
</div>
<ul>
<li><i class="bi bi-plus-square-fill text-success"></i>1 Bio/Links <span class="hide-in-cell">pessoal virtual</span></li>
<li><i class="bi bi-plus-square-fill text-success"></i><span class="hide-in-cell">Exibir cartão </span>Whatsapp *</li>
<li><i class="bi bi-plus-square-fill text-success"></i>100 links</li>
<li><i class="bi bi-square text-success"></i><span class="hide-in-cell">Sem página de</span> Produtos</li>
@*
<li><i class="bi bi-plus-square-fill text-success"></i>1 Link agendado **</li>
*@
<li><i class="bi bi-square text-success"></i><span class="hide-in-cell">Contador de</span> Visualizações</li>
@*
<li><i class="bi bi-square text-success"></i><span class="hide-in-cell">Registro de contatos</span> </li>
*@
</ul>
<div class="pricing-footer">
@if (User.Identity.IsAuthenticated)
{
<a href="/Pay/?plan=bio" class="btn db-button-color-square btn-lg">Assinar</a>
}
else
{
<a href="/Login" class="btn db-button-color-square btn-lg">Login / Registro</a>
}
</div>
</div>
</div>
</div>
<div class="col-4 col-xs-4 col-sm-4 col-md-4 col-lg-4">
<div class="db-wrapper">
<div class="db-pricing-eleven db-bk-color-three">
<div class="price text-price-responsive">
<sup>R$</sup>27
<small>por mês</small>
</div>
<div class="type text-type-responsive">
CATÁLOGO
</div>
<ul>
<li><i class="bi bi-plus-square-fill text-success"></i>1 Bio/Cartão <span class="hide-in-cell">pessoal virtual</span></li>
<li><i class="bi bi-plus-square-fill text-success"></i><span class="hide-in-cell">Exibir cartão </span>Whatsapp *</li>
<li><i class="bi bi-plus-square-fill text-success"></i>Sem limite de links </li>
<li><i class="bi bi-plus-square-fill text-success"></i>Links de Produtos</li>
<li><i class="bi bi-plus-square-fill text-success"></i>Contador<span class="hide-in-cell"> de visualizações</span> </li>
@*
<li><i class="bi bi-plus-square-fill text-success"></i><span class="hide-in-cell">Registro de contatos</span> </li>
*@
</ul>
<div class="pricing-footer">
@if (User.Identity.IsAuthenticated)
{
<button type="button" class="btn db-button-color-square btn-lg" onclick="waitingDialog.show('Custom message');window.location.href = '/Pay/?plan=catalogo';">Assinar</button>
@*
<a href="/Pay/?plan=catalogo" class="btn db-button-color-square btn-lg">Assinar</a>
*@
}
else
{
<a href="/Login" class="btn db-button-color-square btn-lg">Login / Registro</a>
}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,225 @@
/*=============================================================
Authour URL: www.designbootstrap.com
http://www.designbootstrap.com/
License: MIT
======================================================== */
/*============================================================
BACKGROUND COLORS
============================================================*/
.db-bk-color-one {
background-color: #D9EDD2;
}
.db-bk-color-two {
background-color: #B9CEA0;
}
.db-bk-color-three {
background-color: #D9EDD2;
}
.db-bk-color-six {
background-color: #F59B24;
}
.db-padding-btm {
padding-bottom: 50px;
}
.db-button-color-square {
color: #fff;
background-color: rgba(0, 0, 0, 0.50);
border: none;
border-radius: 0px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
}
.db-button-color-square:hover {
color: #fff;
background-color: rgba(0, 0, 0, 0.50);
border: none;
}
.db-pricing-eleven {
margin-bottom: 30px;
margin-top: 50px;
text-align: center;
box-shadow: 0 0 5px rgba(0, 0, 0, .5);
border-radius: 7px 7px 7px 7px;
color: #101211;
line-height: 30px;
}
.db-pricing-eleven ul {
list-style: none;
margin: 0;
text-align: left;
padding-left: 5px;
}
.db-pricing-eleven ul li {
padding-top: 20px;
padding-bottom: 20px;
cursor: pointer;
}
.db-pricing-eleven ul li i {
margin-right: 5px;
}
.db-pricing-eleven .price {
background-color: rgba(0, 0, 0, 0);
color: #353000;
}
.db-pricing-eleven .price small {
color: #63783F;
display: block;
font-size: 12px;
margin-top: 22px;
}
.db-pricing-eleven .type {
background-color: #63783F;
padding: 50px 20px;
font-weight: 900;
text-transform: uppercase;
}
.text-price-responsive {
font-size: 30px;
padding: 20px 10px 10px 10px;
font-weight: 500;
}
.text-type-responsive {
color: white;
font-size: 20px;
}
.text-responsive {
font-size: 16px;
}
.hide-in-cell {
display: none
}
@media (min-width: 544px) {
.db-pricing-eleven ul {
list-style: none;
margin: 0;
text-align: left;
padding-left: 5px;
}
.text-price-responsive {
font-size: 30px;
padding: 20px 10px 10px 10px;
font-weight: 500;
}
.text-type-responsive {
font-size: 30px;
color: white;
}
.text-responsive {
font-size: 16px;
}
.hide-in-cell {
display: none
}
}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) {
.text-price-responsive {
padding: 40px 20px 20px 20px;
font-size: 40px;
}
.text-type-responsive {
font-size: 30px;
color: white;
}
.text-responsive {
font-size: 20px;
}
}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) {
.text-price-responsive {
padding: 40px 20px 20px 20px;
font-size: 60px;
}
.text-type-responsive {
font-size: 30px;
color: white;
}
.text-responsive {
font-size: 20px;
}
}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
.db-pricing-eleven ul {
list-style: none;
margin: 0;
text-align: left;
padding-left: 20px;
}
.text-price-responsive {
padding: 40px 20px 20px 20px;
font-size: 60px;
}
.text-type-responsive {
color: white;
font-size: 30px;
}
.text-responsive {
font-size: 16px;
}
.hide-in-cell {
display: inline
}
}
.db-pricing-eleven .pricing-footer {
padding: 20px;
}
.db-attached > .col-lg-4,
.db-attached > .col-lg-3,
.db-attached > .col-md-4,
.db-attached > .col-md-3,
.db-attached > .col-sm-4,
.db-attached > .col-sm-3 {
padding-left: 0;
padding-right: 0;
}
.db-pricing-eleven.popular {
margin-top: 10px;
}
.db-pricing-eleven.popular .price {
padding-top: 80px;
}

View File

@ -0,0 +1,10 @@
@model ChangeViewModel
@{
ViewBag.Title = "OrederStatus";
}
<h2>Order Status</h2>
<p>@ViewBag.Status</p>
<h4>Email</h4>
<p>@ViewBag.Email</p>

View File

@ -0,0 +1,77 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
@section Scripts {
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe = Stripe('Your Secret key');
var elements = stripe.elements();
var style = {
base: {
fontSize: '16px',
color: '#32325d',
},
};
var card = elements.create('card', { style: style });
card.mount('#card-element');
var form = document.getElementById('payment-form');
form.addEventListener('submit', function (event) {
event.preventDefault();
stripe.createToken(card).then(function (result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
stripeTokenHandler(result.token);
}
});
});
function stripeTokenHandler(token) {
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
form.submit();
}
</script>
}
<form action="/cart/Create" method="post" id="payment-form">
<div class="col-sm-6">
<div class="panel panel-success">
<div class="panel-heading">
Credit Card Information
</div>
<div class="panel-body">
<div class="form-horizontal">
<div class="form-group">
<div class="col-sm-8">
<input type="number" class="form-control" name="Amount" placeholder="Amount" required />
</div>
</div>
<div class="form-group">
<div class="col-sm-8">
<input type="text" class="form-control" name="Currency" value="INR" readonly />
</div>
</div>
<div class="form-group">
<div class="col-sm-8">
<input type="text" class="form-control" name="Description" placeholder="Description" required />
</div>
</div>
<div id="card-element">
</div>
<div id="card-errors" role="alert"></div>
</div>
<br />
<input type="submit" value="Submit Payment" />
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,44 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
@section Scripts {
<script src="https://js.stripe.com/v3/"></script>
<script>
// This is your test secret API key.
const stripe = Stripe("pk_test_51PvIzkBk8jHwC3c0efDBJMY9dBwNqs0SDAHP0vIQr17G9iYg4GQtIrCOh2N9teJoYDXUHTWe6iEHnUylMntwhbin00R7y6lQOV");
initialize();
// Create a Checkout Session
async function initialize() {
const payPlan = get('plan');
const fetchClientSecret = async () => {
const response = await fetch("/Pay" + payPlan, {
method: "POST",
});
const { clientSecret } = await response.json();
return clientSecret;
};
const checkout = await stripe.initEmbeddedCheckout({
fetchClientSecret,
});
// Mount Checkout
checkout.mount('#checkout');
}
function get(name) {
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search))
return decodeURIComponent(name[1]);
}
</script>
}
<div id="checkout">
<!-- Checkout will insert the payment form here -->
</div>

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,13 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<div class="loading">
<div class="d-flex justify-content-center">
<div class="spinner-border text-success" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<li class="nav-item dropdown" style="display: none">
<a class="nav-link text-white dropdown-toggle" href="#" id="languageDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="bi bi-book"></i>&nbsp;&nbsp;Idioma - @Context.Request.Cookies["Language"]
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="languageDropdown">
<a class="dropdown-item" asp-controller="Language" asp-action="ChangeLanguage" asp-route-lang="en">English</a>
<a class="dropdown-item" asp-controller="Language" asp-action="ChangeLanguage" asp-route-lang="pt-BR">Português</a>
</div>
</li>

View File

@ -0,0 +1,202 @@
@using System.Security.Claims
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Chat</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
@* <link rel="stylesheet" href="~/ChatMvc.styles.css" asp-append-version="true" />
*@
<link rel="stylesheet" href="~/css/layout.css" asp-append-version="true" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
@await RenderSectionAsync("Styles", required: false)
</head>
<body class="hide-body">
<partial name="_Busy" />
<div id="wrapper">
<nav id="nav-bar" class="navbar navbar-expand-lg navbar-dark">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Chat IA</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
@*
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Plans" asp-action="Index">Planos</a>
</li>
*@
@if (User!=null && User.Identity!=null && User.Identity.IsAuthenticated)
{
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Chat" asp-action="Index">Chat</a>
</li>
}
</ul>
@if (User!=null && User.Identity!=null && !User.Identity.IsAuthenticated)
{
<ul class="navbar-nav ml-auto">
<partial name="_Language" />
<li class="nav-item" style="margin-right: 10px">
<a class="nav-link text-white" asp-area="" asp-controller="Login" asp-action="Index"><i class="bi bi-person"></i> Login</a>
</li>
</ul>
}
else
{
<ul class="navbar-nav ml-auto">
<partial name="_Language"/>
<li class="nav-item dropdown" style="margin-right: 10px">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="bi bi-person"></i> @(User.FindFirst("FirstName") != null ? User.FindFirst("FirstName").Value : "N/A")
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" asp-area="" asp-controller="Login" asp-action="Logout">Sair</a>
@*
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
*@
</div>
</li>
@*
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Login" asp-action="Logout">@User.FindFirst("FullName").Value
</a>
</li>
*@
</ul>
}
</div>
</nav>
<div class="container">
@RenderBody()
@*
<main role="main" class="pb-3">
</main>
*@
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - Chat IA - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/js/wait.js" asp-append-version="true"></script>
<script type="text/javascript">
$(function () {
$(document).ready(function () {
$('.loading').hide();
//$('body').fadeIn(1000);
$('body').slideDown('slow');
});
$('a[href="#search"]').on('click', function (event) {
event.preventDefault();
$('#search').addClass('open');
$('#search > form > input[type="search"]').focus();
inactivateActiveOption();
searchActive();
});
$('#search, #search button.close').on('click keyup', function (event) {
if (event.target == this || event.target.className == 'close' || event.keyCode == 27) {
$(this).removeClass('open');
setActiveByLocation();
searchInactive();
}
});
$(window).on('beforeunload', function () {
displayBusyIndicator();
});
$(document).on('submit', 'form', function () {
displayBusyIndicator();
});
$(document).ready(function () {
$('#wrapper').fadeIn('slow');
$('a.nav-link').click(function () {
$('#wrapper').fadeOut('slow');
});
setActiveByLocation();
});
function setActiveByLocation() {
$('ul.navbar-nav').find('a[href="' + location.pathname + '"]')
.closest('li')
.addClass("active")
$('ul.navbar-nav').find('a[href="' + location.pathname + '"]')
.closest('a')
.removeClass('text-white')
.addClass('text-black');
}
function searchActive() {
$('#searchLi').addClass("active");
$('#searchLi > a')
.removeClass('text-white')
.addClass('text-black');
}
function searchInactive() {
$('#searchLi').removeClass("active");
$('#searchLi > a')
.removeClass('text-black')
.addClass('text-white');
}
function inactivateActiveOption() {
$('ul.navbar-nav li.active')
.closest('li')
.removeClass("active")
$('ul.navbar-nav').find('a[href="' + location.pathname + '"]')
.closest('a')
.removeClass('text-black')
.addClass('text-white');
}
function displayBusyIndicator() {
//$('body').fadeOut(1000);
$('body').slideUp('slow');
}
//$(".hide-body").fadeOut(2000);
});
</script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,82 @@
/* Color palette variables */
:root {
--primary-green: #2E7D32; /* Darker green for headers */
--secondary-green: #43A047; /* Slightly lighter green for interactive elements */
--light-green: #C8E6C9; /* Very light green for backgrounds */
--hover-green: #1B5E20; /* Darker green for hover states */
--accent-green: #81C784; /* Medium green for accents */
--bg-light: #F1F8E9; /* Super light green for main background */
}
/* Navbar styling */
#nav-bar {
background-color: var(--primary-green) !important;
}
/* Button primary override */
.btn-primary, .btn-success {
background-color: var(--secondary-green) !important;
border-color: var(--secondary-green) !important;
}
.btn-primary:hover, .btn-success:hover {
background-color: var(--hover-green) !important;
border-color: var(--hover-green) !important;
}
/* Chat card styling */
.card {
background-color: var(--bg-light) !important;
border: none;
}
.card-header {
background-color: var(--primary-green) !important;
}
/* Message bubbles */
.chat-message-user {
background-color: var(--secondary-green) !important;
color: white;
border-radius: 15px 15px 0 15px !important;
}
.chat-message-bot {
background-color: white !important;
border: 1px solid var(--light-green) !important;
color: #333;
border-radius: 15px 15px 15px 0 !important;
}
/* Input group styling */
.input-group .form-control {
border: 1px solid var(--light-green);
}
.input-group .form-control:focus {
border-color: var(--accent-green);
box-shadow: 0 0 0 0.2rem rgba(67, 160, 71, 0.25);
}
/* Navbar active state */
.navbar .navbar-collapse ul.navbar-nav .nav-item.active {
background-color: var(--accent-green) !important;
}
/* Custom scrollbar for chat messages */
#chat-messages::-webkit-scrollbar {
width: 8px;
}
#chat-messages::-webkit-scrollbar-track {
background: var(--bg-light);
}
#chat-messages::-webkit-scrollbar-thumb {
background: var(--accent-green);
border-radius: 4px;
}
#chat-messages::-webkit-scrollbar-thumb:hover {
background: var(--secondary-green);
}

View File

@ -0,0 +1,182 @@
@using System.Security.Claims
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Chat</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/css/layout.css" asp-append-version="true" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<style>
#wrapper {
opacity: 1;
transition: opacity 0.3s ease-in-out;
display: block;
}
#wrapper.fade-out {
opacity: 0;
}
.loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading .spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
body {
display: block;
}
</style>
@await RenderSectionAsync("Styles", required: false)
</head>
<body>
<partial name="_Busy" />
<div id="wrapper">
<nav id="nav-bar" class="navbar navbar-expand-lg navbar-dark">
<!-- Seu código de navegação existente -->
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Chat IA</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
@if (User!=null && User.Identity!=null && User.Identity.IsAuthenticated)
{
<li class="nav-item">
<a class="nav-link text-white" asp-area="" asp-controller="Chat" asp-action="Index">Chat</a>
</li>
}
</ul>
@if (User!=null && User.Identity!=null && !User.Identity.IsAuthenticated)
{
<ul class="navbar-nav ml-auto">
<partial name="_Language" />
<li class="nav-item" style="margin-right: 10px">
<a class="nav-link text-white" asp-area="" asp-controller="Login" asp-action="Index"><i class="bi bi-person"></i> Login</a>
</li>
</ul>
}
else
{
<ul class="navbar-nav ml-auto">
<partial name="_Language"/>
<li class="nav-item dropdown" style="margin-right: 10px">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="bi bi-person"></i> @(User.FindFirst("FirstName") != null ? User.FindFirst("FirstName").Value : "N/A")
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" asp-area="" asp-controller="Login" asp-action="Logout">Sair</a>
</div>
</li>
</ul>
}
</div>
</nav>
<div class="container">
@RenderBody()
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - Chat IA - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
<script src="~/js/wait.js" asp-append-version="true"></script>
<script type="text/javascript">
$(function () {
// Esconde o loading inicial
$('.loading').hide();
$('#wrapper').show();
// Intercepta cliques em links
$('a:not([target="_blank"]):not([href^="#"]):not([href^="javascript"])').click(function(e) {
if (this.hostname === window.location.hostname) {
e.preventDefault();
const href = $(this).attr('href');
// Adiciona fade out
$('#wrapper').addClass('fade-out');
$('.loading').show();
// Navega após a animação
setTimeout(() => {
window.location.href = href;
}, 300);
}
});
// Gerencia estado ativo dos links
function setActiveByLocation() {
$('ul.navbar-nav').find('a[href="' + location.pathname + '"]')
.closest('li')
.addClass("active")
.find('a')
.removeClass('text-white')
.addClass('text-black');
}
// Remove fade-out quando a página carrega
$(window).on('pageshow', function() {
$('#wrapper').removeClass('fade-out');
$('.loading').hide();
setActiveByLocation();
});
// Gerencia submissão de formulários
$(document).on('submit', 'form', function () {
$('#wrapper').addClass('fade-out');
$('.loading').show();
});
// Configuração inicial
setActiveByLocation();
});
</script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,82 @@
/* Color palette variables */
:root {
--primary-green: #2E7D32; /* Darker green for headers */
--secondary-green: #43A047; /* Slightly lighter green for interactive elements */
--light-green: #C8E6C9; /* Very light green for backgrounds */
--hover-green: #1B5E20; /* Darker green for hover states */
--accent-green: #81C784; /* Medium green for accents */
--bg-light: #F1F8E9; /* Super light green for main background */
}
/* Navbar styling */
#nav-bar {
background-color: var(--primary-green) !important;
}
/* Button primary override */
.btn-primary, .btn-success {
background-color: var(--secondary-green) !important;
border-color: var(--secondary-green) !important;
}
.btn-primary:hover, .btn-success:hover {
background-color: var(--hover-green) !important;
border-color: var(--hover-green) !important;
}
/* Chat card styling */
.card {
background-color: var(--bg-light) !important;
border: none;
}
.card-header {
background-color: var(--primary-green) !important;
}
/* Message bubbles */
.chat-message-user {
background-color: var(--secondary-green) !important;
color: white;
border-radius: 15px 15px 0 15px !important;
}
.chat-message-bot {
background-color: white !important;
border: 1px solid var(--light-green) !important;
color: #333;
border-radius: 15px 15px 15px 0 !important;
}
/* Input group styling */
.input-group .form-control {
border: 1px solid var(--light-green);
}
.input-group .form-control:focus {
border-color: var(--accent-green);
box-shadow: 0 0 0 0.2rem rgba(67, 160, 71, 0.25);
}
/* Navbar active state */
.navbar .navbar-collapse ul.navbar-nav .nav-item.active {
background-color: var(--accent-green) !important;
}
/* Custom scrollbar for chat messages */
#chat-messages::-webkit-scrollbar {
width: 8px;
}
#chat-messages::-webkit-scrollbar-track {
background: var(--bg-light);
}
#chat-messages::-webkit-scrollbar-thumb {
background: var(--accent-green);
border-radius: 4px;
}
#chat-messages::-webkit-scrollbar-thumb:hover {
background: var(--secondary-green);
}

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

@ -0,0 +1,159 @@

@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
Layout = "";
}
<!DOCTYPE html>
<html>
<head>
<title>Blinks</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" integrity="sha384-gfdkjb5BdAXd+lj+gudLWI+BXq4IuLW5IT+brZEZsLFm++aCMlF1V92rMkPaX4PP" crossorigin="anonymous">
<style>
/* Coded with love by Mutiullah Samim */
body,
html {
margin: 0;
padding: 0;
height: 100%;
background: #C5ACD3 !important;
}
.user_card {
height: 400px;
width: 350px;
margin-top: auto;
margin-bottom: auto;
background: #C1DD89;
position: relative;
display: flex;
justify-content: center;
flex-direction: column;
padding: 10px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
-webkit-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
-moz-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border-radius: 5px;
}
.brand_logo_container {
position: absolute;
height: 170px;
width: 170px;
top: -75px;
border-radius: 50%;
background: #C5ACD3;
padding: 10px;
text-align: center;
}
.brand_logo {
height: 150px;
width: 150px;
border-radius: 50%;
/* border: 2px solid white;
*/ }
.form_container {
margin-top: 100px;
}
.login_btn {
width: 100%;
background: darkgreen !important;
color: white !important;
}
.login_btn:focus {
box-shadow: none !important;
outline: 0px !important;
}
.login_container {
padding: 0 2rem;
}
.input-group-text {
background: darkgreen !important;
color: white !important;
border: 0 !important;
border-radius: 0.25rem 0 0 0.25rem !important;
}
.input_user,
.input_pass:focus {
box-shadow: none !important;
outline: 0px !important;
}
.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
background-color: darkgreen !important;
}
</style>
</head>
<!--Coded with love by Mutiullah Samim-->
<body>
<div class="container h-100">
<div class="d-flex justify-content-center h-100">
<div class="user_card">
<div class="d-flex justify-content-center">
<div class="brand_logo_container">
@*
<img src="https://cdn.freebiesupply.com/logos/large/2x/pinterest-circle-logo-png-transparent.png" class="brand_logo" alt="Logo">
*@
<img src="~/img/logo.png" class="brand_logo" alt="Logo">
</div>
</div>
<div class="d-flex justify-content-center form_container">
@*
<form>
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="" class="form-control input_user" value="" placeholder="username">
</div>
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="" class="form-control input_pass" value="" placeholder="password">
</div>
<div class="form-group">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customControlInline">
<label class="custom-control-label" for="customControlInline">Remember me</label>
</div>
</div>
<div class="d-flex justify-content-center mt-3 login_container">
<button type="button" name="button" class="btn login_btn">Login</button>
</div>
</form>
*@
@using (Html.BeginForm("ExternalLogin", "Login", new { provider = "Microsoft" }, FormMethod.Post, true, new { id = "externalLoginForm" }))
{
@Html.AntiForgeryToken()
<button type="submit" class="btn login_btn">Login with Microsoft</button>
}
</div>
<div class="mt-4">
<div class="d-flex justify-content-center links">
Don't have an account? <a href="#" class="ml-2">Sign Up</a>
</div>
<div class="d-flex justify-content-center links">
<a href="#">Forgot your password?</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,181 @@
@using ChatMvc
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
ViewData["Title"] = "Form Example";
}
@section Styles {
<style type="text/css">
.bg-grayed {
background-color: #D8D8D8
}
.disabled {
pointer-events: none;
}
</style>
}
<div class="container mt-5">
<h2>@Resource.InitialFormTitle</h2>
<br />
<br />
<form id="exampleForm">
<div class="row">
<div class="col-6">
<div class="form-group">
<label for="email">@Resource.NameLabel</label>
<input type="name" class="form-control bg-grayed" id="name" disabled value="@User.FindFirst("FullName").Value" style="background-color: #D8D8D8">
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="email">@Resource.EmailLabel</label>
<input type="email" class="form-control bg-grayed" id="email" disabled value="@User.Identity.Name" style="background-color: #D8D8D8">
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card mt-3 tab-card">
<div class="card-header tab-card-header">
<ul class="nav nav-tabs card-header-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link" id="one-tab" data-toggle="tab" href="#one" role="tab" aria-controls="One" aria-selected="true">Dados</a>
</li>
<li class="nav-item">
<a class="nav-link" id="two-tab" data-toggle="tab" href="#two" role="tab" aria-controls="Two" aria-selected="false">Links</a>
</li>
<li class="nav-item">
<a class="nav-link" id="three-tab" data-toggle="tab" href="#three" role="tab" aria-controls="Three" aria-selected="false">Tema</a>
</li>
</ul>
</div>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active p-3" id="one" role="tabpanel" aria-labelledby="one-tab">
<div class="tab-content-inner" style="height: 320px;">
<h5 class="card-title">Dados iniciais</h5>
<div class="form-group">
<label for="country">@Resource.CountryLabel</label>
<select class="form-control" id="country" placeholder="@Resource.CountryPlaceholder" required>
@if (Context.Request.Cookies["Language"] == "en")
{
<option value="1">@Resource.Country_EUA_Label</option>
<option value="2">@Resource.Country_India_Label</option>
<option value="3">@Resource.Country_Nigeria_Label</option>
<option value="4">@Resource.Country_Paquistao_Label</option>
<option value="5">@Resource.Country_UK_Label</option>
<option value="6">@Resource.Country_Filipinas_Label</option>
<option value="7">@Resource.Country_Canada_Label</option>
<option value="8">@Resource.Country_Australia_Label</option>
<option value="9">@Resource.Country_Gana_Label</option>
<option value="10">@Resource.Country_Quenia_Label</option>
}
else if (Context.Request.Cookies["Language"] == "pt-BR")
{
<option value="11">@Resource.Country_Brasil_Label</option>
<option value="12">@Resource.Country_Mocambique_Label</option>
<option value="13">@Resource.Country_Angola_Label</option>
<option value="14">@Resource.Country_Portugal_Label</option>
<option value="15">@Resource.Country_GuineBissau_Label</option>
<option value="16">@Resource.Country_TimorLeste_Label</option>
<option value="17">@Resource.Country_CaboVerde_Label</option>
}
</select>
<small id="countryHelp" class="form-text text-muted">@Resource.ChangeLanguage</small>
</div>
<div class="form-group">
<label for="businessArea">@Resource.BusinessAreaLabel</label>
<select class="form-control" id="country" placeholder="@Resource.CountryPlaceholder" required>
<option value="1">@Resource.BU_Alimentacao</option>
<option value="2">@Resource.BU_Vestuário</option>
<option value="3">@Resource.BU_Construção</option>
<option value="4">@Resource.BU_Saúde</option>
<option value="5">@Resource.BU_TI</option>
<option value="6">@Resource.BU_Beleza</option>
<option value="7">@Resource.BU_Empreendedorismo</option>
<option value="8">@Resource.BU_SetorPET</option>
<option value="9">@Resource.BU_Educacao</option>
<option value="10">@Resource.BU_TransporteLogistica</option>
</select>
</div>
<div class="form-group">
<label for="groupName">@Resource.GroupNameLabel</label>
<input type="text" class="form-control" id="groupName" placeholder="@Resource.GroupPlaceHolder" required>
</div>
</div>
<button type="button" class="btn btn-primary" id="next1Button">Próximo >></button>
</div>
<div class="tab-pane fade p-3" id="two" role="tabpanel" aria-labelledby="two-tab">
<div class="tab-content-inner" style="height: 320px;">
<h5 class="card-title">Tab Card Two</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<button type="button" class="btn btn-primary" id="next2Button">Próximo >></button>
</div>
<div class="tab-pane fade p-3 " id="three" role="tabpanel" aria-labelledby="three-tab">
<div class="tab-content-inner" style="height: 320px;">
<h5 class="card-title">Tab Card Three</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<button type="submit" class="btn btn-primary" id="saveButton" disabled>@Resource.SaveButton</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
@section Scripts {
<script type="text/javascript" >
const nextTab1 = $('#one-tab');
const nextTab2 = $('#two-tab');
const nextTab3 = $('#three-tab');
nextTab2.addClass('disabled');
nextTab3.addClass('disabled');
$(document).ready(function () {
$('#groupName, #businessArea').on('input', function() {
var groupName = $('#groupName').val();
var businessArea = $('#businessArea').val();
if (groupName && businessArea) {
$.ajax({
url: '/validateGroup',
type: 'POST',
data: { groupName: groupName, businessArea: businessArea },
success: function(response) {
if (response.isValid) {
$('#saveButton').prop('disabled', false);
} else {
$('#saveButton').prop('disabled', true);
}
}
});
} else {
$('#saveButton').prop('disabled', true);
}
});
$('#next1Button').on('click', function () {
nextTab2.removeClass('disabled');
nextTab2.tab('show');;
});
$('#next2Button').on('click', function () {
nextTab3.removeClass('disabled');
nextTab3.tab('show');;
});
nextTab3.addEventListener('click', function () {
// Aqui você pode adicionar a lógica para permitir que o usuário volte para as abas anteriores
});
});
</script>
}

View File

@ -0,0 +1,3 @@
@using ChatMvc
@using ChatMvc.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

19
Chat/appsettings.json Normal file
View File

@ -0,0 +1,19 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"AppSecret": "QA48Q~TolhL6faOWfU0GtKu3ZRAMdKjCJhQ7xcBZ",
"ClientID": "04df037b-1d10-4f66-8651-8c943ddb3fa3",
"Stripe": {
"SecretKey": "sua_secret_key_aqui",
"PublishableKey": "sua_publishable_key_aqui"
},
//"Kestrel:Certificates:Development:Password": "1b6db995-0c6e-48c8-b460-d421f42eeee0",
"Microsoft_ClientSecret": "~oN8Q~~pihoAj51JMSvnZJexW.qde2ZF3k4qLdlh",
"Microsoft_ClientId": "04df037b-1d10-4f66-8651-8c943ddb3fa3",
"ExternalApiBaseUrl": "http://localhost:5020"
}

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-circle-fill" viewBox="0 0 16 16">
<path d="M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-8.012 4.158c1.858 0 2.96-1.582 2.96-3.99V7.84c0-2.426-1.079-3.996-2.936-3.996-1.864 0-2.965 1.588-2.965 3.996v.328c0 2.42 1.09 3.99 2.941 3.99"/>
</svg>

After

Width:  |  Height:  |  Size: 476 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-circle" viewBox="0 0 16 16">
<path d="M7.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8"/>
</svg>

After

Width:  |  Height:  |  Size: 507 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-square-fill" viewBox="0 0 16 16">
<path d="M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm5.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99"/>
</svg>

After

Width:  |  Height:  |  Size: 514 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-square" viewBox="0 0 16 16">
<path d="M7.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 579 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M9.283 4.002H7.971L6.072 5.385v1.271l1.834-1.318h.065V12h1.312z"/>
</svg>

After

Width:  |  Height:  |  Size: 250 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8m15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0M9.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383z"/>
</svg>

After

Width:  |  Height:  |  Size: 279 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm7.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383z"/>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-square" viewBox="0 0 16 16">
<path d="M9.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 366 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-123" viewBox="0 0 16 16">
<path d="M2.873 11.297V4.142H1.699L0 5.379v1.137l1.64-1.18h.06v5.961zm3.213-5.09v-.063c0-.618.44-1.169 1.196-1.169.676 0 1.174.44 1.174 1.106 0 .624-.42 1.101-.807 1.526L4.99 10.553v.744h4.78v-.99H6.643v-.069L8.41 8.252c.65-.724 1.237-1.332 1.237-2.27C9.646 4.849 8.723 4 7.308 4c-1.573 0-2.36 1.064-2.36 2.15v.057zm6.559 1.883h.786c.823 0 1.374.481 1.379 1.179.01.707-.55 1.216-1.421 1.21-.77-.005-1.326-.419-1.379-.953h-1.095c.042 1.053.938 1.918 2.464 1.918 1.478 0 2.642-.839 2.62-2.144-.02-1.143-.922-1.651-1.551-1.714v-.063c.535-.09 1.347-.66 1.326-1.678-.026-1.053-.933-1.855-2.359-1.845-1.5.005-2.317.88-2.348 1.898h1.116c.032-.498.498-.944 1.206-.944.703 0 1.206.435 1.206 1.07.005.64-.504 1.106-1.2 1.106h-.75z"/>
</svg>

After

Width:  |  Height:  |  Size: 854 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M6.646 6.24c0-.691.493-1.306 1.336-1.306.756 0 1.313.492 1.313 1.236 0 .697-.469 1.23-.902 1.705l-2.971 3.293V12h5.344v-1.107H7.268v-.077l1.974-2.22.096-.107c.688-.763 1.287-1.428 1.287-2.43 0-1.266-1.031-2.215-2.613-2.215-1.758 0-2.637 1.19-2.637 2.402v.065h1.271v-.07Z"/>
</svg>

After

Width:  |  Height:  |  Size: 457 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8m15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0M6.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306"/>
</svg>

After

Width:  |  Height:  |  Size: 477 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm4.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306"/>
</svg>

After

Width:  |  Height:  |  Size: 484 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-square" viewBox="0 0 16 16">
<path d="M6.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 564 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-8.082.414c.92 0 1.535.54 1.541 1.318.012.791-.615 1.36-1.588 1.354-.861-.006-1.482-.469-1.54-1.066H5.104c.047 1.177 1.05 2.144 2.754 2.144 1.653 0 2.954-.937 2.93-2.396-.023-1.278-1.031-1.846-1.734-1.916v-.07c.597-.1 1.505-.739 1.482-1.876-.03-1.177-1.043-2.074-2.637-2.062-1.675.006-2.59.984-2.625 2.12h1.248c.036-.556.557-1.054 1.348-1.054.785 0 1.348.486 1.348 1.195.006.715-.563 1.237-1.342 1.237h-.838v1.072h.879Z"/>
</svg>

After

Width:  |  Height:  |  Size: 607 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle" viewBox="0 0 16 16">
<path d="M7.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8"/>
</svg>

After

Width:  |  Height:  |  Size: 642 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm5.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318"/>
</svg>

After

Width:  |  Height:  |  Size: 634 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-square" viewBox="0 0 16 16">
<path d="M7.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 714 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M7.519 5.057c-.886 1.418-1.772 2.838-2.542 4.265v1.12H8.85V12h1.26v-1.559h1.007V9.334H10.11V4.002H8.176zM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218"/>
</svg>

After

Width:  |  Height:  |  Size: 359 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle" viewBox="0 0 16 16">
<path d="M7.519 5.057q.33-.527.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8"/>
</svg>

After

Width:  |  Height:  |  Size: 421 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-square-fill" viewBox="0 0 16 16">
<path d="M6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm5.519 5.057q.33-.527.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265Z"/>
</svg>

After

Width:  |  Height:  |  Size: 428 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-square" viewBox="0 0 16 16">
<path d="M7.519 5.057q.33-.527.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 493 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-8.006 4.158c1.74 0 2.924-1.119 2.924-2.806 0-1.641-1.178-2.584-2.56-2.584-.897 0-1.442.421-1.612.68h-.064l.193-2.344h3.621V4.002H5.791L5.445 8.63h1.149c.193-.358.668-.809 1.435-.809.85 0 1.582.604 1.582 1.57 0 1.085-.779 1.682-1.57 1.682-.697 0-1.389-.31-1.53-1.031H5.276c.065 1.213 1.149 2.115 2.72 2.115Z"/>
</svg>

After

Width:  |  Height:  |  Size: 495 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 1 14 0A7 7 0 0 1 1 8m15 0A8 8 0 1 0 0 8a8 8 0 0 0 16 0m-8.006 4.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
</svg>

After

Width:  |  Height:  |  Size: 514 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm5.994 12.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
</svg>

After

Width:  |  Height:  |  Size: 521 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-square" viewBox="0 0 16 16">
<path d="M7.994 12.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>

After

Width:  |  Height:  |  Size: 601 B

Some files were not shown because too many files have changed in this diff Show More