{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Demonstration of `MultiRoute`.
module Ema.Example.Ex05_MultiRoute where

import Ema
import Ema.Example.Common (tailwindLayout)
import Ema.Example.Ex00_Hello qualified as Ex00
import Ema.Example.Ex01_Basic qualified as Ex01
import Ema.Example.Ex02_Clock qualified as Ex02
import Ema.Example.Ex03_Store qualified as Ex03
import Ema.Route.Generic
import Ema.Route.Lib.Multi (MultiRoute)
import Generics.SOP (I (I), NP (Nil, (:*)))
import Text.Blaze.Html5 ((!))
import Text.Blaze.Html5 qualified as H
import Text.Blaze.Html5.Attributes qualified as A

type R =
  MultiRoute
    '[ TopRoute
     , FolderRoute "hello" Ex00.Route
     , FolderRoute "basic" Ex01.Route
     , FolderRoute "clock" Ex02.Route
     , FolderRoute "clockfast" Ex02.Route
     , FolderRoute "store" Ex03.Route
     ]

newtype TopRoute = TopRoute ()
  deriving newtype
    (Int -> TopRoute -> ShowS
[TopRoute] -> ShowS
TopRoute -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TopRoute] -> ShowS
$cshowList :: [TopRoute] -> ShowS
show :: TopRoute -> String
$cshow :: TopRoute -> String
showsPrec :: Int -> TopRoute -> ShowS
$cshowsPrec :: Int -> TopRoute -> ShowS
Show, TopRoute -> TopRoute -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TopRoute -> TopRoute -> Bool
$c/= :: TopRoute -> TopRoute -> Bool
== :: TopRoute -> TopRoute -> Bool
$c== :: TopRoute -> TopRoute -> Bool
Eq, Eq TopRoute
TopRoute -> TopRoute -> Bool
TopRoute -> TopRoute -> Ordering
TopRoute -> TopRoute -> TopRoute
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TopRoute -> TopRoute -> TopRoute
$cmin :: TopRoute -> TopRoute -> TopRoute
max :: TopRoute -> TopRoute -> TopRoute
$cmax :: TopRoute -> TopRoute -> TopRoute
>= :: TopRoute -> TopRoute -> Bool
$c>= :: TopRoute -> TopRoute -> Bool
> :: TopRoute -> TopRoute -> Bool
$c> :: TopRoute -> TopRoute -> Bool
<= :: TopRoute -> TopRoute -> Bool
$c<= :: TopRoute -> TopRoute -> Bool
< :: TopRoute -> TopRoute -> Bool
$c< :: TopRoute -> TopRoute -> Bool
compare :: TopRoute -> TopRoute -> Ordering
$ccompare :: TopRoute -> TopRoute -> Ordering
Ord, forall x. Rep TopRoute x -> TopRoute
forall x. TopRoute -> Rep TopRoute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
to :: forall x. Rep TopRoute x -> TopRoute
$cto :: forall x. Rep TopRoute x -> TopRoute
from :: forall x. TopRoute -> Rep TopRoute x
$cfrom :: forall x. TopRoute -> Rep TopRoute x
Generic, RouteModel TopRoute -> [TopRoute]
RouteModel TopRoute -> Prism_ String TopRoute
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel TopRoute -> [TopRoute]
$crouteUniverse :: RouteModel TopRoute -> [TopRoute]
routePrism :: RouteModel TopRoute -> Prism_ String TopRoute
$croutePrism :: RouteModel TopRoute -> Prism_ String TopRoute
IsRoute)

instance EmaSite TopRoute where
  siteInput :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action
-> SiteArg TopRoute -> m (Dynamic m (RouteModel TopRoute))
siteInput Some @Type Action
_ SiteArg TopRoute
_ = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
  siteOutput :: forall (m :: Type -> Type).
(MonadIO m, MonadLoggerIO m) =>
Prism' String TopRoute
-> RouteModel TopRoute -> TopRoute -> m (SiteOutput TopRoute)
siteOutput Prism' String TopRoute
_enc RouteModel TopRoute
_ TopRoute
_ =
    forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Format -> a -> Asset a
Ema.AssetGenerated Format
Ema.Html LByteString
renderIndex

main :: IO ()
main :: IO ()
main = do
  forall (f :: Type -> Type) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall r.
(Show r, Eq r, EmaStaticSite r) =>
SiteArg r -> IO [String]
Ema.runSite @R forall a b. (a -> b) -> a -> b
$ forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I Int
Ex02.delayNormal forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I Int
Ex02.delayFast forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall {k} (a :: k -> Type). NP @k a ('[] @k)
Nil

renderIndex :: LByteString
renderIndex :: LByteString
renderIndex =
  Html -> Html -> LByteString
tailwindLayout (Html -> Html
H.title Html
"Ex05_MultiRoute" forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> Html
H.base forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
A.href AttributeValue
"/") forall a b. (a -> b) -> a -> b
$
    Html -> Html
H.div forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
A.class_ AttributeValue
"container mx-auto text-center mt-8 p-2" forall a b. (a -> b) -> a -> b
$ do
      Html -> Html
H.p Html
"You can compose Ema sites. Here are three sites composed to produce one, using Ema.Route.Lib.Multi:"
      Html -> Html
H.ul forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
A.class_ AttributeValue
"flex flex-col justify-center .items-center mt-4 space-y-4" forall a b. (a -> b) -> a -> b
$ do
        -- NOTE: Since we don't have the MultiModel, we must hardcode the routes here.
        Html -> Html
H.li forall a b. (a -> b) -> a -> b
$ AttributeValue -> Html -> Html
routeElem AttributeValue
"hello" Html
"Ex00_Hello"
        Html -> Html
H.li forall a b. (a -> b) -> a -> b
$ AttributeValue -> Html -> Html
routeElem AttributeValue
"basic" Html
"Ex01_Basic"
        Html -> Html
H.li forall a b. (a -> b) -> a -> b
$ AttributeValue -> Html -> Html
routeElem AttributeValue
"clock" Html
"Ex02_Clock"
        Html -> Html
H.li forall a b. (a -> b) -> a -> b
$ AttributeValue -> Html -> Html
routeElem AttributeValue
"clockfast" Html
"Ex02_Clock (Fast)"
        Html -> Html
H.li forall a b. (a -> b) -> a -> b
$ AttributeValue -> Html -> Html
routeElem AttributeValue
"store" Html
"Ex03_Store"
  where
    routeElem :: AttributeValue -> Html -> Html
routeElem AttributeValue
r Html
w = do
      Html -> Html
H.a forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
A.class_ AttributeValue
"text-xl text-purple-500 hover:underline" forall h. Attributable h => h -> Attribute -> h
! AttributeValue -> Attribute
A.href AttributeValue
r forall a b. (a -> b) -> a -> b
$ Html
w