Skip to content
This repository was archived by the owner on Apr 21, 2026. It is now read-only.

Commit af00e40

Browse files
authored
Merge pull request #32 from paiindustries/fix/blog
Fix/blog
2 parents ddd4302 + 346abbb commit af00e40

10 files changed

Lines changed: 86 additions & 40 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ settings.xml
2323
/public/files
2424
/app/lib
2525
*.log
26+
/public/images

app/config/routes.cfm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
.get(name = "api_docs", pattern = "api", to = "web.ApiController##Index")
5454
5555
.get(name = "blog", pattern = "blog", to = "web.BlogController##Index")
56-
.get(name = "blog", pattern = "blog/edit/[id]", to = "web.BlogController##Edit")
56+
.get(name = "blogEdit", pattern = "blog/edit/[id]", to = "web.BlogController##Edit")
5757
5858
.get(name = "downloads", pattern = "downloads", to = "web.DownloadsController##Index")
5959

app/controllers/web/BlogController.cfc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ component extends="app.Controllers.Controller" {
33

44
// Configuration function
55
function config() {
6-
verifies(except="index,create,store,show,update,destroy,loadCategories,loadStatuses,loadPostTypes,Categories,blogs,comment,feed", params="key", paramsTypes="integer", handler="index");
6+
verifies(except="index,create,store,show,update,destroy,loadCategories,loadStatuses,loadPostTypes,Categories,blogs,comment,feed,error", params="key", paramsTypes="integer", handler="index");
77
filters(through="restrictAccess", only="create,store,comment");
88
usesLayout("/layout");
99
}
@@ -60,7 +60,6 @@ component extends="app.Controllers.Controller" {
6060
// Function to show the create blog form
6161
function create() {
6262
saveRedirectUrl(cgi.script_name & "?" & cgi.query_string);
63-
renderView(layout="blogLayout");
6463
}
6564

6665
// Function to store a new blog
@@ -96,7 +95,7 @@ component extends="app.Controllers.Controller" {
9695
response = saveBlog(params);
9796
saveTags(params, response.blogId);
9897
saveCategories(params, response.blogId);
99-
redirectTo(action="index");
98+
redirectTo(route="blog");
10099
} catch (any e) {
101100
// Handle error
102101
redirectTo(action="error", errorMessage="Failed to save blog post.");
@@ -469,7 +468,7 @@ component extends="app.Controllers.Controller" {
469468
// Insert new categories
470469
for (var category_Id in categoryArray) {
471470
var newCategory = model("BlogCategory").new();
472-
newCategory.categoryName = category_Id;
471+
newCategory.categoryId = category_Id;
473472
newCategory.blogId = blogId;
474473
newCategory.createdAt = now();
475474
newCategory.updatedAt = now();

app/models/Blog.cfc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ component extends="app.Models.Model" {
5151
* Computed property to get the correct post date.
5252
*/
5353
public function getDisplayDate() {
54-
return this.postCreatedDate ?: this.createdAt;
54+
if (NOT isEmpty(this.postCreatedDate)) {
55+
return this.postCreatedDate;
56+
} else {
57+
return this.createdAt;
58+
}
5559
}
5660
}

app/views/layout.cfm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<link href="/stylesheets/select2-bootstrap-min.css" rel="stylesheet">
8080
<link href="/stylesheets/notifier.min.css" rel="stylesheet">
8181

82+
<script src="/javascripts/jquery.min.js"></script>
8283
<script src="/javascripts/htmx.min.js"></script>
8384
<script src="/javascripts/highlighter.min.js"></script>
8485
<script src="/javascripts/quill.min.js"></script>
@@ -291,7 +292,7 @@
291292
</ul>
292293
</div>
293294
<div class="col-12">
294-
<script src='https://opencollective.com/wheels-fw/banner.js?style={"a":{"color":"var(--primary)"},"h2":{"fontWeight":"medium","fontSize":"18px"}}'></script>
295+
<script src='https://opencollective.com/wheels-dev/banner.js?style={"a":{"color":"rgb(191, 40, 33)"},"h2":{"fontWeight":"medium","fontSize":"18px"}}'></script>
295296
</div>
296297
</div>
297298
</div>
@@ -352,7 +353,6 @@
352353
</footer>
353354

354355

355-
<script src="/javascripts/jquery.min.js"></script>
356356
<script src="/javascripts/swiper.js"></script>
357357
<script src="/javascripts/custom.js"></script>
358358
<script src="/javascripts/infinite-scroll.pkgd.min.js"></script>

app/views/web/BlogController/create.cfm

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
<div class="mb-3">
4646
<label class="form-label mb-1 fs-14 fw-medium">
47-
Post Created Date
47+
Post Create Date
4848
</label>
4949
<input class="form-control fs-14" type="date" name="postCreatedDate" id="postCreatedDate" value="">
5050
</div>
@@ -107,8 +107,14 @@
107107
</div>
108108
</div>
109109
<div class="col-lg-4 col-12">
110-
<div class="bg-white rounded-5 shadow-sm mt-4 p-4">
111-
<h1 class="text-center fs-24 fw-bold">Preview</h1>
110+
<h4 class="mb-3">Live Preview</h4>
111+
<div id="previewContent" class="p-3 border rounded bg-white">
112+
<h2 id="previewTitle" class="fs-20 fw-bold mb-3 text-primary"></h2>
113+
<div id="previewMeta" class="mb-3">
114+
<div id="previewCategories" class="mb-1"></div>
115+
<div id="previewTags"></div>
116+
</div>
117+
<div id="previewBody" class="border p-3 rounded bg-light"></div>
112118
</div>
113119
</div>
114120
</div>
@@ -143,12 +149,15 @@
143149
const postTags = document.getElementById('postTags');
144150
const content = document.getElementById('content');
145151
const editor = document.getElementById("editor");
152+
const tagInput = document.getElementById("tagInput");
153+
const toolbar = document.getElementById('toolbar-container');
146154
147155
// Check if it's a draft submission
148156
const isDraft = document.getElementById("isDraft").value === "1";
149157
150158
// Reset validation styles
151-
[title, categoryId, posttypeId, postTags].forEach(field => field.classList.remove("is-invalid"));
159+
[title, categoryId, posttypeId, tagInput].forEach(field => field.classList.remove("is-invalid"));
160+
toolbar.classList.remove("border-danger");
152161
editor.classList.remove("border-danger");
153162
154163
// Validate fields only if it's NOT a draft
@@ -167,17 +176,19 @@
167176
}
168177
if (postTags.value.trim() === "") {
169178
isValid = false;
170-
postTags.classList.add("is-invalid");
179+
tagInput.classList.add("is-invalid");
180+
tagInput.classList.remove("border-0");
171181
}
172182
if (content.value.trim() === "<p><br></p>" || content.value.trim() === "") {
173183
isValid = false;
184+
toolbar.classList.add("border-danger");
174185
editor.classList.add("border-danger");
175186
}
176187
}
177188
178189
if (!isValid) {
179190
event.preventDefault();
180-
alert("Please fill out all required fields.");
191+
notifier.show('Error!', 'Please fill out all required fields.', '', 'images/high_priority-48.png', 4000);
181192
return false;
182193
}
183194
});
@@ -247,7 +258,43 @@
247258
function updateHiddenTags() {
248259
postTags.value = tags.join(",");
249260
}
261+
262+
// Live preview logic
263+
function updatePreview() {
264+
// Title
265+
const title = document.getElementById("title").value;
266+
document.getElementById("previewTitle").innerText = title;
267+
268+
// Content
269+
document.getElementById("previewBody").innerHTML = quill.root.innerHTML.trim();
270+
271+
// Categories
272+
const categorySelect = document.getElementById("categoryId");
273+
const selectedCategories = Array.from(categorySelect.selectedOptions).map(opt => opt.text);
274+
const previewCategories = document.getElementById("previewCategories");
275+
previewCategories.innerHTML = '';
276+
selectedCategories.forEach(cat => {
277+
const badge = document.createElement("span");
278+
badge.className = "badge bg-primary me-1 mb-1";
279+
badge.textContent = cat;
280+
previewCategories.appendChild(badge);
281+
});
282+
283+
// Tags
284+
const previewTags = document.getElementById("previewTags");
285+
previewTags.innerHTML = '';
286+
tags.forEach(tag => {
287+
const badge = document.createElement("span");
288+
badge.className = "badge bg-secondary me-1 mb-1";
289+
badge.textContent = tag;
290+
previewTags.appendChild(badge);
291+
});
292+
}
293+
294+
// Event listeners
295+
document.getElementById("title").addEventListener("input", updatePreview);
296+
document.getElementById("categoryId").addEventListener("change", updatePreview);
297+
quill.on('text-change', updatePreview);
250298
});
251-
252299
</script>
253300
</main>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<cfscript>
22
writeOutput('<option value="">Select Category</option>');
33
for (var i = 1; i <= categories.recordCount; i++) {
4-
writeOutput('<option value="' & categories.name[i] & '">' & categories.name[i] & '</option>');
4+
writeOutput('<option value="' & categories.id[i] & '">' & categories.name[i] & '</option>');
55
}
66
</cfscript>
Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
<div class="error-message">
2-
<cfif structKeyExists(url, "errorMessage")>
3-
<p>#url.errorMessage#</p>
4-
<cfelse>
5-
<p>An unexpected error has occurred. Please try again later.</p>
6-
</cfif>
7-
</div>
8-
9-
<style>
10-
.error-message {
11-
color: red;
12-
background-color: #f8d7da;
13-
border: 1px solid #f5c6cb;
14-
padding: 10px;
15-
margin: 10px 0;
16-
border-radius: 5px;
17-
}
18-
</style>
1+
<cfif structKeyExists(url, "errorMessage")>
2+
<script>
3+
document.addEventListener("DOMContentLoaded", function () {
4+
notifier.show("Error!", "#jsStringFormat(url.errorMessage)#", "", "/images/high_priority-48.png", 0);
5+
});
6+
</script>
7+
<cfelse>
8+
<script>
9+
document.addEventListener("DOMContentLoaded", function () {
10+
notifier.show("Error!", "An unexpected error has occurred. Please try again later.", "", "/images/high_priority-48.png", 0);
11+
});
12+
</script>
13+
</cfif>

