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 # compile and watch for dev
elm-serve: elm-serve:
npx elm-land serve npx elm-land server
# build css and watch # build css and watch
css-serve: css-serve:
+1 -1
View File
@@ -13,6 +13,7 @@
"elm/html": "1.0.0", "elm/html": "1.0.0",
"elm/http": "2.0.0", "elm/http": "2.0.0",
"elm/json": "1.1.3", "elm/json": "1.1.3",
"elm/parser": "1.1.0",
"elm/svg": "1.0.1", "elm/svg": "1.0.1",
"elm/time": "1.0.0", "elm/time": "1.0.0",
"elm/url": "1.0.0" "elm/url": "1.0.0"
@@ -20,7 +21,6 @@
"indirect": { "indirect": {
"elm/bytes": "1.0.8", "elm/bytes": "1.0.8",
"elm/file": "1.0.5", "elm/file": "1.0.5",
"elm/parser": "1.1.0",
"elm/regex": "1.0.0", "elm/regex": "1.0.0",
"elm/virtual-dom": "1.0.3" "elm/virtual-dom": "1.0.3"
} }
+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 Effect exposing (Effect)
import Html exposing (Html) import Html exposing (Html)
import Html.Attributes exposing (class, href, src) import Html.Attributes exposing (class, href, src, target)
import Http import Http
import Json.Decode as Json import Json.Decode as Json
import Page exposing (Page) import Page exposing (Page)
@@ -102,14 +102,16 @@ view model =
case bloglist of case bloglist of
first :: rest -> first :: rest ->
Html.div [ class "max-w-6xl p-6 mx-auto space-y-6 sm:space-y-12 mb-16" ] 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.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.img [ class "object-cover w-full h-64 rounded sm:h-96 lg:col-span-7", src first.image ] [] [ 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.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.a [ href <| "/posts/" ++ first.category ++ "/" ++ first.slug ]
[ Html.text first.title ] [ Html.h3 [ class "text-2xl font-semibold sm:text-4xl group-hover:underline group-focus:underline" ]
, Html.span [ class "text-gray-400" ] [ Html.text first.date ] [ Html.text first.title ]
, Html.p [] [ Html.text <| String.left 200 first.description ] , Html.span [ class "text-gray-400" ] [ Html.text first.date ]
, UU.categoryNtags first.category [] , 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 , 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 : JsonMeta -> Html msg
card blog = 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.div [ 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.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.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.a [ href <| "/posts/" ++ blog.category ++ "/" ++ blog.slug ]
, Html.span [ class " text-gray-400" ] [ Html.text blog.date ] [ Html.h3 [ class "text-2xl font-semibold group-hover:underline group-focus:underline" ] [ Html.text blog.title ]
, Html.p [] [ Html.text <| String.left 200 blog.description ] , Html.span [ class " text-gray-400" ] [ Html.text <| UU.getFormattedDate blog.date ]
, UU.categoryNtags blog.category [] , 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" { title = "Blog by Avinal"
, body = , body =
[ Html.section [ class "text-gray-100" ] [ 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.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 [ Html.ul
[ class "flex flex-wrap items-center mt-3 text-xl text-neutral-500 sm:mt-0" ] [ 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 Effect exposing (Effect)
import Html exposing (Html) import Html exposing (Html)
@@ -17,7 +17,7 @@ import View exposing (View)
import Yaml.Decode as Yaml 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 shared route =
Page.new Page.new
{ init = init route { 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 () = init route () =
let let
requestUrl = requestUrl =
UU.contentUrl UU.contentUrl
{ category = route.params.first_ { category = route.params.category
, post = , post = route.params.post
Maybe.withDefault "" <| List.head route.params.rest_
} }
cmd : Cmd Msg 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 Int
nameMatrix = nameMatrix =
Array.fromList Array.fromList
+51 -3
View File
@@ -1,21 +1,69 @@
module Utils.Utils exposing (..) module Utils.Utils exposing (..)
import Array exposing (Array)
import Html exposing (Html) import Html exposing (Html)
import Html.Attributes exposing (class) import Html.Attributes exposing (class, href, target)
import Http exposing (Error(..)) import Http exposing (Error(..))
import Parser exposing (..)
import Utils.Constants 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 : String -> List String -> Html msg
categoryNtags category tags = categoryNtags category tags =
Html.span [ class "flex flex-wrap py-6 space-x-2 border-t border-dashed border-teal-500" ] 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 [ Html.text category
] ]
:: List.map :: List.map
(\tag -> (\tag ->
Html.i [ class "px-3 py-1 m-1 rounded-sm hover:underline bg-cyan-500 text-gray-900" ] 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 tags
+2 -2
View File
@@ -35,7 +35,7 @@ toBrowserDocument :
} }
-> Browser.Document msg -> Browser.Document msg
toBrowserDocument { view } = toBrowserDocument { view } =
{ title = view.title { title = view.title ++ " | Avinal's personal website"
, body = , body =
[ Html.main_ [ class "container mx-auto bg-neutral-800" ] [ Html.main_ [ class "container mx-auto bg-neutral-800" ]
view.body view.body
@@ -57,7 +57,7 @@ authenticated pages.
-} -}
none : View msg none : View msg
none = none =
{ title = "Be My SpaceTime" { title = "Avinal | Personal Website"
, body = [] , body = []
} }