+
+
+
+
+
+
diff --git a/generator/templateExampleApp/src/main.js b/generator/templateExampleApp/src/main.js
new file mode 100644
index 0000000..d75a149
--- /dev/null
+++ b/generator/templateExampleApp/src/main.js
@@ -0,0 +1,11 @@
+import Vue from 'vue'
+import App from './App.vue'
+import VueCompositionApi from '@vue/composition-api'
+
+Vue.use(VueCompositionApi);
+
+Vue.config.productionTip = false
+
+new Vue({
+ render: h => h(App),
+}).$mount('#app')
diff --git a/generator/templateExampleApp/src/views/PrivacyPolicy.purs b/generator/templateExampleApp/src/views/PrivacyPolicy.purs
deleted file mode 100644
index 00efb15..0000000
--- a/generator/templateExampleApp/src/views/PrivacyPolicy.purs
+++ /dev/null
@@ -1,24 +0,0 @@
-module PrivacyPolicy where
-
-import Prelude
-import Effect (Effect)
-import Effect.Unsafe (unsafePerformEffect)
-import Effect.Vue.Ref as Ref
-import Record.Extra as Record
-import Data.Array as Arr
-import Type.Row (RProxy(..))
-
-type Props = ( release :: Int )
-
--- this to lib
--- type RecordProps = Record.Record Props
-props = Record.keys (RProxy :: RProxy Props)
-
-privacyPolicy :: String -> String
-privacyPolicy policyRaw = policyRaw
-
-buildSetup :: forall a. String -> _ -> Effect a
-buildSetup policyRaw props = unsafePerformEffect do
- dialog <- Ref.new true
-
- Ref.vReturn { dialog, privacyPolicy: privacyPolicy policyRaw }
\ No newline at end of file
diff --git a/generator/templateExampleApp/src/views/PrivacyPolicy.vue b/generator/templateExampleApp/src/views/PrivacyPolicy.vue
deleted file mode 100644
index 1bac6fb..0000000
--- a/generator/templateExampleApp/src/views/PrivacyPolicy.vue
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- Privacy Policy r {{ release }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/generator/templateExampleApp/src/views/Todo.purs b/generator/templateExampleApp/src/views/Todo.purs
new file mode 100644
index 0000000..e95fac5
--- /dev/null
+++ b/generator/templateExampleApp/src/views/Todo.purs
@@ -0,0 +1,195 @@
+module Todo where
+
+import Prelude
+import Effect (Effect)
+import Effect.Unsafe (unsafePerformEffect)
+import Effect.Vue.Ref as Ref
+import Props (PropType(..), Props)
+import Data.Array (snoc, filter)
+import Data.Foldable (any, all)
+import Data.Maybe (Maybe(..), fromJust)
+import Partial.Unsafe (unsafePartial)
+import Web.HTML (window)
+import Web.HTML.Window (localStorage, location)
+import Web.HTML.Location (hash, setHash)
+import Web.Storage.Storage (getItem, setItem)
+import Simple.JSON as JSON
+import Data.Either (Either(..))
+import Data.String.Utils (startsWith)
+import Data.String.CodePoints (drop)
+import Effect.Console (log)
+
+props :: Props
+props = [String "prop_filter"]
+
+data TaskStatus = Active | Completed
+instance showTaskStatus :: Show TaskStatus where
+ show Active = "active"
+ show Completed = "completed"
+derive instance eqTaskStatus :: Eq TaskStatus
+
+type Filter = Maybe TaskStatus
+
+readFilter :: String -> Filter
+readFilter ts | ts == "active" = Just Active
+readFilter ts | ts == "completed" = Just Completed
+readFilter _ = Nothing
+
+type Task = { title :: String, status :: TaskStatus }
+type Tasks = Array Task
+
+type SerializableTask = { title :: String, status :: String }
+
+toSerializableTask :: Task -> SerializableTask
+toSerializableTask t = t { status = show t.status }
+
+fromSerializableTask :: SerializableTask -> Task
+fromSerializableTask t = t { status = unsafePartial $ fromJust $ readFilter t.status }
+
+-- Only add a task if it is not already on this list
+addTask :: Tasks-> Task -> Tasks
+addTask tasks { title: "", status: _ } = tasks
+addTask tasks task =
+ if any (\t -> t.title == task.title) tasks
+ then tasks
+ else snoc tasks task
+
+execAddTask :: Ref.Ref Tasks -> Ref.Ref String -> Effect Unit
+execAddTask tasks taskTitle = do
+ ts <- Ref.read tasks
+ title <- Ref.read taskTitle
+ let t = { title, status: Active }
+ let ts' = addTask ts t
+ Ref.write ts' tasks
+ updateTasksJs tasks
+
+updateTasksJs :: Ref.Ref Tasks -> Effect Unit
+updateTasksJs tasks = do
+ win <- window
+ store <- localStorage win
+ tasks' <- Ref.read tasks
+ setItem "todos-pure-vue" (JSON.writeJSON $ toSerializableTask <$> tasks') store
+
+restoreTasks :: Effect Tasks
+restoreTasks = do
+ win <- window
+ store <- localStorage win
+ i <- getItem "todos-pure-vue" store
+ case i of
+ Just items -> do
+ case JSON.readJSON items of
+ Right (st :: Array SerializableTask) -> pure $ fromSerializableTask <$> st
+ Left e -> do
+ log $ "error: " <> show e
+ pure []
+ Nothing -> pure []
+
+toggleAll :: Ref.Ref Tasks -> Effect Unit
+toggleAll tasks = do
+ tasks' <- Ref.read tasks
+ if allCompleted tasks'
+ then Ref.modify_ (setStatus Active) tasks
+ else Ref.modify_ (setStatus Completed) tasks
+ updateTasksJs tasks
+ where
+ setStatus :: TaskStatus -> Tasks -> Tasks
+ setStatus status tasks' = map (\t -> t { status = status }) tasks'
+
+ allCompleted :: Tasks -> Boolean
+ allCompleted tasks' = all (\task -> task.status == Completed) tasks'
+
+toggleTask :: Ref.Ref Tasks -> Task -> Effect Unit
+toggleTask tasks task = do
+ Ref.modify_ (\ts -> toggleTask' ts task) tasks
+ updateTasksJs tasks
+
+toggleTask' :: Tasks -> Task -> Tasks
+toggleTask' tasks' task = do
+ t <- tasks'
+ if t.title == task.title
+ then pure $ t { status = if t.status == Completed then Active else Completed }
+ else pure t
+
+removeTask :: Ref.Ref Tasks -> Task -> Effect Unit
+removeTask tasks task = Ref.modify_ (filter (\t -> t.title /= task.title)) tasks
+
+tasksToJs :: Tasks -> Array { title :: String, status :: String }
+tasksToJs tasks = map (\t -> t { status = show t.status }) tasks
+
+clearCompleted :: Ref.Ref Tasks -> Effect Unit
+clearCompleted tasks = do
+ Ref.modify_ clearCompleted' tasks
+ updateTasksJs tasks
+ where clearCompleted' :: Tasks -> Tasks
+ clearCompleted' tasks' = filter (\t -> t.status /= Completed) tasks'
+
+filterTasks :: Ref.Ref Tasks -> Ref.Ref Filter -> Effect (Array { title :: String, status :: String })
+filterTasks tasks taskFilter = do
+ t <- Ref.read tasks
+ f <- Ref.read taskFilter
+ pure $ tasksToJs $ filterTasks' t f
+
+filterTasksLeft :: Ref.Ref Tasks -> Effect (Array { title :: String, status :: String })
+filterTasksLeft tasks = do
+ t <- Ref.read tasks
+ pure $ tasksToJs $ filterTasks' t $ Just Active
+
+filterTasks' :: Tasks -> Filter -> Tasks
+filterTasks' tasks' Nothing = tasks'
+filterTasks' tasks' (Just taskFilter') = filter (\t -> t.status == taskFilter') tasks'
+
+setFilter :: Ref.Ref Filter -> Filter -> Effect Unit
+setFilter filter toFilter = do
+ win <- window
+ loc <- location win
+ setHash ("/" <> showFilter toFilter) loc
+ Ref.write toFilter filter
+ where showFilter :: Filter -> String
+ showFilter (Just Active) = "active"
+ showFilter (Just Completed) = "completed"
+ showFilter Nothing = ""
+
+initFilters :: Effect (Ref.Ref Filter)
+initFilters = do
+ win <- window
+ loc <- location win
+ hsh <- hash loc
+ let filter = if startsWith "#/" hsh
+ then readFilter $ drop 2 hsh
+ else Nothing
+ taskFilter :: Ref.Ref Filter <- Ref.new filter
+ pure taskFilter
+
+setup :: forall a. Props -> Effect a
+setup props = unsafePerformEffect do
+ taskTitle <- Ref.new ""
+
+ tasksRestored <- restoreTasks
+ tasks :: Ref.Ref Tasks <- Ref.new tasksRestored
+
+ taskFilter <- initFilters
+
+ filteredTasks <- Ref.computed $ filterTasks tasks taskFilter
+ tasksLeft <- Ref.computed $ filterTasksLeft tasks
+
+ Ref.vReturn { taskTitle
+ , addTask: execAddTask tasks taskTitle
+ , removeTask: removeTask tasks
+ , toggleTask: toggleTask tasks
+ , toggleAll: toggleAll tasks
+ , clearCompleted: clearCompleted tasks
+ , filter: taskFilter
+ , filteredTasks
+ , setFilter: setFilter taskFilter
+ , tasksLeft
+ , tasks
+ , filterIs: filterIs taskFilter
+ , fNothing: Nothing
+ , fActive: Just Active
+ , fCompleted: Just Completed
+ }
+ where
+ filterIs :: Ref.Ref Filter -> Filter -> Effect Boolean
+ filterIs fRef fa = do
+ fb <- Ref.read fRef
+ pure $ fa == fb
\ No newline at end of file
diff --git a/generator/templateExampleApp/src/views/Todo.vue b/generator/templateExampleApp/src/views/Todo.vue
new file mode 100644
index 0000000..451f71b
--- /dev/null
+++ b/generator/templateExampleApp/src/views/Todo.vue
@@ -0,0 +1,619 @@
+
+
+
+
+
todos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Props.purs b/src/Props.purs
index 43964c4..bd9ef32 100644
--- a/src/Props.purs
+++ b/src/Props.purs
@@ -9,13 +9,13 @@ data PropType = Int String
| Number String
-- | Object String
-toProp :: PropType -> String
-toProp (Int s) = s
-toProp (String s) = s
-toProp (Number s) = s
+instance showPropType :: Show PropType where
+ show (Int a) = show a
+ show (String a) = a
+ show (Number a) = show a
toProps :: Array PropType -> Array String
-toProps = map toProp
+toProps = map show
-- class Proppable a where