Webbserverprogrammering 1

Show sourcecode

The following files exists in this folder. Click to view.

webbutv3/word-app/public/

PageElement.js
practice.js
style.css

practice.js

256 lines ASCII Windows (CRLF)
// practice module
function Practice() {
  // api definition
  async function submitGuess(translationResults) {
    await fetch("api/submit-problem-result.php", {
      method: "POST",
      body: JSON.stringify({
        translations: translationResults,
      }),
    });
  }

  async function disableToggled(toDisable) {
    await fetch("api/disable-translation.php", {
      method: "POST",
      body: JSON.stringify({
        translations: toDisable,
      }),
    });
  }

  async function getProblem() {
    const res = await fetch("api/get-problem.php");
    const data = await res.json();
    return data;
  }

  // misc data
  function getTransaltions() {
    return page.pageElements
      .filter((x) => x.name === "translation")
      .map((pageElement) => ({
        id: pageElement.id,
        toggled: pageElement.element.hasAttribute("toggled"),
      }));
  }

  // page
  const page = new Page();

  // basic element getters

  const pageElements = (() => {
    return {
      get translationContainer() {
        return page.getPageElement({
          name: "translationContainer",
        });
      },
      get wordContainer() {
        return page.getPageElement({
          name: "wordContainer",
        });
      },
      get submitButton() {
        return page.getPageElement({
          name: "submitButton",
        });
      },
      get disableButton() {
        return page.getPageElement({
          name: "disableButton",
        });
      },
      get revealButton() {
        return page.getPageElement({
          name: "revealButton",
        });
      },
    };
  })();

  // basic flow functions

  function setTranslations(translations) {
    page.pageElements
      .filter((x) => x.name === "translation")
      .forEach((pageElement) => page.remove(pageElement));
    translations.forEach((translation) => {
      const button = new PageElement()
        .elementToggleButton(translation.translation)
        .setId(translation.id)
        .setName("translation");
      button.classList().add("text-selectable");
      page.addPageElement(button);
      pageElements.translationContainer.appendChild(button);
    });
  }

  function renderPracticeProblem(problem) {
    pageElements.wordContainer.element.innerText = problem.word.word;
    practice.setTranslations(problem.translations);
  }

  async function newPracticeProblem() {
    const problem = await practice.getProblem();
    renderPracticeProblem(problem);
  }

  function initialize({
    translationContainer,
    wordContainer,
    submitButton,
    revealButton,
    disableButton,
  }) {
    const onSubmit = async () => {
      pageElements.revealButton.hide();
      await practice.submitGuess(
        practice
          .getTransaltions()
          .map((x) => ({ success: x.toggled, id: x.id }))
      );
      pageElements.submitButton.hide();
      pageElements.translationContainer.hide();
      pageElements.disableButton.hide();
      await newPracticeProblem();
      pageElements.revealButton.show();
    };

    const onReveal = () => {
      pageElements.translationContainer.show();
      pageElements.submitButton.show();
      pageElements.disableButton.show();
    };

    const onDisable = () => {
      const toDisable = practice.getTransaltions().filter((t) => t.toggled);
      disableToggled(toDisable);
      toDisable.forEach((x) => page.remove(page.getPageElement({ id: x.id })));
    };

    page.addPageElement(translationContainer.setName("translationContainer"));
    page.addPageElement(wordContainer.setName("wordContainer"));
    page.addPageElement(
      submitButton.setName("submitButton").addEventListener("click", onSubmit)
    );
    page.addPageElement(
      revealButton.setName("revealButton").addEventListener("click", onReveal)
    );
    page.addPageElement(
      disableButton
        .setName("disableButton")
        .addEventListener("click", onDisable)
    );
  }

  return {
    submitGuess,
    getProblem,
    disableToggled,

    getTransaltions,
    setTranslations,

    initialize,
    newPracticeProblem,

    get page() {
      return page;
    },

    get currentWord() {
      return pageElements.wordContainer.element.innerText;
    },

    get currentTranslations() {
      return page.pageElements
        .filter((x) => x.name === "translation")
        .map((x) => x.element.innerText);
    },
  };
}

const practice = Practice();

function initialize() {
  const translationContainer = new PageElement()
    .getElementById("translations")
    .hide();
  const wordContainer = new PageElement().getElementById("word-container");
  const submitButton = new PageElement()
    .getElementById("submit-problem")
    .hide();
  const revealButton = new PageElement().getElementById("reveal-answers");
  const disableButton = new PageElement()
    .getElementById("disable-selected")
    .hide();

  practice.initialize({
    translationContainer,
    wordContainer,
    submitButton,
    revealButton,
    disableButton,
  });

  practice.newPracticeProblem();

  function generatePrompt(word, contexts, answers) {
    const prompt = `You should grade the following scentances where I was instructed to write diferent scentences using the word "${word}" in diferent contextexts of the word.

contexts and scentences:
${contexts
  .map((x, i) => `${i + 1}. Context: "${x}"\nAnswer: "${answers[i]}"`)
  .join("\n")}

Also, please comment on any odidies normal spanish speakers would notice or think about and dont be to picky about miss spellings`;
    return prompt;
  }

  const gptExamWindow = new PageElement()
    .getElementById("gpt-exam-window")
    .hide();

  const gptExamQuestionContainer = new PageElement().getElementById(
    "gpt-exam-questions"
  );
  const inputs = [];
  const gptExamCopy = new PageElement()
    .getElementById("gpt-exam-copy")
    .addEventListener("click", () => {
      const prompt = generatePrompt(
        practice.currentWord,
        practice.currentTranslations,
        inputs.map((x) => x.element.value)
      );
      navigator.clipboard.writeText(prompt);
    });
  const gptExamClose = new PageElement()
    .getElementById("gpt-exam-close")
    .addEventListener("click", () => {
      gptExamWindow.hide();
    });

  const openGptExam = new PageElement()
    .getElementById("gpt-exam-open")
    .addEventListener("click", () => {
      gptExamWindow.show();

      inputs.length = 0;
      gptExamQuestionContainer.replaceChildren([]);

      practice.currentTranslations.forEach((translation) => {
        const text = new PageElement().fromTag("p");
        text.element.innerText = translation;
        const input = new PageElement().fromTag("input");
        inputs.push(input);
        gptExamQuestionContainer.appendChild(text);
        gptExamQuestionContainer.appendChild(input);
      });
    });
}

initialize();