summaryrefslogtreecommitdiffhomepage
path: root/backend/src
diff options
context:
space:
mode:
authorrealtradam <[email protected]>2024-07-28 20:00:49 -0400
committerrealtradam <[email protected]>2024-07-28 20:00:49 -0400
commitfc34d9853386b6dbf270a10862a47a052f1fb151 (patch)
tree20ebca59324d88eab8b867306dd251a27cd91699 /backend/src
parentc24839e8f8b4b6868f8ee383b589ce01dcdc81e1 (diff)
downloadspring-blog-dev.tar.gz
spring-blog-dev.zip
code cleanupdev
Diffstat (limited to 'backend/src')
-rw-r--r--backend/src/main/java/com/blog/web/controllers/ArticleController.java6
-rw-r--r--backend/src/main/java/com/blog/web/models/Article.java18
-rw-r--r--backend/src/main/java/com/blog/web/models/UserEntity.java22
-rw-r--r--backend/src/main/java/com/blog/web/repository/ArticleRepository.java5
-rw-r--r--backend/src/main/java/com/blog/web/services/ArticleService.java8
-rw-r--r--backend/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java44
-rw-r--r--backend/src/main/java/com/blog/web/services/impl/UserServiceImpl.java9
-rw-r--r--backend/src/main/resources/application.properties2
-rw-r--r--backend/src/main/resources/templates/articles-list.html14
-rw-r--r--backend/src/main/resources/templates/articles/edit.html15
-rw-r--r--backend/src/main/resources/templates/articles/new.html94
-rw-r--r--backend/src/main/resources/templates/articles/show.html32
-rw-r--r--backend/src/main/resources/templates/auth/login.html4
-rw-r--r--backend/src/main/resources/templates/auth/register.html13
-rw-r--r--backend/src/main/resources/templates/index.html46
-rw-r--r--backend/src/main/resources/templates/layout.html59
-rw-r--r--backend/src/main/resources/templates/post.html117
17 files changed, 314 insertions, 194 deletions
diff --git a/backend/src/main/java/com/blog/web/controllers/ArticleController.java b/backend/src/main/java/com/blog/web/controllers/ArticleController.java
index e7890b0..fef8c63 100644
--- a/backend/src/main/java/com/blog/web/controllers/ArticleController.java
+++ b/backend/src/main/java/com/blog/web/controllers/ArticleController.java
@@ -12,8 +12,8 @@ import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
-import java.util.List;
import java.util.Optional;
+import java.util.Set;
@CrossOrigin(origins = "http://localhost:5173", allowCredentials = "true", allowedHeaders = "*")
@RestController
@@ -41,8 +41,8 @@ public class ArticleController {
}
@GetMapping("/articles")
- public List<ArticlePublicDto> listArticles(@RequestParam(value = "search", required = false) Optional<String> search) {
- final List<ArticlePublicDto> articles;
+ public Set<ArticlePublicDto> listArticles(@RequestParam(value = "search", required = false) Optional<String> search) {
+ final Set<ArticlePublicDto> articles;
if (search.isPresent()) {
articles = articleService.searchPublicArticles(search.get());
} else {
diff --git a/backend/src/main/java/com/blog/web/models/Article.java b/backend/src/main/java/com/blog/web/models/Article.java
index ed4ac1c..58fcca3 100644
--- a/backend/src/main/java/com/blog/web/models/Article.java
+++ b/backend/src/main/java/com/blog/web/models/Article.java
@@ -6,12 +6,13 @@ import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
+import java.util.Optional;
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long id;
+ private final long id;
private String title;
private String photoUrl;
private String content;
@@ -23,7 +24,7 @@ public class Article {
@JoinColumn(name = "created_by", nullable = false)
private UserEntity createdBy;
- public Article(Long id, String title, String photoUrl, String content, UserEntity createdBy, LocalDateTime createdOn, LocalDateTime updatedOn) {
+ public Article(long id, String title, String photoUrl, String content, UserEntity createdBy, LocalDateTime createdOn, LocalDateTime updatedOn) {
this.id = id;
this.title = title;
this.photoUrl = photoUrl;
@@ -33,11 +34,8 @@ public class Article {
this.updatedOn = updatedOn;
}
- public Article() {
- }
-
public Article(ArticleDto articleDto) {
- this.id = articleDto.getId();
+ this.id = Optional.ofNullable(articleDto.getId()).orElse(0L);
this.title = articleDto.getTitle();
this.photoUrl = articleDto.getPhotoUrl();
this.content = articleDto.getContent();
@@ -46,12 +44,12 @@ public class Article {
this.updatedOn = articleDto.getUpdatedOn();
}
- public Long getId() {
- return id;
+ public Article() {
+ this.id = 0;
}
- public void setId(Long id) {
- this.id = id;
+ public long getId() {
+ return id;
}
public String getTitle() {
diff --git a/backend/src/main/java/com/blog/web/models/UserEntity.java b/backend/src/main/java/com/blog/web/models/UserEntity.java
index 089b8bc..f74308b 100644
--- a/backend/src/main/java/com/blog/web/models/UserEntity.java
+++ b/backend/src/main/java/com/blog/web/models/UserEntity.java
@@ -1,12 +1,11 @@
package com.blog.web.models;
import jakarta.persistence.*;
+import jakarta.validation.constraints.NotEmpty;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -15,13 +14,18 @@ import java.util.stream.Collectors;
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
- private long id;
+ private final long id = 0;
+ @NotEmpty
+ @Column(unique = true)
private String username;
+ @NotEmpty
+ @Column(unique = true)
private String email;
+ @NotEmpty
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "user_roles", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
- private Set<Role> roles = new HashSet<>();
+ private final Set<Role> roles = new HashSet<>();
public UserEntity(String username, String email, String password, HashSet<Role> roles) {
this.username = username;
@@ -39,17 +43,13 @@ public class UserEntity {
}
public User toSecurityUser() {
- return new User(this.getEmail(), this.getPassword(), this.getRoles().stream().map((role) -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList()));
+ return new User(this.getEmail(), this.password, this.getRoles().stream().map((role) -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList()));
}
public long getId() {
return id;
}
- public void setId(long id) {
- this.id = id;
- }
-
public String getUsername() {
return username;
}
@@ -66,10 +66,6 @@ public class UserEntity {
this.email = email;
}
- public String getPassword() {
- return password;
- }
-
public void setPassword(String password) {
this.password = password;
}
diff --git a/backend/src/main/java/com/blog/web/repository/ArticleRepository.java b/backend/src/main/java/com/blog/web/repository/ArticleRepository.java
index e48f156..1ddb394 100644
--- a/backend/src/main/java/com/blog/web/repository/ArticleRepository.java
+++ b/backend/src/main/java/com/blog/web/repository/ArticleRepository.java
@@ -4,10 +4,9 @@ import com.blog.web.models.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
-import java.util.HashSet;
-import java.util.List;
+import java.util.Set;
public interface ArticleRepository extends JpaRepository<Article, Long> {
@Query("SELECT a from Article a WHERE a.title LIKE CONCAT('%', :search, '%')")
- List<Article> searchArticles(String search);
+ Set<Article> searchArticles(String search);
}
diff --git a/backend/src/main/java/com/blog/web/services/ArticleService.java b/backend/src/main/java/com/blog/web/services/ArticleService.java
index 4bf3028..5ec0175 100644
--- a/backend/src/main/java/com/blog/web/services/ArticleService.java
+++ b/backend/src/main/java/com/blog/web/services/ArticleService.java
@@ -4,11 +4,11 @@ import com.blog.web.dto.ArticleDto;
import com.blog.web.dto.ArticlePublicDto;
import com.blog.web.models.Article;
-import java.util.List;
import java.util.Optional;
+import java.util.Set;
public interface ArticleService {
- List<ArticlePublicDto> findAllArticles();
+ Set<ArticlePublicDto> findAllArticles();
Optional<Article> saveArticle(ArticleDto article);
@@ -18,9 +18,7 @@ public interface ArticleService {
boolean delete(long articleId);
- //List<ArticleDto> searchArticles(String search);
-
ArticlePublicDto findArticlePublicById(long articleId);
- List<ArticlePublicDto> searchPublicArticles(String search);
+ Set<ArticlePublicDto> searchPublicArticles(String search);
}
diff --git a/backend/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java b/backend/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java
index 04cc8be..871a2bf 100644
--- a/backend/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java
+++ b/backend/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java
@@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
import static com.blog.web.mappers.ArticleMapper.*;
@@ -32,9 +33,9 @@ public class ArticleServiceImpl implements ArticleService {
@Override
- public List<ArticlePublicDto> findAllArticles() {
+ public Set<ArticlePublicDto> findAllArticles() {
List<Article> articles = articleRepository.findAll();
- return articles.stream().map(ArticleMapper::mapToArticlePublicDto).collect(Collectors.toList());
+ return articles.stream().map(ArticleMapper::mapToArticlePublicDto).collect(Collectors.toSet());
}
@Override
@@ -52,28 +53,35 @@ public class ArticleServiceImpl implements ArticleService {
@Override
public Optional<ArticleDto> findArticleById(long articleId) {
final Optional<Article> otpArticle = articleRepository.findById(articleId);
- if(otpArticle.isEmpty()) {
+ if (otpArticle.isEmpty()) {
return Optional.empty();
- }
- else {
+ } else {
return Optional.of(mapToArticleDto(otpArticle.get()));
}
}
@Override
public void updateArticle(ArticleDto newArticle) {
- if(newArticle == null) { return; }
+ if (newArticle == null) {
+ return;
+ }
final Optional<ArticleDto> optExistingArticle = this.findArticleById(newArticle.getId());
- if(optExistingArticle.isEmpty()) { return; } // cant find article, give up
+ if (optExistingArticle.isEmpty()) {
+ return;
+ } // cant find article, give up
final ArticleDto existingArticle = optExistingArticle.get();
Long ownerId = existingArticle.getUserId();
final Optional<UserEntity> optUser = userService.getLoggedInUser();
- if (optUser.isEmpty()) { return; } // not logged in, not allowed to edit
+ if (optUser.isEmpty()) {
+ return;
+ } // not logged in, not allowed to edit
final UserEntity user = optUser.get();
Long userId = user.getId();
- if (!ownerId.equals(userId)) { return; } // logged in a different user, not allowed to edit
+ if (!ownerId.equals(userId)) {
+ return;
+ } // logged in a different user, not allowed to edit
final Article article = mapToArticle(newArticle);
article.setCreatedBy(user);
@@ -83,16 +91,22 @@ public class ArticleServiceImpl implements ArticleService {
@Override
public boolean delete(long articleId) {
final Optional<ArticleDto> optArticle = this.findArticleById(articleId);
- if(optArticle.isEmpty()) { return false; } // cant find article, give up
+ if (optArticle.isEmpty()) {
+ return false;
+ } // cant find article, give up
final ArticleDto article = optArticle.get();
String ownerId = article.getUsername();
final Optional<UserEntity> optUser = userService.getLoggedInUser();
- if (optUser.isEmpty()) { return false; } // not logged in, not allowed to delete
+ if (optUser.isEmpty()) {
+ return false;
+ } // not logged in, not allowed to delete
final UserEntity user = optUser.get();
String userId = user.getUsername();
- if (!ownerId.equals(userId)) { return false; } // logged in a different user, not allowed to delete
+ if (!ownerId.equals(userId)) {
+ return false;
+ } // logged in a different user, not allowed to delete
else {
articleRepository.deleteById(articleId);
return true;
@@ -105,8 +119,8 @@ public class ArticleServiceImpl implements ArticleService {
}
@Override
- public List<ArticlePublicDto> searchPublicArticles(String search) {
- List<Article> articles = articleRepository.searchArticles(search);
- return articles.stream().map(article -> mapToArticlePublicDto(article)).collect(Collectors.toList());
+ public Set<ArticlePublicDto> searchPublicArticles(String search) {
+ Set<Article> articles = articleRepository.searchArticles(search);
+ return articles.stream().map(article -> mapToArticlePublicDto(article)).collect(Collectors.toSet());
}
}
diff --git a/backend/src/main/java/com/blog/web/services/impl/UserServiceImpl.java b/backend/src/main/java/com/blog/web/services/impl/UserServiceImpl.java
index b39d15e..9ca8b0b 100644
--- a/backend/src/main/java/com/blog/web/services/impl/UserServiceImpl.java
+++ b/backend/src/main/java/com/blog/web/services/impl/UserServiceImpl.java
@@ -10,7 +10,8 @@ import com.blog.web.services.UserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Optional;
@Service
public class UserServiceImpl implements UserService {
@@ -26,7 +27,9 @@ public class UserServiceImpl implements UserService {
@Override
public void saveUser(RegistrationDto registrationDto) {
- final HashSet<Role> roles = (HashSet<Role>) Set.of(roleRepository.findByName("User").orElse(new Role()));
+ final HashSet<Role> roles = new HashSet<Role>() {{
+ add(roleRepository.findByName("User").get());
+ }};
userRepository.save(new UserEntity(registrationDto.getUsername(), registrationDto.getEmail(), passwordEncoder.encode(registrationDto.getPassword()), roles));
}
@@ -43,7 +46,7 @@ public class UserServiceImpl implements UserService {
public Optional<UserEntity> getLoggedInUser() {
final Optional<UserEntity> user;
Optional<String> optUsername = Optional.ofNullable(SecurityUtil.getSessionUser());
- if(optUsername.isPresent()) {
+ if (optUsername.isPresent()) {
user = this.findByUsername(optUsername.get());
} else {
user = Optional.empty();
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 102e2c2..3f985f6 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -2,9 +2,7 @@ spring.application.name=web
spring.datasource.url=jdbc:postgresql://localhost:5432/spring
spring.datasource.username=tradam
spring.datasource.driver-class-name=org.postgresql.Driver
-
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
-
spring.security.user.name=zxcv
spring.security.user.password=zxcv
diff --git a/backend/src/main/resources/templates/articles-list.html b/backend/src/main/resources/templates/articles-list.html
index 799c751..3e133df 100644
--- a/backend/src/main/resources/templates/articles-list.html
+++ b/backend/src/main/resources/templates/articles-list.html
@@ -5,12 +5,12 @@
<title>Title</title>
</head>
<body>
- <h1>blah blah</h1>
- <div th:each="article :${articles}" style="">
- <div>my aga article</div>
- <h2 th:text="${article.title}"></h2>
- <img th:src="${article.photoUrl}" alt="..."/>
- <p th:text="${article.content}"></p>
- </div>
+<h1>blah blah</h1>
+<div th:each="article :${articles}" style="">
+ <div>my aga article</div>
+ <h2 th:text="${article.title}"></h2>
+ <img th:src="${article.photoUrl}" alt="..."/>
+ <p th:text="${article.content}"></p>
+</div>
</body>
</html> \ No newline at end of file
diff --git a/backend/src/main/resources/templates/articles/edit.html b/backend/src/main/resources/templates/articles/edit.html
index f4faee9..d48bd14 100644
--- a/backend/src/main/resources/templates/articles/edit.html
+++ b/backend/src/main/resources/templates/articles/edit.html
@@ -7,7 +7,8 @@
<body layout:fragment="content">
<div class="flex justify-center bg-white p-12">
- <form th:action="@{/articles/edit/{articleId}(articleId=${article.id})}" th:object="${article}" method="post" class="w-full max-w-lg">
+ <form th:action="@{/articles/edit/{articleId}(articleId=${article.id})}" th:object="${article}" method="post"
+ class="w-full max-w-lg">
<input type="hidden" th:field="*{id}">
<div class="flex flex-wrap -mx-3 mb-6">
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
@@ -21,7 +22,8 @@
name="title"
th:field="*{title}"
placeholder="Yep">
- <p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-red-500 text-xs italic">Please
+ fill out this field.</p>
</div>
<div class="w-full md:w-1/2 px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
@@ -34,7 +36,8 @@
name="photoUrl"
th:field="*{photoUrl}"
placeholder="Doe">
- <p th:if="${#fields.hasErrors('photoUrl')}" th:errors="*{photoUrl}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('photoUrl')}" th:errors="*{photoUrl}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
@@ -49,12 +52,14 @@
name="content"
th:field="*{content}"
placeholder="Doe">
- <p th:if="${#fields.hasErrors('content')}" th:errors="*{content}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('content')}" th:errors="*{content}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
</div>
</div>
<div class="flex flex-wrap mb-2">
</div>
- <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Update</button>
+ <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Update
+ </button>
</form>
</div>
diff --git a/backend/src/main/resources/templates/articles/new.html b/backend/src/main/resources/templates/articles/new.html
index f5924d6..fec6d6f 100644
--- a/backend/src/main/resources/templates/articles/new.html
+++ b/backend/src/main/resources/templates/articles/new.html
@@ -7,55 +7,59 @@
<body layout:fragment="content">
<div class="flex justify-center bg-white p-12">
-<form th:action="@{/articles/new}" th:object="${article}" method="post" class="w-full max-w-lg">
- <div class="flex flex-wrap -mx-3 mb-6">
- <div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
- <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
- for="title">
- Title
- </label>
- <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
- id="title"
- type="text"
- name="title"
- th:field="*{title}"
- placeholder="Yep">
- <p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <form th:action="@{/articles/new}" th:object="${article}" method="post" class="w-full max-w-lg">
+ <div class="flex flex-wrap -mx-3 mb-6">
+ <div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
+ <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
+ for="title">
+ Title
+ </label>
+ <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-red-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
+ id="title"
+ type="text"
+ name="title"
+ th:field="*{title}"
+ placeholder="Yep">
+ <p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-red-500 text-xs italic">Please
+ fill out this field.</p>
+ </div>
+ <div class="w-full md:w-1/2 px-3">
+ <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
+ for="photoUrl">
+ Photo URL
+ </label>
+ <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
+ id="photoUrl"
+ type="text"
+ name="photoUrl"
+ th:field="*{photoUrl}"
+ placeholder="Doe">
+ <p th:if="${#fields.hasErrors('photoUrl')}" th:errors="*{photoUrl}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
+ </div>
</div>
- <div class="w-full md:w-1/2 px-3">
- <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
- for="photoUrl">
- Photo URL
- </label>
- <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
- id="photoUrl"
- type="text"
- name="photoUrl"
- th:field="*{photoUrl}"
- placeholder="Doe">
- <p th:if="${#fields.hasErrors('photoUrl')}" th:errors="*{photoUrl}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <div class="flex flex-wrap -mx-3 mb-6">
+ <div class="w-full px-3">
+ <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
+ for="content">
+ Content
+ </label>
+ <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
+ id="content"
+ type="text"
+ name="content"
+ th:field="*{content}"
+ placeholder="Doe">
+ <p th:if="${#fields.hasErrors('content')}" th:errors="*{content}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
+ </div>
</div>
- </div>
- <div class="flex flex-wrap -mx-3 mb-6">
- <div class="w-full px-3">
- <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
- for="content">
- Content
- </label>
- <input class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
- id="content"
- type="text"
- name="content"
- th:field="*{content}"
- placeholder="Doe">
- <p th:if="${#fields.hasErrors('content')}" th:errors="*{content}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <div class="flex flex-wrap mb-2">
</div>
- </div>
- <div class="flex flex-wrap mb-2">
- </div>
- <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Create</button>
+ <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Create
+ </button>
-</form>
+ </form>
</div>
</body>
diff --git a/backend/src/main/resources/templates/articles/show.html b/backend/src/main/resources/templates/articles/show.html
index 206aaae..0912e8e 100644
--- a/backend/src/main/resources/templates/articles/show.html
+++ b/backend/src/main/resources/templates/articles/show.html
@@ -7,7 +7,6 @@
<body layout:fragment="content">
-
<!--Title-->
<div class="text-center pt-16 md:pt-32">
<p th:text="${article.createdOn}" class="text-sm md:text-base text-green-500 font-bold"></p>
@@ -15,14 +14,16 @@
</div>
<!--image-->
-<div class="container w-full max-w-6xl mx-auto bg-white bg-cover mt-8 rounded" th:style="'background:url(' + @{${article.photoUrl}} + '); height: 75vh;'"></div>
+<div class="container w-full max-w-6xl mx-auto bg-white bg-cover mt-8 rounded"
+ th:style="'background:url(' + @{${article.photoUrl}} + '); height: 75vh;'"></div>
<!--Container-->
<div class="container max-w-5xl mx-auto -mt-32">
<div class="mx-0 sm:mx-6">
- <div class="bg-white w-full p-8 md:p-24 text-xl md:text-2xl text-gray-800 leading-normal" style="font-family:Georgia,serif;">
+ <div class="bg-white w-full p-8 md:p-24 text-xl md:text-2xl text-gray-800 leading-normal"
+ style="font-family:Georgia,serif;">
<!--Post Content-->
@@ -36,12 +37,17 @@
<!--Subscribe-->
<div class="container font-sans bg-green-100 rounded mt-8 p-4 md:p-24 text-center">
<h2 class="font-bold break-normal text-2xl md:text-4xl">Subscribe to Ghostwind CSS</h2>
- <h3 class="font-bold break-normal font-normal text-gray-600 text-base md:text-xl">Get the latest posts delivered right to your inbox</h3>
+ <h3 class="font-bold break-normal font-normal text-gray-600 text-base md:text-xl">Get the latest posts
+ delivered right to your inbox</h3>
<div class="w-full text-center pt-4">
<form action="#">
<div class="max-w-sm mx-auto p-1 pr-0 flex flex-wrap items-center">
- <input type="email" placeholder="[email protected]" class="flex-1 appearance-none rounded shadow p-3 text-gray-600 mr-2 focus:outline-none">
- <button type="submit" class="flex-1 mt-4 md:mt-0 block md:inline-block appearance-none bg-green-500 text-white text-base font-semibold tracking-wider uppercase py-4 rounded shadow hover:bg-green-400">Subscribe</button>
+ <input type="email" placeholder="[email protected]"
+ class="flex-1 appearance-none rounded shadow p-3 text-gray-600 mr-2 focus:outline-none">
+ <button type="submit"
+ class="flex-1 mt-4 md:mt-0 block md:inline-block appearance-none bg-green-500 text-white text-base font-semibold tracking-wider uppercase py-4 rounded shadow hover:bg-green-400">
+ Subscribe
+ </button>
</div>
</form>
</div>
@@ -54,7 +60,9 @@
<img class="w-10 h-10 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author">
<div class="flex-1">
<p class="text-base font-bold text-base md:text-xl leading-none">Ghostwind CSS</p>
- <p class="text-gray-600 text-xs md:text-base">Tailwind CSS version of Ghost's Casper theme by <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500" href="https://www.tailwindtoolbox.com">TailwindToolbox.com</a></p>
+ <p class="text-gray-600 text-xs md:text-base">Tailwind CSS version of Ghost's Casper theme by <a
+ class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500"
+ href="https://www.tailwindtoolbox.com">TailwindToolbox.com</a></p>
</div>
<div class="justify-end">
@@ -74,11 +82,13 @@
<svg class="progress-circle" width="100%" height="100%" viewBox="-1 -1 102 102">
<path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/>
</svg>
- <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24"
+ viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round"
+ stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <line x1="12" y1="5" x2="12" y2="19" />
- <line x1="18" y1="11" x2="12" y2="5" />
- <line x1="6" y1="11" x2="12" y2="5" />
+ <line x1="12" y1="5" x2="12" y2="19"/>
+ <line x1="18" y1="11" x2="12" y2="5"/>
+ <line x1="6" y1="11" x2="12" y2="5"/>
</svg>
</button>
diff --git a/backend/src/main/resources/templates/auth/login.html b/backend/src/main/resources/templates/auth/login.html
index 47bc63e..1eaa5f9 100644
--- a/backend/src/main/resources/templates/auth/login.html
+++ b/backend/src/main/resources/templates/auth/login.html
@@ -39,7 +39,9 @@
</div>
<div class="flex flex-wrap mb-2">
</div>
- <button type="submit" value="Log in" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Log In</button>
+ <button type="submit" value="Log in"
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Log In
+ </button>
</form>
</div>
diff --git a/backend/src/main/resources/templates/auth/register.html b/backend/src/main/resources/templates/auth/register.html
index dc57ca4..89153e2 100644
--- a/backend/src/main/resources/templates/auth/register.html
+++ b/backend/src/main/resources/templates/auth/register.html
@@ -21,7 +21,8 @@
name="username"
th:field="*{username}"
placeholder="Ted">
- <p th:if="${#fields.hasErrors('username')}" th:errors="*{username}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('username')}" th:errors="*{username}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
</div>
<div class="w-full md:w-1/2 px-3">
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2"
@@ -34,7 +35,8 @@
name="email"
th:field="*{email}"
placeholder="[email protected]">
- <p th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-red-500 text-xs italic">Please
+ fill out this field.</p>
</div>
</div>
<div class="flex flex-wrap -mx-3 mb-6">
@@ -49,12 +51,15 @@
name="password"
th:field="*{password}"
placeholder="Doe">
- <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}" class="text-red-500 text-xs italic">Please fill out this field.</p>
+ <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}" class="text-red-500 text-xs italic">
+ Please fill out this field.</p>
</div>
</div>
<div class="flex flex-wrap mb-2">
</div>
- <button th:href="@{/register}" type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Register</button>
+ <button th:href="@{/register}" type="submit"
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Register
+ </button>
</form>
</div>
diff --git a/backend/src/main/resources/templates/index.html b/backend/src/main/resources/templates/index.html
index 0c42c21..e3c4a8c 100644
--- a/backend/src/main/resources/templates/index.html
+++ b/backend/src/main/resources/templates/index.html
@@ -1,4 +1,3 @@
-
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
@@ -22,24 +21,33 @@
<a class="inline-block py-2 px-2 text-white no-underline hover:underline" href="post.html">POST</a>
</li>
<li class="mr-2">
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2" href="multimenu post.html">MULTIMENU POST</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2"
+ href="multimenu post.html">MULTIMENU POST</a>
</li>
<li class="mr-2">
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2" href="#">LINK</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2"
+ href="#">LINK</a>
</li>
<li class="mr-2">
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2" href="post_vue.html">POST_VUE</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-2"
+ href="post_vue.html">POST_VUE</a>
</li>
</ul>
</div>
<div class="flex w-1/2 justify-end content-center">
- <a class="inline-block text-gray-500 no-underline hover:text-white hover:text-underline text-center h-10 p-2 md:h-auto md:p-4 avatar" data-tippy-content="@twitter_handle" href="https://twitter.com/intent/tweet?url=#">
- <svg class="fill-current h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"></path></svg>
+ <a class="inline-block text-gray-500 no-underline hover:text-white hover:text-underline text-center h-10 p-2 md:h-auto md:p-4 avatar"
+ data-tippy-content="@twitter_handle" href="https://twitter.com/intent/tweet?url=#">
+ <svg class="fill-current h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"></path>
+ </svg>
</a>
- <a class="inline-block text-gray-500 no-underline hover:text-white hover:text-underline text-center h-10 p-2 md:h-auto md:p-4 avatar" data-tippy-content="#facebook_id" href="https://www.facebook.com/sharer/sharer.php?u=#">
- <svg class="fill-current h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"></path></svg>
+ <a class="inline-block text-gray-500 no-underline hover:text-white hover:text-underline text-center h-10 p-2 md:h-auto md:p-4 avatar"
+ data-tippy-content="#facebook_id" href="https://www.facebook.com/sharer/sharer.php?u=#">
+ <svg class="fill-current h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"></path>
+ </svg>
</a>
</div>
@@ -49,7 +57,8 @@
<div class="bg-gray-200 w-full text-xl md:text-2xl text-gray-800 leading-normal rounded-t">
<!--Lead Card-->
- <div class="flex h-full bg-contain rounded overflow-hidden shadow-lg" style="background-image: url('/abstract-polygonal-banner-background-vector.jpg');">
+ <div class="flex h-full bg-contain rounded overflow-hidden shadow-lg"
+ style="background-image: url('/abstract-polygonal-banner-background-vector.jpg');">
<a href="post.html" class="flex flex-wrap no-underline hover:no-underline">
<div class="w-full md:w-2/3 rounded-t">
</div>
@@ -57,9 +66,11 @@
<div class="w-full md:w-1/3 flex flex-col flex-grow flex-shrink">
<div class="flex-1 bg-white rounded-t rounded-b-none overflow-hidden shadow-lg">
<p class="w-full text-gray-600 text-xs md:text-sm pt-6 px-6">Spring Blog</p>
- <div class="w-full font-bold text-xl text-gray-900 px-6">👋 Welcome to my Java Spring Blog!</div>
+ <div class="w-full font-bold text-xl text-gray-900 px-6">👋 Welcome to my Java Spring Blog!
+ </div>
<p class="text-gray-800 font-serif text-base px-6 mb-5">
- This is a blog project I have created with the goal of learning and understand the ins and outs of the Java Spring framework.
+ This is a blog project I have created with the goal of learning and understand the ins
+ and outs of the Java Spring framework.
</p>
</div>
@@ -81,14 +92,19 @@
<div class="flex flex-wrap justify-between pt-12 -mx-6">
<div th:each="article :${articles}" class="w-full md:w-1/2 p-6 flex flex-col flex-grow flex-shrink">
<div class="flex-1 bg-white rounded-t rounded-b-none overflow-hidden shadow-lg">
- <a th:href="@{/articles/{articleId}(articleId=${article.id})}" class="flex flex-wrap no-underline hover:no-underline">
+ <a th:href="@{/articles/{articleId}(articleId=${article.id})}"
+ class="flex flex-wrap no-underline hover:no-underline">
<img th:src="${article.photoUrl}" class="h-full w-full rounded-t pb-6">
- <div th:text="${article.title}" class="w-full font-bold text-xl text-gray-900 px-6">Lorem ipsum dolor sit amet.</div>
+ <div th:text="${article.title}" class="w-full font-bold text-xl text-gray-900 px-6">Lorem
+ ipsum dolor sit amet.
+ </div>
<p class="text-gray-800 font-serif text-base px-6 mb-5"></p>
</a>
<div th:if="${user.id} == ${article.createdBy.id}"></div>
- <a th:href="@{/articles/edit/{articleId}(articleId=${article.id})}" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 ml-4 text-sm rounded">Edit</a>
- <a th:href="@{/articles/delete/{articleId}(articleId=${article.id})}" class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 ml-4 text-sm rounded">Delete</a>
+ <a th:href="@{/articles/edit/{articleId}(articleId=${article.id})}"
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 ml-4 text-sm rounded">Edit</a>
+ <a th:href="@{/articles/delete/{articleId}(articleId=${article.id})}"
+ class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 ml-4 text-sm rounded">Delete</a>
</div>
<div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6">
diff --git a/backend/src/main/resources/templates/layout.html b/backend/src/main/resources/templates/layout.html
index f3e0278..f2941f6 100644
--- a/backend/src/main/resources/templates/layout.html
+++ b/backend/src/main/resources/templates/layout.html
@@ -12,10 +12,12 @@
<meta name="author" content="name">
<meta name="description" content="description here">
<meta name="keywords" content="keywords,here">
- <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/tailwind.min.css"/> <!--Replace with your tailwind.css once created-->
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/tailwind.min.css"/>
+ <!--Replace with your tailwind.css once created-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet">
<style>:root{
-::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#efefef;border-radius:6px}::-webkit-scrollbar-thumb{background:#d5d5d5;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#c4c4c4}</style>
+::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#efefef;border-radius:6px}::-webkit-scrollbar-thumb{background:#d5d5d5;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#c4c4c4}
+ </style>
</head>
@@ -29,10 +31,12 @@
<nav class="bg-gray-900 p-4 mt-0 w-full">
<div class="container mx-auto flex items-center">
<div class="flex text-white font-extrabold">
- <a th:if="${(user == null || user.username == null)}" class="flex text-white text-base no-underline hover:text-white hover:no-underline" href="#">
+ <a th:if="${(user == null || user.username == null)}"
+ class="flex text-white text-base no-underline hover:text-white hover:no-underline" href="#">
☕<span class="hidden w-0 md:w-auto md:block pl-1">Spring!</span>
</a>
- <a th:if="${!(user == null || user.username == null)}" class="flex text-white text-base no-underline hover:text-white hover:no-underline" href="#">
+ <a th:if="${!(user == null || user.username == null)}"
+ class="flex text-white text-base no-underline hover:text-white hover:no-underline" href="#">
☕<span th:text="'Logged in as: ' + ${user.username}" class="hidden w-0 md:w-auto md:block pl-1"></span>
</a>
</div>
@@ -42,14 +46,20 @@
<a class="inline-block py-2 px-2 text-white no-underline" href="/">HOME</a>
</li>
<li class="mr-2">
- <a class="inline-block text-indigo-200 no-underline hover:text-gray-100 hover:text-underline py-2 px-2" href="/articles/new">NEW</a>
+ <a class="inline-block text-indigo-200 no-underline hover:text-gray-100 hover:text-underline py-2 px-2"
+ href="/articles/new">NEW</a>
</li>
<li class="mr-2">
- <a class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2" href="/register">REGISTER</a>
+ <a class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2"
+ href="/register">REGISTER</a>
</li>
<li class="mr-2">
- <a th:if="${(user == null || user.username == null)}" class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2" href="/userlogin">LOGIN</a>
- <a th:if="${!(user == null || user.username == null)}" class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2" href="/logout">LOGOUT</a>
+ <a th:if="${(user == null || user.username == null)}"
+ class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2"
+ href="/userlogin">LOGIN</a>
+ <a th:if="${!(user == null || user.username == null)}"
+ class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2"
+ href="/logout">LOGOUT</a>
</li>
</ul>
<form th:action="@{/articles/search}" class="w-full max-w-md">
@@ -78,22 +88,30 @@
</div>
<div class="flex w-1/2 justify-end content-center">
<p class="hidden sm:block mr-3 text-center h-14 p-4 text-xs"><span class="pr-2">Share this</span> 👉</p>
- <a class="inline-block text-white no-underline hover:text-white hover:text-underline text-center h-10 w-10 p-2 md:h-auto md:w-16 md:p-4" href="https://twitter.com/intent/tweet?url=#" style="background-color:#33b1ff;">
- <svg class="fill-current text-white h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"></path></svg>
+ <a class="inline-block text-white no-underline hover:text-white hover:text-underline text-center h-10 w-10 p-2 md:h-auto md:w-16 md:p-4"
+ href="https://twitter.com/intent/tweet?url=#" style="background-color:#33b1ff;">
+ <svg class="fill-current text-white h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"></path>
+ </svg>
</a>
- <a class="inline-block text-white no-underline hover:text-white hover:text-underline text-center h-10 w-10 p-2 md:h-auto md:w-16 md:p-4" href="https://www.facebook.com/sharer/sharer.php?u=#" style="background-color:#005e99">
- <svg class="fill-current text-white h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"></path></svg>
+ <a class="inline-block text-white no-underline hover:text-white hover:text-underline text-center h-10 w-10 p-2 md:h-auto md:w-16 md:p-4"
+ href="https://www.facebook.com/sharer/sharer.php?u=#" style="background-color:#005e99">
+ <svg class="fill-current text-white h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+ <path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"></path>
+ </svg>
</a>
</div>
</div>
</div>
<!--Progress bar-->
- <div id="progress" class="h-1 bg-white shadow" style="background:linear-gradient(to right, #4dc0b5 var(--scroll), transparent 0);"></div>
+ <div id="progress" class="h-1 bg-white shadow"
+ style="background:linear-gradient(to right, #4dc0b5 var(--scroll), transparent 0);"></div>
</div>
<!--Header-->
-<div class="w-full m-0 p-0 bg-cover bg-bottom" style="background-image:url('https://upload.wikimedia.org/wikipedia/commons/6/65/Toronto_Skyline_Summer_2020.jpg'); height: 60vh; max-height:460px;">
+<div class="w-full m-0 p-0 bg-cover bg-bottom"
+ style="background-image:url('https://upload.wikimedia.org/wikipedia/commons/6/65/Toronto_Skyline_Summer_2020.jpg'); height: 60vh; max-height:460px;">
<div class="container max-w-4xl bg-black bg-opacity-50 pb-16 rounded-b-xl mx-auto pt-16 md:pt-32 text-center break-normal">
<!--Title-->
<p class="text-white font-extrabold text-3xl md:text-5xl">
@@ -104,8 +122,7 @@
</div>
-
-<div layout:fragment="content" ></div>
+<div layout:fragment="content"></div>
<footer class="bg-gray-900">
<div class="container max-w-6xl mx-auto flex items-center px-2 py-8">
@@ -122,20 +139,22 @@
<a class="inline-block py-2 px-3 text-white no-underline" href="#"></a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#"></a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#"></a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#"></a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#"></a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#"></a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#"></a>
</li>
</ul>
</div>
</div>
-
</div>
</footer>
diff --git a/backend/src/main/resources/templates/post.html b/backend/src/main/resources/templates/post.html
index a775ff2..75d39cc 100644
--- a/backend/src/main/resources/templates/post.html
+++ b/backend/src/main/resources/templates/post.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html lang="en" xmlns:th="http://www.thymeleaf.org">
+<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -8,7 +8,8 @@
<meta name="author" content="name">
<meta name="description" content="description here">
<meta name="keywords" content="keywords,here">
- <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/tailwind.min.css"/> <!--Replace with your tailwind.css once created-->
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/tailwind.min.css"/>
+ <!--Replace with your tailwind.css once created-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="stylesheet">
<style>
.smooth {transition: box-shadow 0.3s ease-in-out;}
@@ -24,42 +25,74 @@
<!--Nav-->
-
<!--Title-->
<div class="text-center pt-16 md:pt-32">
- <p class="text-sm md:text-base text-green-500 font-bold">04 JULY 2023 <span class="text-gray-900">/</span> GETTING STARTED</p>
+ <p class="text-sm md:text-base text-green-500 font-bold">04 JULY 2023 <span class="text-gray-900">/</span> GETTING
+ STARTED</p>
<h1 class="font-bold break-normal text-3xl md:text-5xl">Welcome to Ghostwind CSS</h1>
</div>
<!--image-->
-<div class="container w-full max-w-6xl mx-auto bg-white bg-cover mt-8 rounded" style="background-image:url('https://source.unsplash.com/collection/1118905/'); height: 75vh;"></div>
+<div class="container w-full max-w-6xl mx-auto bg-white bg-cover mt-8 rounded"
+ style="background-image:url('https://source.unsplash.com/collection/1118905/'); height: 75vh;"></div>
<!--Container-->
<div class="container max-w-5xl mx-auto -mt-32">
<div class="mx-0 sm:mx-6">
- <div class="bg-white w-full p-8 md:p-24 text-xl md:text-2xl text-gray-800 leading-normal" style="font-family:Georgia,serif;">
+ <div class="bg-white w-full p-8 md:p-24 text-xl md:text-2xl text-gray-800 leading-normal"
+ style="font-family:Georgia,serif;">
<!--Post Content-->
<!--Lead Para-->
<p class="text-2xl md:text-3xl mb-5">
- 👋 Welcome fellow <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500" href="https://www.tailwindcss.com">Tailwind CSS</a> and <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500" href="https://www.ghost.org">Ghost</a> fan. This starter template is an attempt to replicate the default Ghost theme <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500" href="https://demo.ghost.io/welcome">"Casper"</a> using Tailwind CSS and vanilla Javascript.
+ 👋 Welcome fellow <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500"
+ href="https://www.tailwindcss.com">Tailwind CSS</a> and <a
+ class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500"
+ href="https://www.ghost.org">Ghost</a> fan. This starter template is an attempt to replicate the
+ default Ghost theme <a
+ class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500"
+ href="https://demo.ghost.io/welcome">"Casper"</a> using Tailwind CSS and vanilla Javascript.
</p>
- <p class="py-6">The basic blog page layout is available and all using the default Tailwind CSS classes (although there are a few hardcoded style tags). If you are going to use this in your project, you will want to convert the classes into components.</p>
+ <p class="py-6">The basic blog page layout is available and all using the default Tailwind CSS classes
+ (although there are a few hardcoded style tags). If you are going to use this in your project, you will
+ want to convert the classes into components.</p>
- <p class="py-6">Sed dignissim lectus ut tincidunt vulputate. Fusce tincidunt lacus purus, in mattis tortor sollicitudin pretium. Phasellus at diam posuere, scelerisque nisl sit amet, tincidunt urna. Cras nisi diam, pulvinar ut molestie eget, eleifend ac magna. Sed at lorem condimentum, dignissim lorem eu, blandit massa. Phasellus eleifend turpis vel erat bibendum scelerisque. Maecenas id risus dictum, rhoncus odio vitae, maximus purus. Etiam efficitur dolor in dolor molestie ornare. Aenean pulvinar diam nec neque tincidunt, vitae molestie quam fermentum. Donec ac pretium diam. Suspendisse sed odio risus. Nunc nec luctus nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis nec nulla eget sem dictum elementum.</p>
+ <p class="py-6">Sed dignissim lectus ut tincidunt vulputate. Fusce tincidunt lacus purus, in mattis tortor
+ sollicitudin pretium. Phasellus at diam posuere, scelerisque nisl sit amet, tincidunt urna. Cras nisi
+ diam, pulvinar ut molestie eget, eleifend ac magna. Sed at lorem condimentum, dignissim lorem eu,
+ blandit massa. Phasellus eleifend turpis vel erat bibendum scelerisque. Maecenas id risus dictum,
+ rhoncus odio vitae, maximus purus. Etiam efficitur dolor in dolor molestie ornare. Aenean pulvinar diam
+ nec neque tincidunt, vitae molestie quam fermentum. Donec ac pretium diam. Suspendisse sed odio risus.
+ Nunc nec luctus nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
+ himenaeos. Duis nec nulla eget sem dictum elementum.</p>
<ol>
- <li class="py-3">Maecenas accumsan lacus sit amet elementum porta. Aliquam eu libero lectus. Fusce vehicula dictum mi. In non dolor at sem ullamcorper venenatis ut sed dui. Ut ut est quam. Suspendisse quam quam, commodo sit amet placerat in, interdum a ipsum. Morbi sit amet tellus scelerisque tortor semper posuere.</li>
- <li class="py-3">Morbi varius posuere blandit. Praesent gravida bibendum neque eget commodo. Duis auctor ornare mauris, eu accumsan odio viverra in. Proin sagittis maximus pharetra. Nullam lorem mauris, faucibus ut odio tempus, ultrices aliquet ex. Nam id quam eget ipsum luctus hendrerit. Ut eros magna, eleifend ac ornare vulputate, pretium nec felis.</li>
- <li class="py-3">Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc vitae pretium elit. Cras leo mauris, tristique in risus ac, tristique rutrum velit. Mauris accumsan tempor felis vitae gravida. Cras egestas convallis malesuada. Etiam ac ante id tortor vulputate pretium. Maecenas vel sapien suscipit, elementum odio et, consequat tellus.</li>
+ <li class="py-3">Maecenas accumsan lacus sit amet elementum porta. Aliquam eu libero lectus. Fusce
+ vehicula dictum mi. In non dolor at sem ullamcorper venenatis ut sed dui. Ut ut est quam.
+ Suspendisse quam quam, commodo sit amet placerat in, interdum a ipsum. Morbi sit amet tellus
+ scelerisque tortor semper posuere.
+ </li>
+ <li class="py-3">Morbi varius posuere blandit. Praesent gravida bibendum neque eget commodo. Duis auctor
+ ornare mauris, eu accumsan odio viverra in. Proin sagittis maximus pharetra. Nullam lorem mauris,
+ faucibus ut odio tempus, ultrices aliquet ex. Nam id quam eget ipsum luctus hendrerit. Ut eros
+ magna, eleifend ac ornare vulputate, pretium nec felis.
+ </li>
+ <li class="py-3">Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+ Nunc vitae pretium elit. Cras leo mauris, tristique in risus ac, tristique rutrum velit. Mauris
+ accumsan tempor felis vitae gravida. Cras egestas convallis malesuada. Etiam ac ante id tortor
+ vulputate pretium. Maecenas vel sapien suscipit, elementum odio et, consequat tellus.
+ </li>
</ol>
- <blockquote class="border-l-4 border-green-500 italic my-8 pl-8 md:pl-12">Example of blockquote - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam at ipsum eu nunc commodo posuere et sit amet ligula.</blockquote>
+ <blockquote class="border-l-4 border-green-500 italic my-8 pl-8 md:pl-12">Example of blockquote - Lorem
+ ipsum dolor sit amet, consectetur adipiscing elit. Aliquam at ipsum eu nunc commodo posuere et sit amet
+ ligula.
+ </blockquote>
<p class="py-6">Example code block:</p>
<pre class="bg-gray-900 rounded text-white font-mono text-base p-4">
@@ -81,12 +114,17 @@
<!--Subscribe-->
<div class="container font-sans bg-green-100 rounded mt-8 p-4 md:p-24 text-center">
<h2 class="font-bold break-normal text-2xl md:text-4xl">Subscribe to Ghostwind CSS</h2>
- <h3 class="font-bold break-normal font-normal text-gray-600 text-base md:text-xl">Get the latest posts delivered right to your inbox</h3>
+ <h3 class="font-bold break-normal font-normal text-gray-600 text-base md:text-xl">Get the latest posts
+ delivered right to your inbox</h3>
<div class="w-full text-center pt-4">
<form action="#">
<div class="max-w-sm mx-auto p-1 pr-0 flex flex-wrap items-center">
- <input type="email" placeholder="[email protected]" class="flex-1 appearance-none rounded shadow p-3 text-gray-600 mr-2 focus:outline-none">
- <button type="submit" class="flex-1 mt-4 md:mt-0 block md:inline-block appearance-none bg-green-500 text-white text-base font-semibold tracking-wider uppercase py-4 rounded shadow hover:bg-green-400">Subscribe</button>
+ <input type="email" placeholder="[email protected]"
+ class="flex-1 appearance-none rounded shadow p-3 text-gray-600 mr-2 focus:outline-none">
+ <button type="submit"
+ class="flex-1 mt-4 md:mt-0 block md:inline-block appearance-none bg-green-500 text-white text-base font-semibold tracking-wider uppercase py-4 rounded shadow hover:bg-green-400">
+ Subscribe
+ </button>
</div>
</form>
</div>
@@ -99,7 +137,9 @@
<img class="w-10 h-10 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author">
<div class="flex-1">
<p class="text-base font-bold text-base md:text-xl leading-none">Ghostwind CSS</p>
- <p class="text-gray-600 text-xs md:text-base">Tailwind CSS version of Ghost's Casper theme by <a class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500" href="https://www.tailwindtoolbox.com">TailwindToolbox.com</a></p>
+ <p class="text-gray-600 text-xs md:text-base">Tailwind CSS version of Ghost's Casper theme by <a
+ class="text-gray-800 hover:text-green-500 no-underline border-b-2 border-green-500"
+ href="https://www.tailwindtoolbox.com">TailwindToolbox.com</a></p>
</div>
<div class="justify-end">
@@ -119,11 +159,13 @@
<svg class="progress-circle" width="100%" height="100%" viewBox="-1 -1 102 102">
<path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/>
</svg>
- <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+ <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24"
+ viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round"
+ stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <line x1="12" y1="5" x2="12" y2="19" />
- <line x1="18" y1="11" x2="12" y2="5" />
- <line x1="6" y1="11" x2="12" y2="5" />
+ <line x1="12" y1="5" x2="12" y2="19"/>
+ <line x1="18" y1="11" x2="12" y2="5"/>
+ <line x1="6" y1="11" x2="12" y2="5"/>
</svg>
</button>
@@ -134,16 +176,20 @@
<div class="w-full md:w-1/3 px-2 pb-12">
<div class="h-full bg-white rounded overflow-hidden shadow-md hover:shadow-lg relative smooth">
<a href="#" class="no-underline hover:no-underline">
- <img src="https://source.unsplash.com/_AjqGGafofE/400x200" class="h-48 w-full rounded-t shadow-lg">
+ <img src="https://source.unsplash.com/_AjqGGafofE/400x200"
+ class="h-48 w-full rounded-t shadow-lg">
<div class="p-6 h-auto md:h-48">
<p class="text-gray-600 text-xs md:text-sm">GETTING STARTED</p>
<div class="font-bold text-xl text-gray-900">Aperture Science</div>
<p class="text-gray-800 font-serif text-base mb-5">
- I’ll be honest, we’re throwing science at the wall here to see what sticks. No idea what it’ll do. Probably nothing. Best case scenario you might get some super powers. Worst case, some tumors, which we’ll cut out.
+ I’ll be honest, we’re throwing science at the wall here to see what sticks. No idea what
+ it’ll do. Probably nothing. Best case scenario you might get some super powers. Worst
+ case, some tumors, which we’ll cut out.
</p>
</div>
<div class="flex items-center justify-between inset-x-0 bottom-0 p-6">
- <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author">
+ <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300"
+ alt="Avatar of Author">
<p class="text-gray-600 text-xs md:text-sm">2 MIN READ</p>
</div>
</a>
@@ -161,7 +207,8 @@
</p>
</div>
<div class="flex items-center justify-between inset-x-0 bottom-0 p-6">
- <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author">
+ <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300"
+ alt="Avatar of Author">
<p class="text-gray-600 text-xs md:text-sm">4 MIN READ</p>
</div>
</a>
@@ -173,13 +220,17 @@
<img src="https://source.unsplash.com/DEa8_vxKlEo/400x200" class="h-48 w-full rounded-t shadow">
<div class="p-6 h-auto md:h-48">
<p class="text-gray-600 text-xs md:text-sm">FOREST</p>
- <div class="font-bold text-xl text-gray-900">What is life but a teardrop in the eye of infinity?</div>
+ <div class="font-bold text-xl text-gray-900">What is life but a teardrop in the eye of
+ infinity?
+ </div>
<p class="text-gray-800 font-serif text-base mb-5">
- Mollis pretium integer eros et dui orci, lectus nec elit sagittis neque. Dignissim ac nullam semper aliquet volutpat, ut scelerisque.
+ Mollis pretium integer eros et dui orci, lectus nec elit sagittis neque. Dignissim ac
+ nullam semper aliquet volutpat, ut scelerisque.
</p>
</div>
<div class="flex items-center justify-between inset-x-0 bottom-0 p-6">
- <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author">
+ <img class="w-8 h-8 rounded-full mr-4" src="http://i.pravatar.cc/300"
+ alt="Avatar of Author">
<p class="text-gray-600 text-xs md:text-sm">7 MIN READ</p>
</div>
</a>
@@ -206,20 +257,22 @@
<a class="inline-block py-2 px-3 text-white no-underline" href="index.html">HOME</a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#">link</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#">link</a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#">link</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#">link</a>
</li>
<li>
- <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3" href="#">link</a>
+ <a class="inline-block text-gray-600 no-underline hover:text-gray-200 hover:underline py-2 px-3"
+ href="#">link</a>
</li>
</ul>
</div>
</div>
-
</div>
</footer>