Slug-based RSS URLs and success flash messages
Build and Deploy / build-and-deploy (push) Successful in 45s
Build and Deploy / build-and-deploy (push) Successful in 45s
- Add podcast_slug to users with global uniqueness check
- RSS available at /rss/{slug} (path-based) with legacy ?slug= fallback
- Slug field in dashboard settings with validation (lowercase, hyphens)
- JS flash messages for success/error after form submissions
- Remove unused imports
This commit is contained in:
+31
-7
@@ -12,6 +12,7 @@ type User struct {
|
||||
Email string
|
||||
PasswordHash string
|
||||
PodcastTitle string
|
||||
PodcastSlug string
|
||||
PodcastImage string
|
||||
PodcastAuthor string
|
||||
CreatedAt time.Time
|
||||
@@ -53,6 +54,7 @@ func migrate(db *sql.DB) error {
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
podcast_title TEXT NOT NULL DEFAULT '',
|
||||
podcast_slug TEXT NOT NULL DEFAULT '',
|
||||
podcast_image TEXT NOT NULL DEFAULT '',
|
||||
podcast_author TEXT NOT NULL DEFAULT '',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
@@ -95,8 +97,8 @@ func (s *Store) CreateUser(email, passwordHash string) (int64, error) {
|
||||
|
||||
func (s *Store) UserByEmail(email string) (*User, error) {
|
||||
u := &User{}
|
||||
err := s.db.QueryRow("SELECT id, email, password_hash, podcast_title, podcast_image, podcast_author, created_at FROM users WHERE email = ?", email).
|
||||
Scan(&u.ID, &u.Email, &u.PasswordHash, &u.PodcastTitle, &u.PodcastImage, &u.PodcastAuthor, &u.CreatedAt)
|
||||
err := s.db.QueryRow("SELECT id, email, password_hash, podcast_title, podcast_slug, podcast_image, podcast_author, created_at FROM users WHERE email = ?", email).
|
||||
Scan(&u.ID, &u.Email, &u.PasswordHash, &u.PodcastTitle, &u.PodcastSlug, &u.PodcastImage, &u.PodcastAuthor, &u.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -105,17 +107,39 @@ func (s *Store) UserByEmail(email string) (*User, error) {
|
||||
|
||||
func (s *Store) GetUser(id int64) (*User, error) {
|
||||
u := &User{}
|
||||
err := s.db.QueryRow("SELECT id, email, password_hash, podcast_title, podcast_image, podcast_author, created_at FROM users WHERE id = ?", id).
|
||||
Scan(&u.ID, &u.Email, &u.PasswordHash, &u.PodcastTitle, &u.PodcastImage, &u.PodcastAuthor, &u.CreatedAt)
|
||||
err := s.db.QueryRow("SELECT id, email, password_hash, podcast_title, podcast_slug, podcast_image, podcast_author, created_at FROM users WHERE id = ?", id).
|
||||
Scan(&u.ID, &u.Email, &u.PasswordHash, &u.PodcastTitle, &u.PodcastSlug, &u.PodcastImage, &u.PodcastAuthor, &u.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateUserPodcast(id int64, title, image, author string) error {
|
||||
_, err := s.db.Exec("UPDATE users SET podcast_title=?, podcast_image=?, podcast_author=? WHERE id=?",
|
||||
title, image, author, id)
|
||||
func (s *Store) UserBySlug(slug string) (*User, error) {
|
||||
u := &User{}
|
||||
err := s.db.QueryRow("SELECT id, email, password_hash, podcast_title, podcast_slug, podcast_image, podcast_author, created_at FROM users WHERE podcast_slug = ?", slug).
|
||||
Scan(&u.ID, &u.Email, &u.PasswordHash, &u.PodcastTitle, &u.PodcastSlug, &u.PodcastImage, &u.PodcastAuthor, &u.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *Store) SlugTaken(slug string, excludeUserID int64) (bool, error) {
|
||||
var id int64
|
||||
err := s.db.QueryRow("SELECT id FROM users WHERE podcast_slug = ? AND id != ?", slug, excludeUserID).Scan(&id)
|
||||
if err == sql.ErrNoRows {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateUserPodcast(id int64, title, slug, image, author string) error {
|
||||
_, err := s.db.Exec("UPDATE users SET podcast_title=?, podcast_slug=?, podcast_image=?, podcast_author=? WHERE id=?",
|
||||
title, slug, image, author, id)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user