Edit posts
Use fix routes for user profile edit handles to make it easier when user decides to change his username
This commit is contained in:
@@ -1,150 +1,151 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer utilities {
|
||||
.htmx-indicator {
|
||||
@apply hidden;
|
||||
}
|
||||
.htmx-indicator {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.htmx-request .htmx-indicator {
|
||||
@apply inline-flex items-center ml-2;
|
||||
}
|
||||
.htmx-request .htmx-indicator {
|
||||
@apply inline-flex items-center ml-2;
|
||||
}
|
||||
|
||||
#load-more .htmx-indicator {
|
||||
@apply block;
|
||||
}
|
||||
#load-more .htmx-indicator {
|
||||
@apply block;
|
||||
}
|
||||
|
||||
.htmx-request .continue-text {
|
||||
@apply hidden;
|
||||
}
|
||||
.htmx-request .continue-text {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.prose-compact {
|
||||
@apply prose prose-slate max-w-none;
|
||||
.prose-compact {
|
||||
@apply prose prose-slate max-w-none;
|
||||
|
||||
--tw-prose-body: theme(colors.gray.700);
|
||||
--tw-prose-headings: theme(colors.gray.900);
|
||||
--tw-prose-links: theme(colors.blue.600);
|
||||
--tw-prose-code: theme(colors.gray.800);
|
||||
}
|
||||
--tw-prose-body: theme(colors.gray.700);
|
||||
--tw-prose-headings: theme(colors.gray.900);
|
||||
--tw-prose-links: theme(colors.blue.600);
|
||||
--tw-prose-code: theme(colors.gray.800);
|
||||
}
|
||||
|
||||
.prose-compact p {
|
||||
@apply mb-2 mt-0;
|
||||
}
|
||||
.prose-compact p {
|
||||
@apply mb-2 mt-0;
|
||||
}
|
||||
|
||||
.prose-compact h1 {
|
||||
@apply pb-2 mb-3 border-b-2 border-gray-100;
|
||||
}
|
||||
.prose-compact h1 {
|
||||
@apply pb-2 mb-3 border-b-2 border-gray-200;
|
||||
}
|
||||
|
||||
.prose-compact h2 {
|
||||
@apply mt-4 pb-2 mb-3 border-b-2 border-gray-100 font-semibold;
|
||||
}
|
||||
.prose-compact h2 {
|
||||
@apply mt-4 pb-2 mb-3 border-b-2 border-gray-200 font-semibold;
|
||||
}
|
||||
|
||||
.prose-compact h3 {
|
||||
@apply mt-3 mb-1;
|
||||
}
|
||||
.prose-compact h3 {
|
||||
@apply mt-3 mb-1;
|
||||
}
|
||||
|
||||
.prose-compact h4,
|
||||
.prose-compact h5,
|
||||
.prose-compact h6 {
|
||||
@apply mt-2 mb-1;
|
||||
}
|
||||
.prose-compact h4,
|
||||
.prose-compact h5,
|
||||
.prose-compact h6 {
|
||||
@apply mt-2 mb-1;
|
||||
}
|
||||
|
||||
.prose-compact ul,
|
||||
.prose-compact ol {
|
||||
@apply my-2 space-y-0;
|
||||
}
|
||||
.prose-compact ul,
|
||||
.prose-compact ol {
|
||||
@apply my-2 space-y-0;
|
||||
}
|
||||
|
||||
.prose-compact li {
|
||||
@apply my-0;
|
||||
}
|
||||
.prose-compact li {
|
||||
@apply my-0;
|
||||
}
|
||||
|
||||
.prose-compact blockquote {
|
||||
@apply my-3 py-2;
|
||||
}
|
||||
.prose-compact blockquote {
|
||||
@apply my-3 py-2;
|
||||
}
|
||||
|
||||
.prose-compact img {
|
||||
@apply m-0 align-top;
|
||||
}
|
||||
.prose-compact img {
|
||||
@apply m-0 align-top;
|
||||
}
|
||||
|
||||
.prose-compact a:has(img) {
|
||||
@apply no-underline border-0 inline-block align-top;
|
||||
}
|
||||
.prose-compact a:has(img) {
|
||||
@apply no-underline border-0 inline-block align-top;
|
||||
}
|
||||
|
||||
.prose-compact a img {
|
||||
@apply inline-block align-top;
|
||||
}
|
||||
.prose-compact a img {
|
||||
@apply inline-block align-top;
|
||||
}
|
||||
|
||||
.prose-compact :not(pre) > code {
|
||||
@apply bg-gray-100 text-gray-800 px-1.5 py-0.5 rounded text-sm font-mono font-normal;
|
||||
}
|
||||
.prose-compact :not(pre) > code {
|
||||
@apply bg-gray-100 text-gray-800 px-1.5 py-0.5 rounded text-sm font-mono font-normal;
|
||||
}
|
||||
|
||||
.prose-compact :not(pre) > code::before,
|
||||
.prose-compact :not(pre) > code::after {
|
||||
content: none !important;
|
||||
}
|
||||
.prose-compact :not(pre) > code::before,
|
||||
.prose-compact :not(pre) > code::after {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.prose-compact pre {
|
||||
@apply my-3 p-4 bg-gray-100 text-gray-800 rounded-sm overflow-x-auto border border-gray-200;
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
width: 0;
|
||||
min-width: 100%;
|
||||
}
|
||||
.prose-compact pre {
|
||||
@apply my-3 p-4 bg-gray-100 text-gray-800 rounded-sm overflow-x-auto border border-gray-200;
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
width: 0;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.prose-compact pre code {
|
||||
@apply bg-transparent text-gray-800 p-0 rounded-none;
|
||||
}
|
||||
.prose-compact pre code {
|
||||
@apply bg-transparent text-gray-800 p-0 rounded-none;
|
||||
}
|
||||
|
||||
.prose-compact pre code::before,
|
||||
.prose-compact pre code::after {
|
||||
content: none !important;
|
||||
}
|
||||
.prose-compact pre code::before,
|
||||
.prose-compact pre code::after {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.prose-compact table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
@apply my-6;
|
||||
font-size: 14px;
|
||||
line-height: 1.45;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.prose-compact table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
@apply my-6;
|
||||
font-size: 14px;
|
||||
line-height: 1.45;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.prose-compact table thead,
|
||||
.prose-compact table tbody {
|
||||
display: table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.prose-compact table thead,
|
||||
.prose-compact table tbody {
|
||||
display: table;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.prose-compact table tr {
|
||||
display: table-row;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
}
|
||||
.prose-compact table tr {
|
||||
display: table-row;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
}
|
||||
|
||||
.prose-compact table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
.prose-compact table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
.prose-compact table th,
|
||||
.prose-compact table td {
|
||||
display: table-cell;
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
min-width: 0;
|
||||
}
|
||||
.prose-compact table th,
|
||||
.prose-compact table td {
|
||||
display: table-cell;
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.prose-compact table th {
|
||||
font-weight: 600;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
.prose-compact table th {
|
||||
font-weight: 600;
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ post.title }}{% endblock %}
|
||||
{% block title %}Edit: {{ post.title }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="max-w-3xl mx-auto">
|
||||
<article>
|
||||
<header class="mb-4">
|
||||
<h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-4 leading-tight">{{ post.title }}</h1>
|
||||
<h1 class="text-4xl font-bold text-gray-900 mb-4 leading-tight">{{ post.title }}</h1>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between text-sm text-gray-600">
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="flex items-center">
|
||||
@@ -33,9 +33,70 @@
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
{% if session_username.as_deref() == Some(post.author) %}
|
||||
<div class="mt-4 sm:mt-0">
|
||||
<button onclick="document.getElementById('edit-form').classList.toggle('hidden')"
|
||||
class="inline-flex items-center px-3 py-1.5 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md transition-colors">
|
||||
<svg class="w-4 h-4 mr-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
|
||||
</svg>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
<div class="prose-compact">{{ post.content | safe }}</div>
|
||||
|
||||
{% if session_username.as_deref() == Some(post.author) %}
|
||||
<div id="edit-form" class="hidden bg-gray-50 border border-gray-200 rounded-lg p-6">
|
||||
<h2 class="text-xl font-bold text-gray-900 mb-4">Edit post</h2>
|
||||
<form hx-put="/posts/{{ post.post_id }}"
|
||||
hx-target="#edit-messages"
|
||||
hx-swap="innerHTML">
|
||||
<div class="mb-4">
|
||||
<label for="title" class="block text-sm font-medium text-gray-700 mb-2">Title</label>
|
||||
<input type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
value="{{ post.title }}"
|
||||
required
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="content" class="block text-sm font-medium text-gray-700 mb-2">Content (markdown)</label>
|
||||
<textarea id="content"
|
||||
name="content"
|
||||
rows="12"
|
||||
required
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 font-mono text-sm">{{ post.content }}</textarea>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<button type="submit"
|
||||
class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-md transition-colors">
|
||||
<svg class="w-4 h-4 mr-2"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M5 13l4 4L19 7"/>
|
||||
</svg>
|
||||
Save changes
|
||||
</button>
|
||||
<button type="button"
|
||||
onclick="document.getElementById('edit-form').classList.add('hidden')"
|
||||
class="inline-flex items-center px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 font-medium rounded-md transition-colors">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="edit-messages" class="mt-6"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="content-display" class="prose-compact">{{ post_html | safe }}</div>
|
||||
</article>
|
||||
<div class="mt-8">{% include "posts/comments/list.html" %}</div>
|
||||
<div class="mt-8 bg-gradient-to-r from-blue-600 to-indigo-700 rounded-lg shadow-lg text-white p-8 text-center">
|
||||
@@ -47,4 +108,4 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -1,10 +1,11 @@
|
||||
<div class="bg-white rounded-lg shadow-md border border-gray-200 p-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-6">Profile Information</h2>
|
||||
|
||||
<form hx-put="/users/{{ user.username }}/edit"
|
||||
<form hx-put="/users/edit"
|
||||
hx-target="#edit-messages"
|
||||
hx-swap="innerHTML"
|
||||
class="space-y-6">
|
||||
<input type="hidden" name="user_id" value="{{ user.user_id }}" />
|
||||
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">
|
||||
@@ -45,7 +46,7 @@
|
||||
|
||||
<button type="submit"
|
||||
class="w-full bg-blue-600 text-white hover:bg-blue-700 font-medium py-2 px-4 rounded-md transition-colors">
|
||||
Save Changes
|
||||
Save changes
|
||||
</button>
|
||||
|
||||
<div id="edit-messages"></div>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if session_username.as_deref() == Some(user.username) %}
|
||||
<a href="/users/{{ user.username }}/edit"
|
||||
<a href="/users/edit"
|
||||
class="inline-flex items-center text-sm text-blue-600 hover:text-blue-700 font-medium mb-3">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
|
||||
Reference in New Issue
Block a user