diff options
| author | realtradam <[email protected]> | 2024-07-14 23:43:35 -0400 |
|---|---|---|
| committer | realtradam <[email protected]> | 2024-07-14 23:43:35 -0400 |
| commit | 0081ab9926c486beb3033791e9e8f946b3c8b48a (patch) | |
| tree | ddd52a3454d630b43946a3271c5fac2880d1f722 /src/main | |
| parent | 16aea3767fc42f4baa30f7fc466e7a8851b0ecbb (diff) | |
| download | spring-blog-0081ab9926c486beb3033791e9e8f946b3c8b48a.tar.gz spring-blog-0081ab9926c486beb3033791e9e8f946b3c8b48a.zip | |
add auth for editing and deleting posts
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/java/com/blog/web/controllers/ArticleController.java | 39 | ||||
| -rw-r--r-- | src/main/java/com/blog/web/mappers/ArticleMapper.java | 31 | ||||
| -rw-r--r-- | src/main/java/com/blog/web/security/SecurityConfig.java | 6 | ||||
| -rw-r--r-- | src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java | 30 | ||||
| -rw-r--r-- | src/main/resources/static/abstract-polygonal-banner-background-vector.jpg | bin | 0 -> 1841814 bytes | |||
| -rw-r--r-- | src/main/resources/templates/auth/login.html | 4 | ||||
| -rw-r--r-- | src/main/resources/templates/index.html | 110 | ||||
| -rw-r--r-- | src/main/resources/templates/layout.html | 30 |
8 files changed, 101 insertions, 149 deletions
diff --git a/src/main/java/com/blog/web/controllers/ArticleController.java b/src/main/java/com/blog/web/controllers/ArticleController.java index 9af5b92..d1bfcce 100644 --- a/src/main/java/com/blog/web/controllers/ArticleController.java +++ b/src/main/java/com/blog/web/controllers/ArticleController.java @@ -12,7 +12,6 @@ import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import java.time.LocalDateTime; import java.util.List; @Controller @@ -27,13 +26,8 @@ public class ArticleController { @GetMapping("/articles") public String listArticles(Model model) { - UserEntity user = new UserEntity(); List<ArticleDto> articles = articleService.findAllArticles(); - String username = SecurityUtil.getSessionUser(); - if(username != null) { - user = userService.findByUsername(username); - model.addAttribute("user", user); - } + UserEntity user = getLoggedInUser(); model.addAttribute("user", user); model.addAttribute("articles", articles); return "index"; @@ -43,11 +37,15 @@ public class ArticleController { public String showArticle(@PathVariable("articleId") long articleId, Model model) { ArticleDto articleDto = articleService.findArticleById(articleId); model.addAttribute("article", articleDto); + UserEntity user = getLoggedInUser(); + model.addAttribute("user", user); return "articles/show"; } @GetMapping("/articles/new") public String createArticleForm(Model model) { + UserEntity user = getLoggedInUser(); + model.addAttribute("user", user); Article article = new Article(); model.addAttribute("article", article); return "articles/new"; @@ -65,14 +63,30 @@ public class ArticleController { return "redirect:/articles"; } + private UserEntity getLoggedInUser() { + UserEntity user = new UserEntity(); + String username = SecurityUtil.getSessionUser(); + if(username != null) { + user = userService.findByUsername(username); + } + return user; + } + @GetMapping("/articles/delete/{articleId}") public String deleteArticle(@PathVariable("articleId") Long articleId) { - articleService.delete(articleId); + UserEntity user = getLoggedInUser(); + ArticleDto article = articleService.findArticleById(articleId); + UserEntity owner = article.getCreatedBy(); + if(owner.getId() == user.getId()) { + articleService.delete(articleId); + } return "redirect:/articles"; } @GetMapping("/articles/edit/{articleId}") public String editArticleForm(@PathVariable("articleId") long articleId, Model model) { + UserEntity user = getLoggedInUser(); + model.addAttribute("user", user); ArticleDto articleDto = articleService.findArticleById(articleId); model.addAttribute("article", articleDto); return "articles/edit"; @@ -92,11 +106,20 @@ public class ArticleController { @GetMapping("/articles/search") public String searchArticle(@RequestParam(value = "search") String search, Model model) { + UserEntity user = getLoggedInUser(); + model.addAttribute("user", user); List<ArticleDto> articles = articleService.searchArticles(search); model.addAttribute("articles", articles); return "index"; } + @GetMapping("/userlogin") + public String login(Model model) { + UserEntity user = getLoggedInUser(); + model.addAttribute("user", user); + return "auth/login"; + } + @GetMapping("/") public String getArticles() { return "redirect:/articles"; diff --git a/src/main/java/com/blog/web/mappers/ArticleMapper.java b/src/main/java/com/blog/web/mappers/ArticleMapper.java new file mode 100644 index 0000000..a3642da --- /dev/null +++ b/src/main/java/com/blog/web/mappers/ArticleMapper.java @@ -0,0 +1,31 @@ +package com.blog.web.mappers; + +import com.blog.web.dto.ArticleDto; +import com.blog.web.models.Article; + +public class ArticleMapper { + public static Article mapToArticle(ArticleDto articleDto) { + Article article = Article.builder() + .id(articleDto.getId()) + .title(articleDto.getTitle()) + .photoUrl(articleDto.getPhotoUrl()) + .content(articleDto.getContent()) + .createdBy(articleDto.getCreatedBy()) + .createdOn(articleDto.getCreatedOn()) + .updatedOn(articleDto.getUpdatedOn()) + .build(); + return article; + } + + public static ArticleDto mapToArticleDto(Article article) { + return ArticleDto.builder() + .id(article.getId()) + .title(article.getTitle()) + .photoUrl(article.getPhotoUrl()) + .content(article.getContent()) + .createdBy(article.getCreatedBy()) + .createdOn(article.getCreatedOn()) + .updatedOn(article.getUpdatedOn()) + .build(); + } +} diff --git a/src/main/java/com/blog/web/security/SecurityConfig.java b/src/main/java/com/blog/web/security/SecurityConfig.java index 49b3402..6b85bb3 100644 --- a/src/main/java/com/blog/web/security/SecurityConfig.java +++ b/src/main/java/com/blog/web/security/SecurityConfig.java @@ -36,12 +36,12 @@ public class SecurityConfig { .permitAll() ) .formLogin(form -> form - .loginPage("/login") + .loginPage("/userlogin") .usernameParameter("username") .passwordParameter("password") .defaultSuccessUrl("/articles") - .loginProcessingUrl("/login") - .failureUrl("/login?error=true") + .loginProcessingUrl("/userlogin") + .failureUrl("/userlogin?error=true") .permitAll() ).logout( logout -> logout diff --git a/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java b/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java index 6fdbe3f..1ddd6f0 100644 --- a/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java +++ b/src/main/java/com/blog/web/services/impl/ArticleServiceImpl.java @@ -12,6 +12,9 @@ import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; +import static com.blog.web.mappers.ArticleMapper.mapToArticle; +import static com.blog.web.mappers.ArticleMapper.mapToArticleDto; + @Service public class ArticleServiceImpl implements ArticleService { public ArticleServiceImpl(com.blog.web.repository.ArticleRepository articleRepository, com.blog.web.repository.UserRepository userRepository) { @@ -25,7 +28,7 @@ public class ArticleServiceImpl implements ArticleService { @Override public List<ArticleDto> findAllArticles() { List<Article> articles = articleRepository.findAll(); - return articles.stream().map(this::mapToArticleDto).collect(Collectors.toList()); + return articles.stream().map((article) -> mapToArticleDto(article)).collect(Collectors.toList()); } @Override @@ -62,29 +65,4 @@ public class ArticleServiceImpl implements ArticleService { List<Article> articles = articleRepository.searchArticles(search); return articles.stream().map(article -> mapToArticleDto(article)).collect(Collectors.toList()); } - - private Article mapToArticle(ArticleDto articleDto) { - Article article = Article.builder() - .id(articleDto.getId()) - .title(articleDto.getTitle()) - .photoUrl(articleDto.getPhotoUrl()) - .content(articleDto.getContent()) - .createdBy(articleDto.getCreatedBy()) - .createdOn(articleDto.getCreatedOn()) - .updatedOn(articleDto.getUpdatedOn()) - .build(); - return article; - } - - private ArticleDto mapToArticleDto(Article article) { - return ArticleDto.builder() - .id(article.getId()) - .title(article.getTitle()) - .photoUrl(article.getPhotoUrl()) - .content(article.getContent()) - .createdBy(article.getCreatedBy()) - .createdOn(article.getCreatedOn()) - .updatedOn(article.getUpdatedOn()) - .build(); - } } diff --git a/src/main/resources/static/abstract-polygonal-banner-background-vector.jpg b/src/main/resources/static/abstract-polygonal-banner-background-vector.jpg Binary files differnew file mode 100644 index 0000000..1c6746e --- /dev/null +++ b/src/main/resources/static/abstract-polygonal-banner-background-vector.jpg diff --git a/src/main/resources/templates/auth/login.html b/src/main/resources/templates/auth/login.html index aee1594..47bc63e 100644 --- a/src/main/resources/templates/auth/login.html +++ b/src/main/resources/templates/auth/login.html @@ -9,8 +9,8 @@ <div th:if="${param.error}" class="text-xl p-4 bg-black text-red-500">Invalid Username/Password</div> <div th:if="${param.logout}" class="text-xl p-4 bg-black text-red-500">You have been logged out</div> -<div class="flex justify-center bg-white p-12"> - <form th:action="@{/login}" method="post" class="w-full max-w-lg"> +<div class="flex h-full justify-center bg-white p-12"> + <form th:action="@{/userlogin}" 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" diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 1a71459..0c42c21 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -49,25 +49,23 @@ <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-white rounded overflow-hidden shadow-lg"> + <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"> - <img src="https://source.unsplash.com/collection/494263/800x600" class="h-full w-full shadow"> </div> <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">GETTING STARTED</p> - <div class="w-full font-bold text-xl text-gray-900 px-6">👋 Welcome fellow Tailwind CSS and Ghost fan</div> + <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> <p class="text-gray-800 font-serif text-base px-6 mb-5"> - This starter template is an attempt to replicate the default Ghost theme "Casper" using Tailwind CSS and vanilla Javascript. + 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> <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> + <p class="text-gray-600 text-xs md:text-sm"></p> </div> </div> </div> @@ -81,28 +79,6 @@ <!--Posts Container--> <div class="flex flex-wrap justify-between pt-12 -mx-6"> - - <!--1/3 col --> - <div class="w-full md:w-1/3 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 href="#" class="flex flex-wrap no-underline hover:no-underline"> - <img src="https://source.unsplash.com/collection/225/800x600" class="h-64 w-full rounded-t pb-6"> - <p class="w-full text-gray-600 text-xs md:text-sm px-6">GETTING STARTED</p> - <div 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"> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam at ipsum eu nunc commodo posuere et sit amet ligula. - </p> - </a> - </div> - <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> - <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> - </div> - </div> - </div> - - <!--1/2 col --> <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"> @@ -110,81 +86,17 @@ <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}"> - <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> - <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> - <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> - </div> - </div> - </div> + <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> - <!--1/2 col --> - <div class="w-full md:w-1/2 p-6 flex flex-col flex-grow flex-shrink"> - <div class="flex-1 flex-row bg-white rounded-t rounded-b-none overflow-hidden shadow-lg"> - <a href="#" class="flex flex-wrap no-underline hover:no-underline"> - <img src="https://source.unsplash.com/collection/764827/800x600" class="h-full w-full rounded-t pb-6"> - <p class="w-full text-gray-600 text-xs md:text-sm px-6">GETTING STARTED</p> - <div 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"> - Lorem ipsum eu nunc commodo posuere et sit amet ligula. - </p> - </a> </div> <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> + <p class="text-gray-600 text-xs md:text-sm"></p> </div> </div> </div> - - - - <!--2/3 col --> - <div class="w-full md:w-2/3 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 href="#" class="flex flex-wrap no-underline hover:no-underline"> - <img src="https://source.unsplash.com/collection/325867/800x600" class="h-full w-full rounded-t pb-6"> - <p class="w-full text-gray-600 text-xs md:text-sm px-6">GETTING STARTED</p> - <div 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"> - Lorem ipsum eu nunc commodo posuere et sit amet ligula. - </p> - </a> - </div> - <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> - <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> - </div> - </div> - </div> - - <!--1/3 col --> - <div class="w-full md:w-1/3 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 href="#" class="flex flex-wrap no-underline hover:no-underline"> - <img src="https://source.unsplash.com/collection/1118905/800x600" class="h-full w-full rounded-t pb-6"> - <p class="w-full text-gray-600 text-xs md:text-sm px-6">GETTING STARTED</p> - <div 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"> - Lorem ipsum eu nunc commodo posuere et sit amet ligula. - </p> - </a> - </div> - <div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow-lg p-6"> - <div class="flex items-center justify-between"> - <img class="w-8 h-8 rounded-full mr-4 avatar" data-tippy-content="Author Name" src="http://i.pravatar.cc/300" alt="Avatar of Author"> - <p class="text-gray-600 text-xs md:text-sm">1 MIN READ</p> - </div> - </div> - </div> - </div> <!--/ Post Content--> @@ -192,6 +104,7 @@ <!--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> @@ -204,10 +117,12 @@ </form> </div> </div> + --> <!-- /Subscribe--> <!--Author--> + <!-- <div class="flex w-full items-center font-sans p-8 md:p-24"> <img class="w-10 h-10 rounded-full mr-4" src="http://i.pravatar.cc/300" alt="Avatar of Author"> <div class="flex-1"> @@ -218,6 +133,7 @@ <a href="post.html" class="bg-transparent border border-gray-500 hover:border-green-500 text-xs text-gray-500 hover:text-green-500 font-bold py-2 px-4 rounded-full">Read More</a> </div> </div> + --> <!--/Author--> </div> diff --git a/src/main/resources/templates/layout.html b/src/main/resources/templates/layout.html index a5bdb2c..f3e0278 100644 --- a/src/main/resources/templates/layout.html +++ b/src/main/resources/templates/layout.html @@ -24,13 +24,16 @@ <head> <meta charset="UTF-8"> </head> -<body class="bg-gray-200 font-sans leading-normal tracking-normal"> +<body class="bg-gray-200 min-h-screen font-sans leading-normal tracking-normal"> <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 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">Ghostwind CSS</span> + <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="#"> + ☕<span th:text="'Logged in as: ' + ${user.username}" class="hidden w-0 md:w-auto md:block pl-1"></span> </a> </div> <div class="flex pl-4 text-sm place-content-between w-full"> @@ -45,7 +48,8 @@ <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 class="inline-block text-indigo-200 no-underline hover:text-indigo-100 hover:text-underline py-2 px-2" href="/login">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="/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"> @@ -68,7 +72,7 @@ <div class="bg-white"> <div class="flex flex-wrap items-center content-center"> <div class="flex w-1/2 justify-start text-white font-extrabold"> - <a class="flex text-gray-900 no-underline hover:text-gray-900 hover:no-underline pl-2" href="#"> + <a class="flex text-gray-100 no-underline hover:text-gray-900 hover:no-underline pl-2" href="#"> 👻 <span class="hidden w-0 md:w-auto md:block pl-1">Ghostwind CSS</span> </a> </div> @@ -90,12 +94,12 @@ <!--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="container max-w-4xl mx-auto pt-16 md:pt-32 text-center break-normal"> + <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"> - 👻 Ghostwind CSS + ☕ Spring! </p> - <p class="text-xl md:text-2xl text-gray-500">Welcome to my Blog</p> + <p class="text-xl md:text-2xl text-gray-200">Welcome to my Blog</p> </div> </div> @@ -109,22 +113,22 @@ <div class="w-full mx-auto flex flex-wrap items-center"> <div class="flex w-full md:w-1/2 justify-center md:justify-start text-white font-extrabold"> <a class="text-gray-900 no-underline hover:text-gray-900 hover:no-underline" href="#"> - 👻 <span class="text-base text-gray-200">Ghostwind CSS</span> + <span class="text-base text-gray-200"></span> </a> </div> <div class="flex w-full pt-2 content-center justify-between md:w-1/2 md:justify-end"> <ul class="list-reset flex justify-center flex-1 md:flex-none items-center"> <li> - <a class="inline-block py-2 px-3 text-white no-underline" href="#">Active</a> + <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="#">link</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="#">link</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="#">link</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> |
