diff --git a/src/QuizEditor/Editor.elm b/src/QuizEditor/Editor.elm index 4d4718a2885332c6c8c941ad9e494c44de0b505a..43e2764ddbd5ac8551f9f6f87c9882cf27d5070c 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 146a20f96e9c3402eb9b3bce1fb321edfb99c406..57c740118e8219c7ba991d878f461a817954684f 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