app/views/web/BlogController/show.cfm

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
<div class="editor editor1 form-control border border-top-0 rounded-top-0" id="editor" style="height: 150px;"></div>
116116
<div class="mt-3 text-end">
117117
<input required class="form-control" type="hidden" name="content" id="content">
118-
<button type="submit" class="bg--iris fs-14 text-white px-3 py-2 rounded-2 flex-shrink-0">Post</button>
118+
<button type="submit" class="bg--primary fs-14 text-white px-3 py-2 rounded-2 flex-shrink-0">Post</button>
119119
</div>
120120
</div>
121121
</div>
@@ -135,17 +135,17 @@
135135
<p class="fs-14 fw-normal text-dark">#content#</p>
136136
<div class="d-flex flex-wrap justify-content-end align-items-center gap-4">
137137
<div class="d-flex cursor-pointer align-items-center gap-2">
138-
<p class="fs-14 text--iris mb-0 reply-btn" data-commentid="#Id#" data-blogid="#blog.Id#">Reply</p>
138+
<p class="fs-14 text--primary mb-0 reply-btn" data-commentid="#Id#" data-blogid="#blog.Id#">Reply</p>
139139

140140
<svg width="18" height="14" viewBox="0 0 18 14" fill="none"
141141
xmlns="http://www.w3.org/2000/svg">
142142
<path
143143
d="M1.42013 6.05185L5.66612 10.2979C5.76346 10.3952 5.81446 10.5099 5.81912 10.6419C5.82379 10.7745 5.77079 10.8959 5.66013 11.0059C5.55013 11.1125 5.43246 11.1665 5.30712 11.1679C5.18112 11.1699 5.06313 11.1159 4.95312 11.0059L0.565125 6.61685C0.477792 6.53019 0.416458 6.44119 0.381125 6.34985C0.345792 6.25919 0.328125 6.15985 0.328125 6.05185C0.328125 5.94385 0.345792 5.84452 0.381125 5.75385C0.416458 5.66319 0.477792 5.57419 0.565125 5.48685L4.95312 1.09785C5.04646 1.00452 5.16013 0.954521 5.29413 0.947854C5.42812 0.941187 5.55046 0.991187 5.66112 1.09785C5.77112 1.20785 5.82612 1.32685 5.82612 1.45485C5.82612 1.58285 5.77112 1.70185 5.66112 1.81185L1.42013 6.05185ZM6.03612 6.55185L9.78213 10.2979C9.87946 10.3952 9.93046 10.5099 9.93513 10.6419C9.93913 10.7745 9.88612 10.8959 9.77612 11.0059C9.66613 11.1125 9.54813 11.1665 9.42212 11.1679C9.29612 11.1692 9.17812 11.1152 9.06812 11.0059L4.68013 6.61685C4.59279 6.53019 4.53146 6.44119 4.49613 6.34985C4.46079 6.25919 4.44312 6.15985 4.44312 6.05185C4.44312 5.94385 4.46079 5.84452 4.49613 5.75385C4.53146 5.66319 4.59279 5.57419 4.68013 5.48685L9.06812 1.09785C9.16146 1.00452 9.27512 0.954521 9.40912 0.947854C9.54379 0.941187 9.66613 0.991187 9.77612 1.09785C9.88612 1.20785 9.94113 1.32685 9.94113 1.45485C9.94113 1.58285 9.88612 1.70185 9.77612 1.81185L6.03612 5.55185H13.4991C14.7418 5.55185 15.8025 5.99119 16.6811 6.86985C17.5598 7.74852 17.9991 8.80919 17.9991 10.0519V12.5519C17.9991 12.6945 17.9515 12.8135 17.8561 12.9089C17.7608 13.0042 17.6418 13.0519 17.4991 13.0519C17.3565 13.0519 17.2375 13.0042 17.1421 12.9089C17.0468 12.8135 16.9991 12.6945 16.9991 12.5519V10.0519C16.9991 9.09052 16.6561 8.26685 15.9701 7.58085C15.2841 6.89485 14.4605 6.55185 13.4991 6.55185H6.03612Z"
144-
fill="var(--iris)" />
144+
fill="var(--primary)" />
145145
</svg>
146146
</div>
147147
<div class="d-flex cursor-pointer align-items-center gap-2">
148-
<p class="fs-14 text--iris mb-0">#dateformat(publishedAt, 'MMM DD, YYYY')#</p>
148+
<p class="fs-14 text--primary mb-0">#dateformat(publishedAt, 'MMM DD, YYYY')#</p>
149149
</div>
150150
<!-- Reply Form (Hidden by Default) -->
151151
<div class="reply-form" id="reply-form-#Id#" style="display:none;width:100%;">
@@ -174,7 +174,7 @@
174174
<div class="editor editor2 form-control border border-top-0 rounded-top-0" id="editor" style="height: 150px;"></div>
175175
<input required class="form-control" type="hidden" name="content" id="content">
176176
<div class="mt-3 text-end">
177-
<button type="submit" class="bg--iris fs-14 text-white px-3 py-2 rounded-2 flex-shrink-0">Post</button>
177+
<button type="submit" class="bg--primary fs-14 text-white px-3 py-2 rounded-2 flex-shrink-0">Post</button>
178178
</div>
179179
</form>
180180
</div>

public/stylesheets/notifier.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)