# Updating the UI

At this point, we have a functioning blockchain. Now, we can add a UI to upload file hashes from our browser.

First, start by navigating to localhost:8080, which hosts our vue applicaton.

# Creating a new Component

In order to make it easier for users to upload a hash to the blockchain, we will create a new component that lets someone drag and drop a file into the UI. The component will calculate the file hash, and the user will have the option to upload this proof as a claim.

We can create a new folder and file called vue/src/components/DropZone.vue with following content:

# vue/src/components/DropZone.vue

Copy <template> <div></div> </template> <style></style>

Import and add our new component DragZone into our vue/src/views/Index.vue file within <script></script> tags:

Copy import DropZone from "@/components/DropZone"; export default { components: { ...sp, DropZone }, };

# Index.vue

Copy <template> <div> <div class="sp-container"> <sp-sign-in /> <sp-bank-balances /> <sp-token-send /> <drop-zone /> <!-- this line is used by starport scaffolding # 4 --> <sp-type-form type="claim" :fields="['proof']" /> </div> </div> </template> <script> import * as sp from "@tendermint/vue"; import DropZone from "@/components/DropZone"; export default { components: { ...sp, DropZone }, }; </script>

Now, we should see our UI update whenever we add something to our component.

# Component layout

Next, let's add some elements to create the layout for our component.

We will be reusing a few components from the @tendermint/vue component library, as well as creating our own drop zone.

# vue/src/components/DropZone.vue

Copy <template> <div> <sp-h3>Calculate Proof</sp-h3> <div id="drop-zone" @drop.prevent="hash" @dragover.prevent> {{ hashed || placeholderText }} </div> <sp-button @click="submit" :loading="flight" :disabled="hashed == '' || flight" >Submit Proof as a new Claim</sp-button > </div> </template> <style scoped> #drop-zone { font-family: "Inter", "Helvetica", sans-serif; height: 20rem; line-height: 20rem; font-size: 1.25rem; background-color: rgb(247, 247, 247); text-align: center; margin-bottom: 2rem; border-radius: 0.5rem; } </style>

Back to vue/src/views/Index.vue, add the following JavaScript code right after previous section added in <script></script> tags:

Copy import { SpH3, SpButton } from "@tendermint/vue"; export default { components: { SpH3, SpButton, }, data() { return { placeholderText: "Drag and drop a file here", hashed: "", flight: false, }; }, methods: { hash(e) {}, async submit() {}, } }

# Implementing our hash functionality

As mentioned earlier, we want to be able to upload a file to the browser, calculate its hash, and submitting our hash to the blockchain.

First, we will add the js-sha256 package. Let's install it via npm, and make sure we're in the vue/ directory when we run the following command.

Copy npm install --save js-sha256

Once installed, we can add the import and hash(e){} functionality for creating the hash:

Copy import { sha256 } from "js-sha256"; ... methods: { hash(e) { const files = e.dataTransfer.items; if (!files.length) return; // Read the file and hash it const reader = new FileReader(); reader.onload = (ev) => { this.hashed = sha256(ev.target.result); }; reader.readAsArrayBuffer(files[0].getAsFile()); },

And now we can add our submit(){} function, which will dispatch actions to the cosmos store for submitting and fetching things from our blockchain.

Copy async submit() { // Submit this.flight = true; await this.$store.dispatch("cosmos/entitySubmit", { type: "claim", body: { proof: this.hashed, }, }); await this.$store.dispatch("cosmos/entityFetch", { type: "claim", }); // Clear fields this.flight = false; this.hashed = ""; },

Voilà! We can now log in using the mnemonic provided when running the starport serve command, and start uploading proof of files as claims to the blockchain!

Congratulations, your app is complete!