From 1f5ae8d8d1890e10bf9c942010b3d463eb6c1bac Mon Sep 17 00:00:00 2001
From: aqquq <jannik.wurche@student.uni-halle.de>
Date: Sun, 7 Jul 2024 13:03:16 +0200
Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9C=20format=20error=20output?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/QuizEditor/Editor.elm | 82 +++++++++++++++++++++++----------------
 src/editor.html           | 60 +++++++++++++++++++---------
 2 files changed, 91 insertions(+), 51 deletions(-)

diff --git a/src/QuizEditor/Editor.elm b/src/QuizEditor/Editor.elm
index 4d4718a..43e2764 100644
--- a/src/QuizEditor/Editor.elm
+++ b/src/QuizEditor/Editor.elm
@@ -1,23 +1,23 @@
-module QuizEditor.Editor exposing (main)
+port module QuizEditor.Editor exposing (main)
 
 import Browser
-import Html exposing (Html, div, text)
-import Json.Decode as Decode exposing (Decoder, field)
+import Html exposing (Html, div, text, button, p, br)
+import Html.Events exposing (onClick)
+import Json.Decode as Decode
+import Json.Encode as Encode
+import Types exposing (PartialQuiz)
+import Utils.Api exposing (partialQuizDecoder)
 
 
-type alias ExampleType =
-    { str : String
-    , int : Int
-    }
+port resetInput : () -> Cmd msg
 
+type alias Model =
+    { result : Result Decode.Error PartialQuiz }
 
-exampleTypeDecoder : Decoder ExampleType
-exampleTypeDecoder =
-    Decode.map2 ExampleType
-        ( field "str" Decode.string )
-        ( field "int" Decode.int )
-
+type Msg
+    = ResetInput
 
+main : Program Decode.Value Model Msg
 main =
     Browser.element
         { init = \flags -> init flags
@@ -26,27 +26,20 @@ main =
         , view = view
         }
 
-
-type alias Model =
-    { result : Result Decode.Error ExampleType }
-
-
 init : Decode.Value -> ( Model, Cmd Msg )
 init flags =
     let
         result =
-            Decode.decodeValue exampleTypeDecoder flags
+            Decode.decodeValue partialQuizDecoder flags
     in
     ( Model result, Cmd.none )
 
 
-type Msg
-    = NoOp
-
-
 update : Msg -> Model -> ( Model, Cmd Msg )
 update msg model =
-    ( model, Cmd.none )
+    case msg of
+        ResetInput ->
+            ( model, resetInput () )
 
 
 view : Model -> Html Msg
@@ -55,13 +48,36 @@ view model =
         [ viewResult model.result ]
 
 
-viewResult : Result Decode.Error ExampleType -> Html Msg
+viewResult : Result Decode.Error PartialQuiz -> Html Msg
 viewResult result =
-    case result of
-        Ok example ->
-            div []
-                [ text ("Valid JSON! str: " ++ example.str ++ ", int: " ++ String.fromInt example.int) ]
-
-        Err error ->
-            div []
-                [ text ("Invalid JSON: " ++ Decode.errorToString error) ]
+    let
+        resulttext = case result of
+            Ok _ ->
+                p [] [ text "Valid JSON" ]
+
+            Err error ->
+                div []
+                    [ p [] [ text (formatDecodeError error) ] 
+                    , br [] []
+                    , p [] [ text "complete Error message:" ]
+                    , p [] [ text (Decode.errorToString error) ]
+                    ]
+    in
+    div []
+        [ resulttext
+        , button [ onClick (ResetInput )] [ text "reset" ]]
+    
+formatDecodeError : Decode.Error -> String
+formatDecodeError error =
+    case error of
+        Decode.Field field subError ->
+            "Field error at \"" ++ field ++ "\": " ++ formatDecodeError subError
+
+        Decode.Index index subError ->
+            "Index error at [" ++ String.fromInt index ++ "]: " ++ formatDecodeError subError
+
+        Decode.OneOf errors ->
+            "One of the following errors occurred:\n" ++ String.join "\n" (List.map formatDecodeError errors)
+
+        Decode.Failure msg json ->
+            "Failure: " ++ msg ++ "\n" ++ "JSON: " ++ Encode.encode 2 json
diff --git a/src/editor.html b/src/editor.html
index 146a20f..57c7401 100644
--- a/src/editor.html
+++ b/src/editor.html
@@ -5,27 +5,51 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Elm JSON Type Check</title>
     <link rel="stylesheet" href="style.css">
-    <script defer>
-        document.getElementById('fileInput').addEventListener('change', function(event) {
-            const file = event.target.files[0];
-            if (file) {
-                const reader = new FileReader();
-                reader.onload = function(e) {
-                    const jsonString = e.target.result;
-                    const json = JSON.parse(jsonString);
-                    const app = Elm.Editor.init({
-                        node: document.getElementById('elm-container'),
-                        flags: json
-                    });
-                };
-                reader.readAsText(file);
-            }
-        });        
-    </script>
 </head>
 <body>
-    <input type="file" id="fileInput" />
+    <input type="file" id="jsonFileInput" accept=".json"/>
+    <button id="checkBtn">Check JSON</button>
     <div id="elm-container"></div>
     <script src="editor.js"></script>
+    <script>
+        const checkBtn = document.getElementById('checkBtn')
+
+        // Function to read JSON file
+        function readJsonFile(file) {
+            return new Promise((resolve, reject) => {
+                const reader = new FileReader();
+                reader.onload = event => resolve(JSON.parse(event.target.result));
+                reader.onerror = error => reject(error);
+                reader.readAsText(file);
+            });
+        }
+
+        // Add event listener to button
+        checkBtn.addEventListener('click', async () => {
+            const fileInput = document.getElementById('jsonFileInput');
+
+            if (fileInput.files.length === 0) {
+                alert("Please select a JSON file first");
+                return;
+            }
+
+            const file = fileInput.files[0];
+            try {
+                const jsonData = await readJsonFile(file);
+                checkBtn.remove();
+
+                const app = Elm.QuizEditor.Editor.init({
+                    node: document.getElementById('elm-container'),
+                    flags: jsonData
+                });
+
+                app.ports.resetInput.subscribe(() => {
+                    location.reload()
+                });
+            } catch (error) {
+                console.error("Error reading or storing JSON file: ", error);
+            }
+        });
+    </script>
 </body>
 </html>
\ No newline at end of file
-- 
GitLab