Add project files.
This commit is contained in:
210
ConstructorAppUI/Views/Project/CreateProject.cshtml
Normal file
210
ConstructorAppUI/Views/Project/CreateProject.cshtml
Normal file
@@ -0,0 +1,210 @@
|
||||
@model CreateProjectDto
|
||||
@{
|
||||
ViewData["Title"] = "CreateProject";
|
||||
Layout = "~/Views/AdminLayout/Index.cshtml";
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
<div class="container-fluid">
|
||||
<h4 class="page-title">Ana Sayfa Projelerimiz İşlemleri</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<form asp-action="CreateProject" method="post" enctype="multipart/form-data" id="sliderForm">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Yeni Proje Girişi</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<!-- Sol sütun -->
|
||||
<div class="col-md-6">
|
||||
<h5 class="mb-3 font-weight-bold text-primary">Anasayfa Projeler Kısmında Gösterilecek Alanlar:</h5>
|
||||
<div class="form-group">
|
||||
<label for="Date">Oturum Tarihi</label>
|
||||
<input type="date" class="form-control" asp-for="Date" id="Date">
|
||||
<span asp-validation-for="Date" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Title">Başlık</label>
|
||||
<input type="text" class="form-control" asp-for="Title" id="Title">
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Location">Lokasyon</label>
|
||||
<input type="text" class="form-control" asp-for="Location" id="Location">
|
||||
<span asp-validation-for="Location" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ShortDescription">Kısa Açıklama</label>
|
||||
<textarea rows="2" class="form-control" asp-for="ShortDescription" id="ShortDescription"></textarea>
|
||||
<span asp-validation-for="ShortDescription" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<!-- Görsel CoverFile-->
|
||||
<div class="form-group">
|
||||
<label for="ImageFile">Kapak Görseli</label><br />
|
||||
<span class="badge badge-danger">Tema Bütünlüğü için Görsel Boyutu 775x524 olmalıdır.</span>
|
||||
<input type="file" class="form-control" name="CoverFile" id="CoverFile">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sağ sütun -->
|
||||
<div class="col-md-6">
|
||||
<h5 class="mb-3 font-weight-bold text-warning">Projeler Detay Sayfasında Gösterilecek Alanlar:</h5>
|
||||
<div class="form-group">
|
||||
<label for="Slug">Sayfa Adı</label>
|
||||
<input type="text" class="form-control" asp-for="Slug" id="Slug">
|
||||
<span asp-validation-for="Slug" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="GoogleMapIFrame">Google Map IFrame</label>
|
||||
<input type="text" class="form-control" asp-for="GoogleMapIFrame" id="GoogleMapIFrame">
|
||||
<span asp-validation-for="GoogleMapIFrame" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="LongDescription">Uzun Açıklama</label>
|
||||
<textarea rows="2" class="form-control" asp-for="LongDescription" id="LongDescription"></textarea>
|
||||
<span asp-validation-for="LongDescription" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="VideoUrl">Video Url</label>
|
||||
<input type="text" class="form-control" asp-for="VideoUrl" id="VideoUrl">
|
||||
<span asp-validation-for="VideoUrl" class="text-danger"></span>
|
||||
</div>
|
||||
<!-- Görsel FloorPlanFile-->
|
||||
<div class="form-group">
|
||||
<label for="FloorPlanUrl">Kat Planı</label>
|
||||
<input type="file" class="form-control" name="FloorPlanFile" id="FloorPlanFile">
|
||||
<span asp-validation-for="FloorPlanUrl" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<div id="errorMessages" class="text-danger mb-3"></div>
|
||||
<button class="btn btn-success">Kaydet</button>
|
||||
<a href="/Project/Index/" class="btn btn-warning ml-2">Listeye Dön</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Formdaki alanlar boş geçilemesin *@
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const form = document.getElementById("sliderForm");
|
||||
const errorDiv = document.getElementById("errorMessages");
|
||||
|
||||
const fields = [
|
||||
{ id: "Location", name: "Lokasyon" },
|
||||
{ id: "Title", name: "Başlık" },
|
||||
{ id: "ShortDescription", name: "Kısa Açıklama" },
|
||||
{ id: "GoogleMapIFrame", name: "Google Map IFrame" },
|
||||
{ id: "CoverFile", name: "Kapak Görseli" },
|
||||
{ id: "LongDescription", name: "Uzun Açıklama" },
|
||||
{ id: "Slug", name: "Dinamik Sayfa Adı" }
|
||||
];
|
||||
|
||||
// Her input için focus olduğunda çerçeveyi temizle
|
||||
fields.forEach(field => {
|
||||
const input = document.getElementById(field.id);
|
||||
input.addEventListener("focus", function () {
|
||||
input.style.border = "";
|
||||
errorDiv.innerHTML = ""; // Hataları da temizle
|
||||
});
|
||||
});
|
||||
|
||||
// Form submit kontrolü
|
||||
form.addEventListener("submit", function (e) {
|
||||
let isValid = true;
|
||||
let messages = [];
|
||||
|
||||
errorDiv.innerHTML = ""; // Önceki mesajları temizle
|
||||
|
||||
fields.forEach(field => {
|
||||
const input = document.getElementById(field.id);
|
||||
|
||||
if (input.type === "file") {
|
||||
if (input.files.length === 0) {
|
||||
isValid = false;
|
||||
messages.push(`<li>${field.name} yüklenmelidir.</li>`);
|
||||
input.style.border = "2px solid red";
|
||||
}
|
||||
} else {
|
||||
if (input.value.trim() === "") {
|
||||
isValid = false;
|
||||
messages.push(`<li>${field.name} alanı boş olamaz.</li>`);
|
||||
input.style.border = "2px solid red";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
e.preventDefault();
|
||||
errorDiv.innerHTML = `<ul>${messages.join("")}</ul>`;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Slug dönüştürücü fonksiyon
|
||||
function generateSlug(text) {
|
||||
const map = {
|
||||
ç: 'c', Ç: 'c',
|
||||
ğ: 'g', Ğ: 'g',
|
||||
ü: 'u', Ü: 'u',
|
||||
ş: 's', Ş: 's',
|
||||
ı: 'i', İ: 'i',
|
||||
ö: 'o', Ö: 'o'
|
||||
};
|
||||
|
||||
return text
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[çÇğĞüÜşŞıİöÖ]/g, letter => map[letter])
|
||||
.replace(/[^a-z0-9\s-]/g, '') // harf, sayı, boşluk ve tire dışındakileri sil
|
||||
.replace(/\s+/g, '-') // boşlukları tireye çevir
|
||||
.replace(/-+/g, '-') // birden fazla tire varsa teke indir
|
||||
.replace(/^-+|-+$/g, ''); // baştaki ve sondaki tireleri sil
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const titleInput = document.getElementById("Title");
|
||||
const slugInput = document.getElementById("Slug");
|
||||
|
||||
if (titleInput && slugInput) {
|
||||
titleInput.addEventListener("input", function () {
|
||||
const slug = generateSlug(titleInput.value);
|
||||
slugInput.value = slug;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.input-error {
|
||||
border: 2px solid red !important;
|
||||
box-shadow: 0 0 4px rgba(255, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
177
ConstructorAppUI/Views/Project/Detail.cshtml
Normal file
177
ConstructorAppUI/Views/Project/Detail.cshtml
Normal file
@@ -0,0 +1,177 @@
|
||||
@model ResultProjectDto
|
||||
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<title>@Model.Title</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="keywords" content="">
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href="~/SeedData/favicon-16x16.png" rel="icon">
|
||||
<link href="~/SeedData/apple-touch-icon.png" rel="apple-touch-icon">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect">
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Vendor CSS Files -->
|
||||
<link href="~/EstateAgency/assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="~/EstateAgency/assets/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="~/EstateAgency/assets/vendor/aos/aos.css" rel="stylesheet">
|
||||
<link href="~/EstateAgency/assets/vendor/fontawesome-free/css/all.min.css" rel="stylesheet">
|
||||
<link href="~/EstateAgency/assets/vendor/swiper/swiper-bundle.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Main CSS File -->
|
||||
<link href="~/EstateAgency/assets/css/main.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body class="property-single-page">
|
||||
<main class="main">
|
||||
<!-- Page Title -->
|
||||
<div class="page-title" data-aos="fade">
|
||||
<div class="heading">
|
||||
<div class="container">
|
||||
<div class="row d-flex justify-content-center text-center">
|
||||
<div class="col-lg-8">
|
||||
<h1>@Model.Title</h1>
|
||||
<p class="mb-0">@Model.ShortDescription</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- End Page Title -->
|
||||
<!-- Real Estate 2 Section -->
|
||||
<section id="real-estate-2" class="real-estate-2 section">
|
||||
|
||||
<div class="container" data-aos="fade-up">
|
||||
|
||||
<div class="portfolio-details-slider swiper init-swiper">
|
||||
<script type="application/json" class="swiper-config">
|
||||
{
|
||||
"loop": true,
|
||||
"speed": 600,
|
||||
"autoplay": {
|
||||
"delay": 5000
|
||||
},
|
||||
"slidesPerView": "auto",
|
||||
"navigation": {
|
||||
"nextEl": ".swiper-button-next",
|
||||
"prevEl": ".swiper-button-prev"
|
||||
},
|
||||
"pagination": {
|
||||
"el": ".swiper-pagination",
|
||||
"type": "bullets",
|
||||
"clickable": true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="swiper-wrapper align-items-center">
|
||||
@if (Model.ImageUrls != null && Model.ImageUrls.Any())
|
||||
{
|
||||
foreach (var img in Model.ImageUrls)
|
||||
{
|
||||
<div class="swiper-slide">
|
||||
<img src="@img" alt="">
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="swiper-slide">
|
||||
<img src="@Model.CoverUrl" alt="">
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="swiper-button-prev"></div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="swiper-pagination"></div>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-between gy-4 mt-4">
|
||||
|
||||
<div class="col-lg-12" data-aos="fade-up">
|
||||
|
||||
<div class="portfolio-description">
|
||||
<h2>Proje Detayları</h2>
|
||||
<p>
|
||||
@Model.LongDescription
|
||||
</p>
|
||||
</div><!-- End Portfolio Description -->
|
||||
<!-- Tabs -->
|
||||
<ul class="nav nav-pills mb-3">
|
||||
<li><a class="nav-link active" data-bs-toggle="pill" href="#real-estate-2-tab1">Video</a></li>
|
||||
<li><a class="nav-link" data-bs-toggle="pill" href="#real-estate-2-tab2">Kat Planı</a></li>
|
||||
<li><a class="nav-link" data-bs-toggle="pill" href="#real-estate-2-tab3">Lokasyon</a></li>
|
||||
</ul><!-- End Tabs -->
|
||||
<!-- Tab Content -->
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade show active" id="real-estate-2-tab1">
|
||||
<div class="ratio ratio-16x9">
|
||||
@{
|
||||
var url = Model.VideoUrl;
|
||||
var vid = ConstructorAppUI.Helpers.YouTubeHelper.ExtractVideoId(url);
|
||||
var embedUrl = string.IsNullOrEmpty(vid) ? "" : $"https://www.youtube.com/embed/{vid}?autoplay=1";
|
||||
}
|
||||
<p>Embed URL: @embedUrl</p>
|
||||
@if (!string.IsNullOrEmpty(embedUrl))
|
||||
{
|
||||
<iframe src="@embedUrl" style="width: 100%; height: 400px;" frameborder="0" allowfullscreen></iframe>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div><!-- End Tab 1 Content -->
|
||||
|
||||
<div class="tab-pane fade" id="real-estate-2-tab2">
|
||||
@* <img width="750" height="750" src="@Model.FloorPlanUrl alt="Görsel" /> *@
|
||||
<img src="@Model.FloorPlanUrl" alt="Görsel" width="750" height="750" />
|
||||
|
||||
</div><!-- End Tab 2 Content -->
|
||||
|
||||
<div class="tab-pane fade" id="real-estate-2-tab3">
|
||||
<iframe src="@Html.Raw(Model.GoogleMapIFrame)" style="border:0; width:100%; height:400px;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
|
||||
</div><!-- End Tab 3 Content -->
|
||||
</div><!-- End Tab Content -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</section><!-- /Real Estate 2 Section -->
|
||||
|
||||
</main>
|
||||
|
||||
|
||||
|
||||
<!-- Scroll Top -->
|
||||
<a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
|
||||
|
||||
<!-- Preloader -->
|
||||
<div id="preloader"></div>
|
||||
|
||||
<!-- Vendor JS Files -->
|
||||
<script src="~/EstateAgency/assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/EstateAgency/assets/vendor/php-email-form/validate.js"></script>
|
||||
<script src="~/EstateAgency/assets/vendor/aos/aos.js"></script>
|
||||
<script src="~/EstateAgency/assets/vendor/swiper/swiper-bundle.min.js"></script>
|
||||
<script src="~/EstateAgency/assets/vendor/purecounter/purecounter_vanilla.js"></script>
|
||||
|
||||
<!-- Main JS File -->
|
||||
<script src="~/EstateAgency/assets/js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
92
ConstructorAppUI/Views/Project/Index.cshtml
Normal file
92
ConstructorAppUI/Views/Project/Index.cshtml
Normal file
@@ -0,0 +1,92 @@
|
||||
@using static ConstructorApp.EntityLayer.Entities.Project
|
||||
@using static ConstructorAppUI.Helpers.EnumExtensions
|
||||
@model List<ResultProjectDto>
|
||||
@{
|
||||
ViewData["Title"] = "Index";
|
||||
Layout = "~/Views/AdminLayout/Index.cshtml";
|
||||
int count = 0;
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
<div class="container-fluid">
|
||||
<h4 class="page-title">Ana Sayfa Projelerimiz İşlemleri</h4>
|
||||
<a href="/Project/CreateProject/" class="btn btn-outline-primary">Yeni Ekle</a>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<table class="table table-head-bg-success table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Oturum Tarihi</th>
|
||||
<th scope="col">Başlık</th>
|
||||
<th scope="col">Sayfa Adı</th>
|
||||
<th scope="col">Lokasyon</th>
|
||||
<th scope="col">GoogleMap IFrame</th>
|
||||
<th scope="col">Video Url</th>
|
||||
<th scope="col">Kapak Görseli</th>
|
||||
<th scope="col">Kat Planı</th>
|
||||
<th scope="col">Yayın Durumu</th>
|
||||
<th scope="col">Proje Durumu</th>
|
||||
<th scope="col">İşlemler</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (Model == null || !Model.Any())
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3">Kayıt bulunamadı.</td>
|
||||
</tr>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var item in Model)
|
||||
{
|
||||
count++;
|
||||
<tr>
|
||||
<td>@count</td>
|
||||
<td>@item.Date</td>
|
||||
<td>@item.Title</td>
|
||||
<td>@item.Slug</td>
|
||||
<td>@(item.Location?.Length > 8 ? item.Location.Substring(0, 8) + "..." : item.Location)</td>
|
||||
<td>@(item.GoogleMapIFrame?.Length > 8 ? item.GoogleMapIFrame.Substring(0, 8) + "..." : item.GoogleMapIFrame)</td>
|
||||
<td>@(item.VideoUrl?.Length > 8 ? item.VideoUrl.Substring(0, 8) + "..." : item.VideoUrl)</td>
|
||||
<td>
|
||||
<img width="75" height="75" src="@item.CoverUrl" alt="Görsel" />
|
||||
</td>
|
||||
<td>
|
||||
<img width="75" height="75" src="@item.FloorPlanUrl" alt="Görsel" />
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge @(item.IsActive? "bg-success text-white" : "bg-secondary text-white")">
|
||||
@(item.IsActive ? "Aktif" : "Pasif")
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge
|
||||
@(item.Status == ProjectStatus.Planned ? "bg-warning text-dark" :
|
||||
item.Status == ProjectStatus.UnderConstruction ? "bg-info text-white" :
|
||||
"bg-success text-white")">
|
||||
@item.Status.GetDisplayName()
|
||||
</span>
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<a href="/Project/UpdateProject/@item.ProjectID" class="btn btn-outline-success">Güncelle</a>
|
||||
<a href="/Project/ProjectStatusActive/@item.ProjectID" class="btn btn-outline-info @(item.IsActive == true ? "disabled" : "")">Aktif</a>
|
||||
<a href="/Project/ProjectStatusPassive/@item.ProjectID" class="btn btn-outline-dark @(item.IsActive == false ? "disabled" : "")">Pasif</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
219
ConstructorAppUI/Views/Project/UpdateProject.cshtml
Normal file
219
ConstructorAppUI/Views/Project/UpdateProject.cshtml
Normal file
@@ -0,0 +1,219 @@
|
||||
@model UpdateProjectDto
|
||||
@{
|
||||
ViewData["Title"] = "UpdateProject";
|
||||
Layout = "~/Views/AdminLayout/Index.cshtml";
|
||||
}
|
||||
|
||||
<div class="content">
|
||||
<div class="container-fluid">
|
||||
<h4 class="page-title">Ana Sayfa Projelerimiz İşlemleri</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<form method="post" enctype="multipart/form-data" id="sliderForm">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Slider Güncelleme</div>
|
||||
</div>
|
||||
<input type="hidden" asp-for="ProjectID" />
|
||||
<input type="hidden" asp-for="IsActive" />
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<!-- Sol sütun -->
|
||||
<div class="col-md-6">
|
||||
<h5 class="mb-3 font-weight-bold text-primary">Anasayfa Projeler Kısmında Gösterilecek Alanlar:</h5>
|
||||
<div class="form-group">
|
||||
<label for="Date">Oturum Tarihi</label>
|
||||
<input type="date" class="form-control" asp-for="Date" id="Date">
|
||||
<span asp-validation-for="Date" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Title">Başlık</label>
|
||||
<input type="text" class="form-control" asp-for="Title" id="Title">
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Location">Lokasyon</label>
|
||||
<input type="text" class="form-control" asp-for="Location" id="Location">
|
||||
<span asp-validation-for="Location" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="ShortDescription">Kısa Açıklama</label>
|
||||
<textarea rows="2" class="form-control" asp-for="ShortDescription" id="ShortDescription"></textarea>
|
||||
<span asp-validation-for="ShortDescription" class="text-danger"></span>
|
||||
</div>
|
||||
<!-- Görsel CoverUrl -->
|
||||
<div class="form-group">
|
||||
<label for="ImageFile">Kapak Görseli</label><br />
|
||||
<span class="badge badge-danger">Tema Bütünlüğü için Görsel Boyutu 775x524 olmalıdır.</span>
|
||||
<input type="file" class="form-control" name="CoverFile" id="ImageFile">
|
||||
@if (!string.IsNullOrEmpty(Model.CoverUrl))
|
||||
{
|
||||
<img src="@Model.CoverUrl" alt="Görsel" class="img-fluid mt-2" style="width: 100px; height: 100px;">
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sağ sütun -->
|
||||
<div class="col-md-6">
|
||||
<h5 class="mb-3 font-weight-bold text-warning">Projeler Detay Sayfasında Gösterilecek Alanlar:</h5>
|
||||
<div class="form-group">
|
||||
<label for="Slug">Sayfa Adı</label>
|
||||
<input type="text" class="form-control" asp-for="Slug" id="Slug">
|
||||
<span asp-validation-for="Slug" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="GoogleMapIFrame">Google Map IFrame</label>
|
||||
<input type="text" class="form-control" asp-for="GoogleMapIFrame" id="GoogleMapIFrame">
|
||||
<span asp-validation-for="GoogleMapIFrame" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="LongDescription">Uzun Açıklama</label>
|
||||
<textarea rows="2" class="form-control" asp-for="LongDescription" id="LongDescription"></textarea>
|
||||
<span asp-validation-for="LongDescription" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="VideoUrl">Video Url</label>
|
||||
<input type="text" class="form-control" asp-for="VideoUrl" id="VideoUrl">
|
||||
<span asp-validation-for="VideoUrl" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<!-- Görsel FloorPlanFile -->
|
||||
<div class="form-group">
|
||||
<label for="ImageFile">Kat Planı</label><br />
|
||||
<span class="badge badge-danger">Tema Bütünlüğü için Görsel Boyutu 775x524 olmalıdır.</span>
|
||||
<input type="file" class="form-control" name="FloorPlanFile" id="FloorPlanFile">
|
||||
@if (!string.IsNullOrEmpty(Model.FloorPlanUrl))
|
||||
{
|
||||
<img src="@Model.FloorPlanUrl" alt="Görsel" class="img-fluid mt-2" style="width: 100px; height: 100px;">
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Status">Proje Durumu</label>
|
||||
<select asp-for="Status" class="form-control" asp-items="@(ViewBag.StatusList as List<SelectListItem>)">
|
||||
<option value="">Durum Seçiniz</option>
|
||||
</select>
|
||||
<span asp-validation-for="Status" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-action">
|
||||
<div id="errorMessages" class="text-danger mb-3"></div>
|
||||
<button class="btn btn-success">Kaydet</button>
|
||||
<a href="/Project/Index/" class="btn btn-warning ml-2">Listeye Dön</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Formdaki alanlar boş geçilemesin *@
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const form = document.getElementById("sliderForm");
|
||||
const errorDiv = document.getElementById("errorMessages");
|
||||
|
||||
const fields = [
|
||||
{ id: "Location", name: "Lokasyon" },
|
||||
{ id: "Title", name: "Başlık" },
|
||||
{ id: "ShortDescription", name: "Kısa Açıklama" },
|
||||
{ id: "GoogleMapIFrame", name: "Google Map IFrame" },
|
||||
{ id: "LongDescription", name: "Uzun Açıklama" },
|
||||
{ id: "Slug", name: "Dinamik Sayfa Adı" }
|
||||
];
|
||||
|
||||
// Her input için focus olduğunda çerçeveyi temizle
|
||||
fields.forEach(field => {
|
||||
const input = document.getElementById(field.id);
|
||||
input.addEventListener("focus", function () {
|
||||
input.style.border = "";
|
||||
errorDiv.innerHTML = ""; // Hataları da temizle
|
||||
});
|
||||
});
|
||||
|
||||
// Form submit kontrolü
|
||||
form.addEventListener("submit", function (e) {
|
||||
let isValid = true;
|
||||
let messages = [];
|
||||
|
||||
errorDiv.innerHTML = ""; // Önceki mesajları temizle
|
||||
|
||||
fields.forEach(field => {
|
||||
const input = document.getElementById(field.id);
|
||||
|
||||
if (input.type === "file") {
|
||||
if (input.files.length === 0) {
|
||||
isValid = false;
|
||||
messages.push(`<li>${field.name} yüklenmelidir.</li>`);
|
||||
input.style.border = "2px solid red";
|
||||
}
|
||||
} else {
|
||||
if (input.value.trim() === "") {
|
||||
isValid = false;
|
||||
messages.push(`<li>${field.name} alanı boş olamaz.</li>`);
|
||||
input.style.border = "2px solid red";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
e.preventDefault();
|
||||
errorDiv.innerHTML = `<ul>${messages.join("")}</ul>`;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Slug dönüştürücü fonksiyon
|
||||
function generateSlug(text) {
|
||||
const map = {
|
||||
ç: 'c', Ç: 'c',
|
||||
ğ: 'g', Ğ: 'g',
|
||||
ü: 'u', Ü: 'u',
|
||||
ş: 's', Ş: 's',
|
||||
ı: 'i', İ: 'i',
|
||||
ö: 'o', Ö: 'o'
|
||||
};
|
||||
|
||||
return text
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[çÇğĞüÜşŞıİöÖ]/g, letter => map[letter])
|
||||
.replace(/[^a-z0-9\s-]/g, '') // harf, sayı, boşluk ve tire dışındakileri sil
|
||||
.replace(/\s+/g, '-') // boşlukları tireye çevir
|
||||
.replace(/-+/g, '-') // birden fazla tire varsa teke indir
|
||||
.replace(/^-+|-+$/g, ''); // baştaki ve sondaki tireleri sil
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const titleInput = document.getElementById("Title");
|
||||
const slugInput = document.getElementById("Slug");
|
||||
|
||||
if (titleInput && slugInput) {
|
||||
titleInput.addEventListener("input", function () {
|
||||
const slug = generateSlug(titleInput.value);
|
||||
slugInput.value = slug;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.input-error {
|
||||
border: 2px solid red !important;
|
||||
box-shadow: 0 0 4px rgba(255, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user