1
0
mirror of https://github.com/avinal/avinal.github.io.git synced 2026-07-03 23:30:09 +05:30

add category and minor improvements

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
2023-01-27 21:07:57 +05:30
parent c483f30cea
commit c8b58f6080
10 changed files with 356 additions and 29 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ build:
# compile and watch for dev
elm-serve:
npx elm-land serve
npx elm-land server
# build css and watch
css-serve:
+2 -2
View File
@@ -13,6 +13,7 @@
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/parser": "1.1.0",
"elm/svg": "1.0.1",
"elm/time": "1.0.0",
"elm/url": "1.0.0"
@@ -20,7 +21,6 @@
"indirect": {
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/parser": "1.1.0",
"elm/regex": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
@@ -29,4 +29,4 @@
"direct": {},
"indirect": {}
}
}
}
+9
View File
@@ -0,0 +1,9 @@
module Pages.Pages.AboutMe exposing (page)
import Html exposing (Html)
import View exposing (View)
page : View msg
page =
View.fromString "Pages.Pages.AboutMe"
+68
View File
@@ -0,0 +1,68 @@
module Pages.Pages.Projects exposing (Model, Msg, page)
import Effect exposing (Effect)
import Route exposing (Route)
import Html
import Page exposing (Page)
import Shared
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
, Effect.none
)
-- UPDATE
type Msg
= ExampleMsgReplaceMe
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
ExampleMsgReplaceMe ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
View.fromString "Pages.Pages.Projects"
+20 -15
View File
@@ -2,7 +2,7 @@ module Pages.Posts exposing (Model, Msg, page)
import Effect exposing (Effect)
import Html exposing (Html)
import Html.Attributes exposing (class, href, src)
import Html.Attributes exposing (class, href, src, target)
import Http
import Json.Decode as Json
import Page exposing (Page)
@@ -102,14 +102,16 @@ view model =
case bloglist of
first :: rest ->
Html.div [ class "max-w-6xl p-6 mx-auto space-y-6 sm:space-y-12 mb-16" ]
[ Html.a [ class "block max-w-sm gap-3 mx-auto sm:max-w-full group hover:no-underline focus:no-underline lg:grid lg:grid-cols-12 bg-neutral-900", href ("/posts/" ++ first.category ++ "/" ++ first.slug) ]
[ Html.img [ class "object-cover w-full h-64 rounded sm:h-96 lg:col-span-7", src first.image ] []
[ Html.div [ class "block max-w-sm gap-3 mx-auto sm:max-w-full group hover:no-underline focus:no-underline lg:grid lg:grid-cols-12 bg-neutral-900" ]
[ Html.a [ class "lg:col-span-7", href <| "/posts/" ++ first.category ++ "/" ++ first.slug ] [ Html.img [ class "object-cover w-full h-64 rounded sm:h-96 lg:col-span-7", src first.image ] [] ]
, Html.div [ class "p-6 space-y-2 lg:col-span-5" ]
[ Html.h3 [ class "text-2xl font-semibold sm:text-4xl group-hover:underline group-focus:underline" ]
[ Html.text first.title ]
, Html.span [ class "text-gray-400" ] [ Html.text first.date ]
, Html.p [] [ Html.text <| String.left 200 first.description ]
, UU.categoryNtags first.category []
[ Html.a [ href <| "/posts/" ++ first.category ++ "/" ++ first.slug ]
[ Html.h3 [ class "text-2xl font-semibold sm:text-4xl group-hover:underline group-focus:underline" ]
[ Html.text first.title ]
, Html.span [ class "text-gray-400" ] [ Html.text first.date ]
, Html.p [] [ Html.text <| String.left 200 first.description ]
]
, Html.a [ href <| "/posts/" ++ first.category, target "_blank" ] [ UU.categoryNtags first.category [] ]
]
]
, Html.div [ class "grid justify-center grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3" ] <| List.map card rest
@@ -120,13 +122,15 @@ view model =
card : JsonMeta -> Html msg
card blog =
Html.a [ class "max-w-sm mx-auto group hover:no-underline focus:no-underline bg-neutral-900", href ("/posts/" ++ blog.category ++ "/" ++ blog.slug) ]
[ Html.img [ class "object-cover w-full h-44 rounded", src blog.image ] []
Html.div [ class "max-w-sm mx-auto group hover:no-underline focus:no-underline bg-neutral-900", href ("/posts/" ++ blog.category ++ "/" ++ blog.slug) ]
[ Html.a [ href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ] [ Html.img [ class "object-cover w-full h-44 rounded", src blog.image ] [] ]
, Html.div [ class "p-6 space-y-2" ]
[ Html.h3 [ class "text-2xl font-semibold group-hover:underline group-focus:underline" ] [ Html.text blog.title ]
, Html.span [ class " text-gray-400" ] [ Html.text blog.date ]
, Html.p [] [ Html.text <| String.left 200 blog.description ]
, UU.categoryNtags blog.category []
[ Html.a [ href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ]
[ Html.h3 [ class "text-2xl font-semibold group-hover:underline group-focus:underline" ] [ Html.text blog.title ]
, Html.span [ class " text-gray-400" ] [ Html.text <| UU.getFormattedDate blog.date ]
, Html.p [] [ Html.text <| String.left 200 blog.description ]
]
, Html.a [ href <| "/posts/" ++ blog.category, target "_blank" ] [ UU.categoryNtags blog.category [] ]
]
]
@@ -145,7 +149,8 @@ view model =
{ title = "Blog by Avinal"
, body =
[ Html.section [ class "text-gray-100" ]
[ maincard blogList
[ Html.h1 [ class "text-5xl font-bold mb-6 mt-12 text-center text-white" ] [ Html.text <| "Welcome to my blog" ]
, maincard blogList
, Html.div [ class "fixed bottom-0 left-0 bg-neutral-900 z-20 p-4 w-full md:flex md:items-center md:justify-between md:p-4" ]
[ Html.ul
[ class "flex flex-wrap items-center mt-3 text-xl text-neutral-500 sm:mt-0" ]
+180
View File
@@ -0,0 +1,180 @@
module Pages.Posts.Category_ exposing (Model, Msg, page)
import Effect exposing (Effect)
import Html exposing (Html)
import Html.Attributes exposing (class, href, src)
import Http
import Json.Decode as Json
import Page exposing (Page)
import Route exposing (Route)
import Shared
import Utils.Constants exposing (..)
import Utils.Utils as UU
import View exposing (View)
page : Shared.Model -> Route { category : String } -> Page Model Msg
page shared route =
Page.new
{ init = init route
, update = update
, subscriptions = subscriptions
, view = view
}
-- INIT
type alias JsonMeta =
{ title : String
, date : String
, description : String
, category : String
, slug : String
, image : String
}
type alias Model =
{ error : Maybe String
, blogList : Maybe (List JsonMeta)
, category : String
}
init : Route { category : String } -> () -> ( Model, Effect Msg )
init route () =
let
cmd : Cmd Msg
cmd =
Http.get
{ url = "/content/posts/posts.json"
, expect = Http.expectJson BloglistReceived (Json.list jsonMetaDecoder)
}
in
( { error = Nothing
, blogList = Nothing
, category = route.params.category
}
, Effect.sendCmd cmd
)
-- UPDATE
type Msg
= BloglistReceived (Result Http.Error (List JsonMeta))
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
BloglistReceived (Ok data) ->
( { model | blogList = Just data }
, Effect.none
)
BloglistReceived (Err err) ->
( { model | error = Just (UU.errorToString err) }, Effect.none )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> View Msg
view model =
let
card : JsonMeta -> Html msg
card blog =
Html.a [ class "flex flex-wrap mb-6 ", href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ]
[ Html.div [ class "grow-0 shrink-0 basis-auto w-full md:w-3/12 md:mb-0 ml-auto" ]
[ Html.div [ class "overflow-hidden relative bg-no-repeat bg-cover ripple" ]
[ Html.img [ src blog.image, class "w-full h-44 object-cover rounded" ] []
]
]
, Html.div [ class "grow-0 shrink-0 basis-auto w-full md:w-9/12 xl:w-7/12 p-3 md:mb-0 mr-auto bg-neutral-900" ]
[ Html.h5 [ class "text-2xl font-bold mb-2" ] [ Html.text blog.title ]
, Html.span [ class "text-gray-400 text-sm" ] [ Html.text blog.date ]
, Html.p [ class "text-gray-500 mt-4 text-md" ] [ Html.text <| String.left 200 blog.description ]
]
]
footerLinkToLeft : Link -> Html msg
footerLinkToLeft link =
Html.li []
[ Html.a
[ href link.url
, class "mr-4 md:mr-6 underline decoration-cyan-500 hover:decoration-pink-500"
]
[ Html.text link.text ]
]
in
case model.blogList of
Just blogList ->
let
filteredList =
filterBlogListByCategory blogList model.category
in
case filteredList of
[] ->
{ title = "No posts in this category"
, body = []
}
clist ->
{ title = "Posts in " ++ model.category ++ " category"
, body =
[ Html.div []
[ Html.section [ class "mb-32 text-gray-200 text-center md:text-left" ] <|
Html.h1 [ class "text-5xl font-bold mb-12 mt-12 text-center text-white" ] [ Html.text "Posts in ", Html.i [ class "text-pink-600" ] [ Html.text model.category ], Html.text " category" ]
:: List.map card clist
, Html.div [ class "fixed bottom-0 left-0 bg-neutral-900 z-20 p-4 w-full md:flex md:items-center md:justify-between md:p-4" ]
[ Html.ul
[ class "flex flex-wrap items-center mt-3 text-xl text-neutral-500 sm:mt-0" ]
(List.map footerLinkToLeft <|
{ text = "Home", url = "/" }
:: Utils.Constants.footerLinks
)
]
]
]
}
Nothing ->
{ title = "There is no such category"
, body = []
}
-- UTILS
jsonMetaDecoder : Json.Decoder JsonMeta
jsonMetaDecoder =
Json.map6 JsonMeta
(Json.field "title" Json.string)
(Json.field "date" Json.string)
(Json.field "description" Json.string)
(Json.field "category" Json.string)
(Json.field "slug" Json.string)
(Json.field "image" Json.string)
filterBlogListByCategory : List JsonMeta -> String -> List JsonMeta
filterBlogListByCategory blogList category =
List.filter (\meta -> meta.category == category) blogList
@@ -1,4 +1,4 @@
module Pages.Posts.ALL_ exposing (Model, Msg, page)
module Pages.Posts.Category_.Post_ exposing (Model, Msg, page)
import Effect exposing (Effect)
import Html exposing (Html)
@@ -17,7 +17,7 @@ import View exposing (View)
import Yaml.Decode as Yaml
page : Shared.Model -> Route { first_ : String, rest_ : List String } -> Page Model Msg
page : Shared.Model -> Route { category : String, post : String } -> Page Model Msg
page shared route =
Page.new
{ init = init route
@@ -59,14 +59,13 @@ type alias Blog =
}
init : Route { first_ : String, rest_ : List String } -> () -> ( Model, Effect Msg )
init : Route { category : String, post : String } -> () -> ( Model, Effect Msg )
init route () =
let
requestUrl =
UU.contentUrl
{ category = route.params.first_
, post =
Maybe.withDefault "" <| List.head route.params.rest_
{ category = route.params.category
, post = route.params.post
}
cmd : Cmd Msg
+18
View File
@@ -34,6 +34,24 @@ iconLinks =
]
months : Array String
months =
Array.fromList
[ "January"
, "February"
, "March"
, "April"
, "May"
, "June"
, "July"
, "August"
, "September"
, "October"
, "November"
, "December"
]
nameMatrix : Array Int
nameMatrix =
Array.fromList
+51 -3
View File
@@ -1,21 +1,69 @@
module Utils.Utils exposing (..)
import Array exposing (Array)
import Html exposing (Html)
import Html.Attributes exposing (class)
import Html.Attributes exposing (class, href, target)
import Http exposing (Error(..))
import Parser exposing (..)
import Utils.Constants exposing (..)
type alias Date =
{ day : Int
, month : Int
, year : Int
}
day : Parser Int
day =
succeed identity
|= int
month : Parser Int
month =
succeed identity
|= int
year : Parser Int
year =
succeed identity
|= int
getFormattedDate : String -> String
getFormattedDate dateString =
case Parser.run dateParser dateString of
Ok date ->
(Maybe.withDefault "Month" <| Array.get (date.month - 1) months) ++ " " ++ String.fromInt date.day ++ ", " ++ String.fromInt date.year
Err err ->
"Invalid date!!"
dateParser : Parser Date
dateParser =
succeed Date
|= day
|. symbol "-"
|= month
|. symbol "-"
|= year
categoryNtags : String -> List String -> Html msg
categoryNtags category tags =
Html.span [ class "flex flex-wrap py-6 space-x-2 border-t border-dashed border-teal-500" ]
(Html.b [ class "px-3 py-1 m-1 rounded-sm hover:underline bg-pink-400 text-gray-900" ]
(Html.a [ class "px-3 py-1 m-1 rounded-sm hover:underline bg-pink-400 text-gray-900 font-bold", href <| "/posts/" ++ category, target "_blank" ]
[ Html.text category
]
:: List.map
(\tag ->
Html.i [ class "px-3 py-1 m-1 rounded-sm hover:underline bg-cyan-500 text-gray-900" ]
[ Html.text tag
[ Html.text <| "#" ++ tag
]
)
tags
+2 -2
View File
@@ -35,7 +35,7 @@ toBrowserDocument :
}
-> Browser.Document msg
toBrowserDocument { view } =
{ title = view.title
{ title = view.title ++ " | Avinal's personal website"
, body =
[ Html.main_ [ class "container mx-auto bg-neutral-800" ]
view.body
@@ -57,7 +57,7 @@ authenticated pages.
-}
none : View msg
none =
{ title = "Be My SpaceTime"
{ title = "Avinal | Personal Website"
, body = []
}