diff --git a/App_GlobalResources/Resource.Designer.cs b/App_GlobalResources/Resource.Designer.cs
index 10b21dc..4e53424 100644
--- a/App_GlobalResources/Resource.Designer.cs
+++ b/App_GlobalResources/Resource.Designer.cs
@@ -105,6 +105,33 @@ namespace atakanozbancom.App_GlobalResources {
}
}
+ ///
+ /// Looks up a localized string similar to Affiliate links will be listed here soon..
+ ///
+ public static string AffiliateLinksComingSoon {
+ get {
+ return ResourceManager.GetString("AffiliateLinksComingSoon", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Support my work 💙.
+ ///
+ public static string AffiliateLinksTitle {
+ get {
+ return ResourceManager.GetString("AffiliateLinksTitle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to If you'd like to support my work, you can use the links below. It costs money for me to run and maintain these services, and using them may earn me a small benefit at no extra cost to you..
+ ///
+ public static string AffiliateLinksIntro {
+ get {
+ return ResourceManager.GetString("AffiliateLinksIntro", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to I m working hard and on these projects, and your support really motivates me. If you d like to support you can support by these links.
///
@@ -133,11 +160,11 @@ namespace atakanozbancom.App_GlobalResources {
}
///
- /// Looks up a localized string similar to GitHub.
+ /// Looks up a localized string similar to Gitea.
///
- public static string GitHub {
+ public static string Gitea {
get {
- return ResourceManager.GetString("GitHub", resourceCulture);
+ return ResourceManager.GetString("Gitea", resourceCulture);
}
}
@@ -222,6 +249,15 @@ namespace atakanozbancom.App_GlobalResources {
}
}
+ ///
+ /// Looks up a localized string similar to Support my work 💙.
+ ///
+ public static string NavAffiliateLinks {
+ get {
+ return ResourceManager.GetString("NavAffiliateLinks", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Home.
///
@@ -241,7 +277,7 @@ namespace atakanozbancom.App_GlobalResources {
}
///
- /// Looks up a localized string similar to Server Status.
+ /// Looks up a localized string similar to Service Status.
///
public static string Server {
get {
diff --git a/App_GlobalResources/Resource.resx b/App_GlobalResources/Resource.resx
index c55a70e..e54de30 100644
--- a/App_GlobalResources/Resource.resx
+++ b/App_GlobalResources/Resource.resx
@@ -150,6 +150,18 @@
My Projects
+
+ Support my work 💙
+
+
+ Support my work 💙
+
+
+ If you'd like to support my work, you can use the links below. It costs money for me to run and maintain these services, and using them may earn me a small benefit at no extra cost to you.
+
+
+ Affiliate links will be listed here soon.
+
Thank you
@@ -171,13 +183,13 @@
Photography’s another passion of mine. I love traveling and capturing 360° photos to upload on Google Street View, making hidden places visible to the world. It’s like my own version of a vlog channel, just in pictures.
-
- GitHub
+
+ Gitea
page.
- Server Status
+ Service Status
\ No newline at end of file
diff --git a/App_GlobalResources/Resource.tr-TR.resx b/App_GlobalResources/Resource.tr-TR.resx
index 34c79bf..0412264 100644
--- a/App_GlobalResources/Resource.tr-TR.resx
+++ b/App_GlobalResources/Resource.tr-TR.resx
@@ -150,6 +150,18 @@
Projelerim
+
+ Çalışmamı Destekleyin
+
+
+ Çalışmamı Destekleyin
+
+
+ Çalışmalarımı desteklemek isterseniz aşağıdaki linkleri kullanabilirsiniz. Bu servisleri çalıştırmak ve sürdürmek benim için maliyetli, bu linkleri kullanmanız size ekstra bir maliyet çıkarmadan bana küçük bir fayda sağlayabilir.
+
+
+ Affiliate linkleri yakında burada listelenecek.
+
Teşekkür ederim
@@ -171,13 +183,13 @@
Fotoğrafçılık ise bir başka tutkum. Seyahat etmeyi ve 360° fotoğraflar çekmeyi seviyorum. Bu fotoğrafları Google Street View’a yükleyerek dünyanın görülmeyen yerlerini görünür kılmayı hedefliyorum. Benim için bu, görsel bir vlog kanalı gibi.
-
- GitHub
+
+ Gitea
sayfamı ziyaret edebilirsiniz.
- Sunucu Durumu
+ Servis Durumu
\ No newline at end of file
diff --git a/App_Start/RouteConfig.cs b/App_Start/RouteConfig.cs
index 6606132..6f7e4cd 100644
--- a/App_Start/RouteConfig.cs
+++ b/App_Start/RouteConfig.cs
@@ -13,13 +13,21 @@ namespace atakanozbancom
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+ // Keep old /affiliate URLs working
+ routes.MapRoute(
+ name: "AffiliateRedirect",
+ url: "affiliate/{action}/{id}",
+ defaults: new { controller = "support", action = "Index", id = UrlParameter.Optional },
+ new[] { "atakanozbancom.Controllers" }
+ );
+
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
- defaults: new { controller = "Main", action = "Index", id = UrlParameter.Optional },
+ defaults: new { controller = "main", action = "Index", id = UrlParameter.Optional },
new[] { "atakanozbancom.Controllers" }
);
}
}
-}
+}
\ No newline at end of file
diff --git a/Content/uploads/affiliate-logos/d02c597beea14b2b89e1fffdae8e32f7.png b/Content/uploads/affiliate-logos/d02c597beea14b2b89e1fffdae8e32f7.png
new file mode 100644
index 0000000..20d8e5b
Binary files /dev/null and b/Content/uploads/affiliate-logos/d02c597beea14b2b89e1fffdae8e32f7.png differ
diff --git a/Content/uploads/affiliate-logos/e22ca27172c044d2ae017569d01ad1f4.png b/Content/uploads/affiliate-logos/e22ca27172c044d2ae017569d01ad1f4.png
new file mode 100644
index 0000000..1d63088
Binary files /dev/null and b/Content/uploads/affiliate-logos/e22ca27172c044d2ae017569d01ad1f4.png differ
diff --git a/Content/uploads/projects-media/2a158b008da04f09819d65f0dee7bbb4.png b/Content/uploads/projects-media/2a158b008da04f09819d65f0dee7bbb4.png
new file mode 100644
index 0000000..f9458a7
Binary files /dev/null and b/Content/uploads/projects-media/2a158b008da04f09819d65f0dee7bbb4.png differ
diff --git a/Content/uploads/projects-media/37fab4cfb93441cbbc04878bac60c1ec.png b/Content/uploads/projects-media/37fab4cfb93441cbbc04878bac60c1ec.png
new file mode 100644
index 0000000..30050ae
Binary files /dev/null and b/Content/uploads/projects-media/37fab4cfb93441cbbc04878bac60c1ec.png differ
diff --git a/Content/uploads/projects-media/41853c667bb34ebf9e90ed7f1d2334ba.png b/Content/uploads/projects-media/41853c667bb34ebf9e90ed7f1d2334ba.png
new file mode 100644
index 0000000..b2e105c
Binary files /dev/null and b/Content/uploads/projects-media/41853c667bb34ebf9e90ed7f1d2334ba.png differ
diff --git a/Content/uploads/projects-media/54e27917b1f345aab3eb29bc9b8fac53.png b/Content/uploads/projects-media/54e27917b1f345aab3eb29bc9b8fac53.png
new file mode 100644
index 0000000..af0822e
Binary files /dev/null and b/Content/uploads/projects-media/54e27917b1f345aab3eb29bc9b8fac53.png differ
diff --git a/Content/uploads/projects-media/63ba179cd4b64fecbbd4bd9927b40723.png b/Content/uploads/projects-media/63ba179cd4b64fecbbd4bd9927b40723.png
new file mode 100644
index 0000000..31a67de
Binary files /dev/null and b/Content/uploads/projects-media/63ba179cd4b64fecbbd4bd9927b40723.png differ
diff --git a/Content/uploads/projects-media/83b70aafc2ac4ea886eb84096cad0fac.png b/Content/uploads/projects-media/83b70aafc2ac4ea886eb84096cad0fac.png
new file mode 100644
index 0000000..7705a44
Binary files /dev/null and b/Content/uploads/projects-media/83b70aafc2ac4ea886eb84096cad0fac.png differ
diff --git a/Content/uploads/projects-media/856476623d23456481b0f7732f7ce331.png b/Content/uploads/projects-media/856476623d23456481b0f7732f7ce331.png
new file mode 100644
index 0000000..90b6ce2
Binary files /dev/null and b/Content/uploads/projects-media/856476623d23456481b0f7732f7ce331.png differ
diff --git a/Content/uploads/projects-media/85e3cd4752c148008efd7d4fa1aa0308.png b/Content/uploads/projects-media/85e3cd4752c148008efd7d4fa1aa0308.png
new file mode 100644
index 0000000..5af2edb
Binary files /dev/null and b/Content/uploads/projects-media/85e3cd4752c148008efd7d4fa1aa0308.png differ
diff --git a/Content/uploads/projects-media/c6c4adeafa7f45e98167bd78d0cd55b5.jpg b/Content/uploads/projects-media/c6c4adeafa7f45e98167bd78d0cd55b5.jpg
new file mode 100644
index 0000000..36fc385
Binary files /dev/null and b/Content/uploads/projects-media/c6c4adeafa7f45e98167bd78d0cd55b5.jpg differ
diff --git a/Content/uploads/projects-media/ccedc4a2f5ac44288338e583d82513cf.png b/Content/uploads/projects-media/ccedc4a2f5ac44288338e583d82513cf.png
new file mode 100644
index 0000000..e639f68
Binary files /dev/null and b/Content/uploads/projects-media/ccedc4a2f5ac44288338e583d82513cf.png differ
diff --git a/Content/uploads/projects-media/e0add95125c34c38b562625d7886ea9b.png b/Content/uploads/projects-media/e0add95125c34c38b562625d7886ea9b.png
new file mode 100644
index 0000000..535140b
Binary files /dev/null and b/Content/uploads/projects-media/e0add95125c34c38b562625d7886ea9b.png differ
diff --git a/Content/uploads/projects-media/ee14a5bd1142452b98545a079c25f100.png b/Content/uploads/projects-media/ee14a5bd1142452b98545a079c25f100.png
new file mode 100644
index 0000000..db9a9c1
Binary files /dev/null and b/Content/uploads/projects-media/ee14a5bd1142452b98545a079c25f100.png differ
diff --git a/Content/uploads/projects/1a0180574e3448ceaac4d4f3c5c7fbcb.jpeg b/Content/uploads/projects/1a0180574e3448ceaac4d4f3c5c7fbcb.jpeg
new file mode 100644
index 0000000..cf14583
Binary files /dev/null and b/Content/uploads/projects/1a0180574e3448ceaac4d4f3c5c7fbcb.jpeg differ
diff --git a/Content/uploads/wallpaper/e94637564de340a598769ac78bb18218.jpg b/Content/uploads/wallpaper/e94637564de340a598769ac78bb18218.jpg
new file mode 100644
index 0000000..2a3fe50
Binary files /dev/null and b/Content/uploads/wallpaper/e94637564de340a598769ac78bb18218.jpg differ
diff --git a/Controllers/adminController.cs b/Controllers/adminController.cs
index e5e3931..d175d7f 100644
--- a/Controllers/adminController.cs
+++ b/Controllers/adminController.cs
@@ -13,12 +13,22 @@ namespace atakanozbancom.Controllers
private readonly Context db = new Context();
[Authorize]
- public ActionResult Index() // shows what we have
+ public ActionResult Index() // admin dashboard landing page
+ {
+ ViewBag.MyProjectsCount = db.MyProjects.Count();
+ ViewBag.AffiliateLinksCount = db.AffiliateLinks.Count();
+ ViewBag.SocialIconsCount = db.SocialIcons.Count();
+ return View();
+ }
+
+ [Authorize]
+ public ActionResult MyProjects() // shows what we have
{
var value = db.MyProjects.ToList();
return View(value);
}
+ [Authorize]
[HttpGet]
public ActionResult myprojectsget(int id)
{
@@ -35,8 +45,6 @@ namespace atakanozbancom.Controllers
var vm = new AdminMyProjectsEditVM
{
id = p.id,
- image = p.image,
- iframe = p.iframe,
TitleEN = p.title,
DescEN = p.description,
@@ -45,63 +53,39 @@ namespace atakanozbancom.Controllers
DescTR = tr != null ? tr.description : ""
};
+ // NEW:
+ vm.medias = db.projectmedia
+ .Where(m => m.project_id == p.id)
+ .OrderBy(m => m.sort_order)
+ .ThenBy(m => m.id)
+ .ToList();
+
return View("myprojectsget", vm);
}
+
+ [Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
- public ActionResult myprojectsget(AdminMyProjectsEditVM vm, HttpPostedFileBase file)
+ public ActionResult myprojectsget(AdminMyProjectsEditVM vm)
{
if (!ModelState.IsValid)
+ {
+ vm.medias = db.projectmedia
+ .Where(m => m.project_id == vm.id)
+ .OrderBy(m => m.sort_order)
+ .ThenBy(m => m.id)
+ .ToList();
+
return View("myprojectsget", vm);
+ }
var p = db.MyProjects.FirstOrDefault(x => x.id == vm.id);
if (p == null) return HttpNotFound();
- var imageUrl = p.image;
-
- if (file != null && file.ContentLength > 0)
- {
- try
- {
- var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
- var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".webp" };
-
- if (!allowedExtensions.Contains(ext))
- {
- ModelState.AddModelError("", "You can just upload these formats: '.jpg', '.jpeg', '.png', '.webp'");
- return View("myprojectsget", vm);
- }
-
- var maxFileSize = 5 * 1024 * 1024;
- if (file.ContentLength > maxFileSize)
- {
- ModelState.AddModelError("", "The size of file exceeds 5MB limit.");
- return View("myprojectsget", vm);
- }
-
- var uploadsRoot = Server.MapPath("~/Content/uploads/projects");
- if (!Directory.Exists(uploadsRoot))
- Directory.CreateDirectory(uploadsRoot);
-
- var fileName = Guid.NewGuid().ToString("N") + ext;
- var filePath = Path.Combine(uploadsRoot, fileName);
- file.SaveAs(filePath);
-
- imageUrl = "/Content/uploads/projects/" + fileName;
- }
- catch (Exception ex)
- {
- ModelState.AddModelError("", "An error occured while upload: " + ex.Message);
- return View("myprojectsget", vm);
- }
- }
-
// EN -> base
p.title = vm.TitleEN;
p.description = vm.DescEN;
- p.image = imageUrl;
- p.iframe = vm.iframe;
// TR -> translations
var tr = db.myprojectstranslations
@@ -121,76 +105,28 @@ namespace atakanozbancom.Controllers
return RedirectToAction("myprojectsget", new { id = p.id });
}
- public ActionResult myprojectsupdate(myprojects x)
- {
- var ag = db.MyProjects.Find(x.id);
- ag.description = x.description;
- ag.title = x.title;
- ag.image = x.image;
- ag.iframe = x.iframe;
- db.SaveChanges();
- return RedirectToAction("Index");
- }
+ [Authorize]
[HttpGet]
public ActionResult newmppost() // newmppost = New My Projects Post
{
return View(new AdminMyProjectsEditVM());
}
+ [Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
- public ActionResult newmppost(AdminMyProjectsEditVM vm, HttpPostedFileBase file)
+ public ActionResult newmppost(AdminMyProjectsEditVM vm)
{
if (!ModelState.IsValid)
return View(vm);
- string imageUrl = vm.image;
-
- try
- {
- if (file != null && file.ContentLength > 0)
- {
- var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
- var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".webp" };
-
- if (!allowedExtensions.Contains(ext))
- {
- ModelState.AddModelError("", "You can just upload these formats: '.jpg', '.jpeg', '.png', '.webp'");
- return View(vm);
- }
-
- var maxFileSize = 5 * 1024 * 1024;
- if (file.ContentLength > maxFileSize)
- {
- ModelState.AddModelError("", "The size of file exceeds 5MB limit.");
- return View(vm);
- }
-
- var uploadsRoot = Server.MapPath("~/Content/uploads/projects");
- if (!Directory.Exists(uploadsRoot))
- Directory.CreateDirectory(uploadsRoot);
-
- var fileName = Guid.NewGuid().ToString("N") + ext;
- var filePath = Path.Combine(uploadsRoot, fileName);
- file.SaveAs(filePath);
-
- imageUrl = "/Content/uploads/projects/" + fileName;
- }
- }
- catch (Exception ex)
- {
- ModelState.AddModelError("", "An errror occured while upload: " + ex.Message);
- return View(vm);
- }
-
// EN -> base table
var newProject = new myprojects
{
title = vm.TitleEN,
- description = vm.DescEN,
- image = imageUrl,
- iframe = vm.iframe
+ description = vm.DescEN
+ // image/iframe artık yok
};
db.MyProjects.Add(newProject);
@@ -201,17 +137,21 @@ namespace atakanozbancom.Controllers
{
project_id = newProject.id,
culture = "tr",
- title = vm.TitleTR,
- description = vm.DescTR
+ title = vm.TitleTR ?? "",
+ description = vm.DescTR ?? ""
};
db.myprojectstranslations.Add(tr);
db.SaveChanges();
TempData["ok"] = "Project added successfully!";
- return RedirectToAction("Index");
+ return RedirectToAction("myprojectsget", new { id = newProject.id }); // direkt edit sayfasına at, media eklesin
}
+
+ [Authorize]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult myprojectsdelete(int id)
{
var mpd = db.MyProjects.Find(id); // mpd = my projects delete
@@ -220,42 +160,713 @@ namespace atakanozbancom.Controllers
db.MyProjects.Remove(mpd);
db.SaveChanges();
}
- return RedirectToAction("Index");
+ return RedirectToAction("MyProjects");
}
- //[HttpPost]
- //[ValidateAntiForgeryToken]
- //public ActionResult EditProject(AdminMyProjectsEditVM vm)
- //{
- // if (!ModelState.IsValid)
- // {
- // return View("myprojectsget", vm);
- // }
+ [HttpPost]
+ [Authorize]
+ [ValidateAntiForgeryToken]
+ public ActionResult addmedia(
+ int projectId,
+ int mediaType,
+ int sortOrder = 0,
+ string iframeUrl = null,
+ HttpPostedFileBase mediaFile = null)
+ {
+ var type = (MediaType)mediaType;
- // var p = db.MyProjects.FirstOrDefault(x => x.id == vm.id);
- // if (p == null) return HttpNotFound();
+ // 1) IFRAME -> URL
+ if (type == MediaType.Iframe)
+ {
+ if (string.IsNullOrWhiteSpace(iframeUrl))
+ {
+ TempData["ok"] = "Iframe URL boş olamaz.";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
- // p.image = vm.image;
- // p.iframe = vm.iframe;
- // p.title = vm.TitleEN;
- // p.description = vm.DescEN;
+ var trimmed = iframeUrl.Trim();
+ if (!Uri.TryCreate(trimmed, UriKind.Absolute, out var embedUri)
+ || (embedUri.Scheme != Uri.UriSchemeHttps && embedUri.Scheme != Uri.UriSchemeHttp))
+ {
+ TempData["ok"] = "Iframe URL must be a valid http(s) address.";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
- // var tr = db.myprojectstranslations
- // .FirstOrDefault(x => x.project_id == p.id && (x.culture == "tr" || x.culture == "tr-TR"));
+ var row = new projectmedia
+ {
+ project_id = projectId,
+ media_type = MediaType.Iframe,
+ url = trimmed,
+ sort_order = sortOrder
+ };
- // if (tr == null)
- // {
- // tr = new myprojectstranslation { project_id = p.id, culture = "tr" };
- // db.myprojectstranslations.Add(tr);
- // }
+ db.projectmedia.Add(row);
+ db.SaveChanges();
- // tr.title = vm.TitleTR;
- // tr.description = vm.DescTR;
+ TempData["ok"] = "Media eklendi!";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
- // db.SaveChanges();
+ // 2) IMAGE/VIDEO/DOCUMENT -> FILE
+ if (mediaFile == null || mediaFile.ContentLength <= 0)
+ {
+ TempData["ok"] = "Dosya seçmelisin.";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
+
+ var ext = Path.GetExtension(mediaFile.FileName)?.ToLowerInvariant() ?? "";
+
+ // Tip bazlı uzantı whitelist
+ string[] allowed;
+ switch (type)
+ {
+ case MediaType.Image:
+ allowed = new[] { ".jpg", ".jpeg", ".png", ".webp", ".gif" };
+ break;
+ //case MediaType.Video:
+ // allowed = new[] { ".mp4", ".webm", ".mov" };
+ // break;
+ //case MediaType.Document:
+ // allowed = new[] { ".pdf" };
+ // break;
+ default:
+ TempData["ok"] = "Geçersiz media type.";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
+
+ if (!allowed.Contains(ext))
+ {
+ TempData["ok"] = "Bu dosya tipi kabul edilmiyor: " + ext;
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
+
+ // Upload path
+ var uploadsRoot = Server.MapPath("~/Content/uploads/projects-media");
+ if (!Directory.Exists(uploadsRoot))
+ Directory.CreateDirectory(uploadsRoot);
+
+ var fileName = Guid.NewGuid().ToString("N") + ext;
+ var filePath = Path.Combine(uploadsRoot, fileName);
+ mediaFile.SaveAs(filePath);
+
+ var publicUrl = "/Content/uploads/projects-media/" + fileName;
+
+ var m = new projectmedia
+ {
+ project_id = projectId,
+ media_type = type,
+ url = publicUrl,
+ sort_order = sortOrder
+ };
+
+ db.projectmedia.Add(m);
+ db.SaveChanges();
+
+ TempData["ok"] = "Media eklendi!";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
+
+ [Authorize]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public ActionResult deletemedia(int id, int projectId)
+ {
+ var m = db.projectmedia.FirstOrDefault(x => x.id == id && x.project_id == projectId);
+ if (m == null)
+ return RedirectToAction("myprojectsget", new { id = projectId });
+
+ // Dosya silme: sadece Iframe dışındakiler + URL bizim uploads klasörümüzse
+ if (m.media_type != MediaType.Iframe && !string.IsNullOrWhiteSpace(m.url))
+ {
+ try
+ {
+ // Güvenlik: sadece bizim klasördeki dosyaları sil
+ var prefix = "/Content/uploads/projects-media/";
+ if (m.url.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
+ {
+ var relative = "~" + m.url; // ~/Content/uploads/...
+ var physicalPath = Server.MapPath(relative);
+
+ if (System.IO.File.Exists(physicalPath))
+ System.IO.File.Delete(physicalPath);
+ }
+ }
+ catch
+ {
+ // istersen log yazdırırız, şimdilik sessiz geçiyoruz
+ }
+ }
+
+ db.projectmedia.Remove(m);
+ db.SaveChanges();
+
+ TempData["ok"] = "Media silindi.";
+ return RedirectToAction("myprojectsget", new { id = projectId });
+ }
+
+ // ================= AFFILIATE LINKS =================
+
+ // .svg intentionally excluded: SVGs can embed
+