Files
indiekit-endpoint-blogroll/views/blogroll-blog-edit.njk
Ricardo 2a98784381 fix: use upstream @indiekit/frontend form classes
Add .input, .select, .textarea, .label, .hint classes to all form
elements. Use input-button-group for discover URL. Replace custom
filter-select with upstream .select class. Remove duplicate CSS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 20:14:49 +01:00

216 lines
8.5 KiB
Plaintext

{% extends "layouts/blogroll.njk" %}
{% block blogroll %}
<form method="post" action="{% if isNew %}{{ baseUrl }}/blogs{% else %}{{ baseUrl }}/blogs/{{ blog._id }}{% endif %}" class="blogroll-form">
{% if isNew %}
<div class="blogroll-discover">
<div class="blogroll-field">
<label class="label" for="discoverUrl">{{ __("blogroll.blogs.form.discoverUrl") }}</label>
<div class="input-button-group">
<input class="input" type="url" id="discoverUrl" placeholder="https://tantek.com">
{{ button({ type: "button", text: __("blogroll.blogs.form.discover"), classes: "button--secondary", attributes: { id: "discoverBtn" } }) }}
</div>
<span class="hint">{{ __("blogroll.blogs.form.discoverHint") }}</span>
</div>
<div id="discoverResult" class="blogroll-discover__result" style="display: none;"></div>
</div>
<hr class="blogroll-divider">
{% endif %}
<div class="blogroll-field">
<label class="label" for="feedUrl">{{ __("blogroll.blogs.form.feedUrl") }}</label>
<input class="input" type="url" id="feedUrl" name="feedUrl" value="{{ blog.feedUrl if blog else '' }}" required placeholder="https://example.com/feed.xml">
<span class="hint">{{ __("blogroll.blogs.form.feedUrlHint") }}</span>
</div>
<div class="blogroll-field">
<label class="label" for="title">{{ __("blogroll.blogs.form.title") }}</label>
<input class="input" type="text" id="title" name="title" value="{{ blog.title if blog else '' }}" placeholder="{{ __('blogroll.blogs.form.titlePlaceholder') }}">
<span class="hint">{{ __("blogroll.blogs.form.titleHint") }}</span>
</div>
<div class="blogroll-field">
<label class="label" for="siteUrl">{{ __("blogroll.blogs.form.siteUrl") }}</label>
<input class="input" type="url" id="siteUrl" name="siteUrl" value="{{ blog.siteUrl if blog else '' }}" placeholder="https://example.com">
<span class="hint">{{ __("blogroll.blogs.form.siteUrlHint") }}</span>
</div>
<div class="blogroll-field">
<label class="label" for="category">{{ __("blogroll.blogs.form.category") }}</label>
<input class="input" type="text" id="category" name="category" value="{{ blog.category if blog else '' }}" placeholder="Technology">
<span class="hint">{{ __("blogroll.blogs.form.categoryHint") }}</span>
</div>
<div class="blogroll-field">
<label class="label" for="tags">{{ __("blogroll.blogs.form.tags") }}</label>
<input class="input" type="text" id="tags" name="tags" value="{{ blog.tags | join(', ') if blog and blog.tags else '' }}" placeholder="indie, personal, tech">
<span class="hint">{{ __("blogroll.blogs.form.tagsHint") }}</span>
</div>
<div class="blogroll-field">
<label class="label" for="notes">{{ __("blogroll.blogs.form.notes") }}</label>
<textarea class="textarea" id="notes" name="notes" placeholder="{{ __('blogroll.blogs.form.notesPlaceholder') }}">{{ blog.notes if blog else '' }}</textarea>
<span class="hint">{{ __("blogroll.blogs.form.notesHint") }}</span>
</div>
<div class="blogroll-field blogroll-field--inline">
<input type="checkbox" id="pinned" name="pinned" {% if blog and blog.pinned %}checked{% endif %}>
<label for="pinned">{{ __("blogroll.blogs.form.pinned") }}</label>
</div>
<div class="blogroll-field blogroll-field--inline">
<input type="checkbox" id="hidden" name="hidden" {% if blog and blog.hidden %}checked{% endif %}>
<label for="hidden">{{ __("blogroll.blogs.form.hidden") }}</label>
</div>
<div class="blogroll-actions">
{{ button({ type: "submit", text: __("blogroll.blogs.create") if isNew else __("blogroll.blogs.save") }) }}
{{ button({ href: baseUrl + "/blogs", text: __("blogroll.cancel"), classes: "button--secondary" }) }}
</div>
</form>
{% if not isNew and items %}
{% call section({ title: __("blogroll.blogs.recentItems") }) %}
{% if items.length > 0 %}
<ul class="blogroll-items-list">
{% for item in items %}
<li>
<div class="blogroll-item__title">
<a href="{{ item.url }}" target="_blank" rel="noopener">{{ item.title }}</a>
</div>
<div class="blogroll-item__meta">
{% if item.published %}{{ item.published | date("PPpp") }}{% endif %}
</div>
</li>
{% endfor %}
</ul>
{% else %}
{{ prose({ text: __("blogroll.blogs.noItems") }) }}
{% endif %}
{% endcall %}
{% endif %}
{% if isNew %}
<script>
(function() {
const discoverBtn = document.getElementById('discoverBtn');
const discoverUrl = document.getElementById('discoverUrl');
const discoverResult = document.getElementById('discoverResult');
const feedUrlInput = document.getElementById('feedUrl');
const titleInput = document.getElementById('title');
const siteUrlInput = document.getElementById('siteUrl');
function showResult(message, isError, isSuccess) {
discoverResult.style.display = 'block';
discoverResult.className = 'blogroll-discover__result' +
(isError ? ' blogroll-discover__result--error' : '') +
(isSuccess ? ' blogroll-discover__result--success' : '');
discoverResult.textContent = '';
const span = document.createElement('span');
span.textContent = message;
discoverResult.appendChild(span);
}
function showFeedUrl(message, url) {
discoverResult.style.display = 'block';
discoverResult.className = 'blogroll-discover__result blogroll-discover__result--success';
discoverResult.textContent = '';
const span = document.createElement('span');
span.textContent = message + ' ';
discoverResult.appendChild(span);
const code = document.createElement('code');
code.textContent = url;
discoverResult.appendChild(code);
}
discoverBtn.addEventListener('click', async function() {
const url = discoverUrl.value.trim();
if (!url) {
showResult('{{ __("blogroll.blogs.form.discoverNoUrl") }}', true, false);
return;
}
discoverBtn.disabled = true;
discoverBtn.textContent = '{{ __("blogroll.blogs.form.discovering") }}';
showResult('{{ __("blogroll.blogs.form.discoveringHint") }}', false, false);
try {
const response = await fetch('{{ baseUrl }}/api/discover?url=' + encodeURIComponent(url));
const data = await response.json();
if (!data.success) {
showResult(data.error || '{{ __("blogroll.blogs.form.discoverFailed") }}', true, false);
return;
}
if (data.feeds.length === 0) {
showResult('{{ __("blogroll.blogs.form.discoverNoFeeds") }}', true, false);
return;
}
// Auto-fill siteUrl and title if available
if (data.siteUrl) {
siteUrlInput.value = data.siteUrl;
}
if (data.pageTitle && !titleInput.value) {
titleInput.value = data.pageTitle;
}
// If only one feed, auto-select it
if (data.feeds.length === 1) {
feedUrlInput.value = data.feeds[0].url;
showFeedUrl('{{ __("blogroll.blogs.form.discoverFoundOne") }}', data.feeds[0].url);
return;
}
// Multiple feeds - let user choose
showResult('{{ __("blogroll.blogs.form.discoverFoundMultiple") }}', false, true);
const feedList = document.createElement('ul');
feedList.className = 'blogroll-discover__feeds';
data.feeds.forEach(function(feed) {
const li = document.createElement('li');
li.className = 'blogroll-discover__feed';
const typeSpan = document.createElement('span');
typeSpan.className = 'blogroll-discover__feed-type';
typeSpan.textContent = feed.type;
li.appendChild(typeSpan);
const urlSpan = document.createElement('span');
urlSpan.className = 'blogroll-discover__feed-url';
urlSpan.textContent = feed.url;
li.appendChild(urlSpan);
li.addEventListener('click', function() {
feedUrlInput.value = feed.url;
showFeedUrl('{{ __("blogroll.blogs.form.discoverSelected") }}', feed.url);
});
feedList.appendChild(li);
});
discoverResult.appendChild(feedList);
} catch (error) {
showResult(error.message || '{{ __("blogroll.blogs.form.discoverFailed") }}', true, false);
} finally {
discoverBtn.disabled = false;
discoverBtn.textContent = '{{ __("blogroll.blogs.form.discover") }}';
}
});
// Allow pressing Enter in the URL field
discoverUrl.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
discoverBtn.click();
}
});
})();
</script>
{% endif %}
{% endblock %}