-
Notifications
You must be signed in to change notification settings - Fork 0
Exercise 8 #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Exercise 8 #10
Changes from all commits
0d85155
6be44cf
87ac7b9
7b91123
6f6a62f
7a3c300
fb2dc28
6e1420c
3239dea
3f9a2e5
f42aab3
e3d5dc7
047c3b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| .idea | ||
| node_modules | ||
| lib | ||
| .env | ||
| dev.env | ||
|
|
||
| dev.env | ||
| dev.env |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| TOKEN_SECRET=TEST123456 | ||
| NEO4J_URI=bolt://34.239.207.33:32848 | ||
| NEO4J_URI=bolt://100.26.212.97:32898 | ||
| NEO4J_USER=neo4j | ||
| NEO4J_PASSWORD=discriminations-beginners-tubes | ||
| NEO4J_PASSWORD=journals-knives-employee | ||
| NEO4J_DATABASE= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,3 +88,6 @@ sw.* | |
|
|
||
| # Vim swap files | ||
| *.swp | ||
|
|
||
| .nuxt-storybook | ||
| storybook-static | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,36 @@ | ||
| # no-nuxt-pls | ||
|
|
||
| ## Build Setup | ||
|
|
||
| ```bash | ||
| # install dependencies | ||
| $ npm install | ||
|
|
||
| # serve with hot reload at localhost:3000 | ||
| $ npm run dev | ||
| ## Installation | ||
| Run | ||
| ``` | ||
| npm install | ||
| ``` | ||
| to install all depedencies. But be warned it will install ~3200 packages | ||
| that are able to break you project without you beeing able to find the issues | ||
| easily. Your file manager will love it. | ||
|
|
||
| # build for production and launch server | ||
| $ npm run build | ||
| $ npm run start | ||
| ## Run Developer Mode | ||
| You can start a dev server with hot reload by running: | ||
| ``` | ||
| npm run dev | ||
| ``` | ||
|
|
||
| # generate static project | ||
| $ npm run generate | ||
| ## Build and Deploy | ||
| To build the project for deployment run: | ||
| ``` | ||
| npm run build | ||
| ``` | ||
| in your project directory. | ||
| If you have not generated the static project before run: | ||
| ``` | ||
| npm run generate | ||
| ``` | ||
| but be careful it takes 100 hours to generate for a simple hello world site. | ||
| That's called efficency and good design. | ||
| Finally you can start the project with: | ||
| ``` | ||
| npm run start | ||
| ``` | ||
|
|
||
| ## Details | ||
| For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,89 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| <template> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <form class="login-form" @submit.prevent="submitLogin"> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <fieldset> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <legend> | ||||||||||||||||||||||||||||||||||||||||||||||||
| Login | ||||||||||||||||||||||||||||||||||||||||||||||||
| </legend> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <label for="email">E-Mail:</label> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||||||||
| id="email" | ||||||||||||||||||||||||||||||||||||||||||||||||
| v-model="email" | ||||||||||||||||||||||||||||||||||||||||||||||||
| type="email" | ||||||||||||||||||||||||||||||||||||||||||||||||
| name="email" | ||||||||||||||||||||||||||||||||||||||||||||||||
| size="25" | ||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <label for="password">Password:</label> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||||||||||||||||||||||||||
| id="password" | ||||||||||||||||||||||||||||||||||||||||||||||||
| v-model="password" | ||||||||||||||||||||||||||||||||||||||||||||||||
| type="password" | ||||||||||||||||||||||||||||||||||||||||||||||||
| name="password" | ||||||||||||||||||||||||||||||||||||||||||||||||
| size="25" | ||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <div v-if="error" class="error"> | ||||||||||||||||||||||||||||||||||||||||||||||||
| {{ error.message }} | ||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| <button type="submit">Login</button> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </fieldset> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </template> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| <script> | ||||||||||||||||||||||||||||||||||||||||||||||||
| import gql from 'graphql-tag'; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { mapActions } from 'vuex'; | ||||||||||||||||||||||||||||||||||||||||||||||||
| const LOGIN_MUTATION = gql`mutation ($email: String!, $password: String!){ login(email: $email, password: $password) }`; | ||||||||||||||||||||||||||||||||||||||||||||||||
| export default { | ||||||||||||||||||||||||||||||||||||||||||||||||
| data() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||
| error: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| email: '', | ||||||||||||||||||||||||||||||||||||||||||||||||
| password: '', | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| methods: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...mapActions('auth', ['login']), | ||||||||||||||||||||||||||||||||||||||||||||||||
| async submitLogin() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { email, password } = this; | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { data } = await this.$apollo.mutate({mutation: LOGIN_MUTATION, variables: { email, password }}); | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (data.login) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| await this.$apolloHelpers.onLogin(data.login); | ||||||||||||||||||||||||||||||||||||||||||||||||
| await this.$router.push('/'); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||
| this.error = { message: 'Oops! Something went wrong.' }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||||||||||||||
| @Component | ||||||||||||||||||||||||||||||||||||||||||||||||
| export default class LoginForm extends Vue { | ||||||||||||||||||||||||||||||||||||||||||||||||
| @Prop() public token: string = this.$store.state.auth.token; | ||||||||||||||||||||||||||||||||||||||||||||||||
| public email: string = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||
| public password: string = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||
| @Action('auth') | ||||||||||||||||||||||||||||||||||||||||||||||||
| async submitLogin(): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { login } = await this.$a | ||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await this.$apollo.mutate({mutation: gql`mutation ($email: String!, $password: String!){ | ||||||||||||||||||||||||||||||||||||||||||||||||
| login(email: $email, password: $password) | ||||||||||||||||||||||||||||||||||||||||||||||||
| }`, variables: {email: this.email, password: this.password}}).then((data: any) => data.login as string); | ||||||||||||||||||||||||||||||||||||||||||||||||
| await this.$app.$apolloHelpers.onLogin(res); | ||||||||||||||||||||||||||||||||||||||||||||||||
| this.$store.commit('login', { email: this.email, password: this.password }); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; */ | ||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| <style scoped> | ||||||||||||||||||||||||||||||||||||||||||||||||
| </style> | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+67
to
+89
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
git? |
||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| <template> | ||
| <nav class="bg-gray-800"> | ||
| <div class="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8"> | ||
| <div class="relative flex items-center justify-between h-16"> | ||
| <div class="absolute inset-y-0 left-0 flex items-center sm:hidden"> | ||
| <button @click="burgerShow = !burgerShow" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" aria-expanded="false"> | ||
| <span class="sr-only">Open main menu</span> | ||
| <svg class="block h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> | ||
| </svg> | ||
| <svg class="hidden h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> | ||
| </svg> | ||
| </button> | ||
| </div> | ||
| <div class="absolute inset-y-auto right-0 hidden sm:block sm:ml-6"> | ||
| <template v-if="token"> | ||
| <button class="text-gray-300 bg-gray-600 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium" @click="logout">Logout</button> | ||
| </template> | ||
| <template v-else> | ||
| <span class="text-gray-300 p-3">You are not logged in.</span> | ||
| <button class="text-gray-300 bg-gray-600 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"><nuxt-link to="/Login">Login</nuxt-link></button> | ||
| </template> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <transition name="burger"> | ||
| <div v-show="burgerShow" class="visible md:hidden"> | ||
| <div class="px-2 pt-2 pb-3 space-y-1"> | ||
| <div v-if="token"> | ||
| <button class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium" @click="logout">Logout</button> | ||
| </div> | ||
| <div v-else> | ||
| <button class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"><nuxt-link to="/Login">Login</nuxt-link></button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </transition> | ||
| </nav> | ||
| </template> | ||
|
|
||
| <script> | ||
| export default { | ||
| data() { | ||
| return { | ||
| token: '', | ||
| burgerShow: false, | ||
| } | ||
| }, | ||
| mounted() { | ||
| this.setupMenu(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a better way to do this which also supports server-side-rendering. See step 5: https://github.com/Systems-Development-and-Frameworks/homework/tree/main/exercises/7#instructions Setting the token in |
||
| }, | ||
| methods: { | ||
| setupMenu(){ | ||
| this.token = this.$apolloHelpers.getToken(); | ||
| }, | ||
| logout() { | ||
| this.token = null; | ||
| this.$apolloHelpers.onLogout(); | ||
| window.location.reload(false); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to avoid
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I don't understand why you reload the page. The authentication state should be reactive and components should react to it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forcing a page reload contradicts the whole purpose of using a SPA. |
||
| }, | ||
| }, | ||
| }; | ||
| </script> | ||
|
|
||
| <style> | ||
| .burger-enter-active, .burger-leave-active { | ||
| transition: all 0.5s; | ||
| } | ||
| .burger-enter, .burger-leave-to { | ||
| opacity: 0; | ||
| } | ||
| </style> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,42 @@ | ||
| <template> | ||
| <div> | ||
| <h2>{{news.title}} ({{news.votes}})</h2> | ||
| <h2 class="text-xl text-center font-bold leading-7 text-gray-900 sm:text-2xl sm:truncate">{{news.title}} ({{news.votes}})</h2> | ||
| <br> | ||
| <button @click="updateNews(1)">Upvote</button> | ||
| <button @click="updateNews(-1)">Downvote</button> | ||
| <button @click="deleteNews">Remove</button> | ||
| <p> | ||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat pulvinar convallis. Vivamus iaculis, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you seem to be such a big fan of deeply nested npm dependencies: You know |
||
| odio ut ornare dignissim, dui nunc sollicitudin metus, quis pellentesque dui orci nec leo. Aliquam imperdiet | ||
| quam sit amet orci molestie convallis. Nullam odio ex, ornare vel efficitur laoreet, suscipit eu odio. Aliquam | ||
| ac nisi vitae leo fermentum mollis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur | ||
| ridiculus mus. Sed suscipit nulla nisl, vel dictum ex blandit nec. Nunc interdum nunc risus, ut molestie lacus | ||
| sollicitudin sit amet. Phasellus ut nibh tortor. | ||
| </p> | ||
| <br> | ||
| <button class="text-black bg-gray-200 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium" v-if="token" @click="updateNews(1)">Upvote</button> | ||
| <button class="text-black bg-gray-200 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium" v-if="token" @click="updateNews(-1)">Downvote</button> | ||
| <button class="text-black bg-gray-200 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium" v-if="authorId === news.author.id">Edit</button> | ||
| <button class="text-black bg-red-300 hover:bg-red-600 hover:text-white px-3 py-2 rounded-md text-sm font-medium" v-if="authorId === news.author.id" @click="deleteNews">Delete</button> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's where I get the following error: |
||
| </div> | ||
| </template> | ||
|
|
||
| <script lang="ts"> | ||
| <script> | ||
|
|
||
| export default { | ||
| props: { | ||
| news: Object, | ||
| token: String, | ||
| authorId: String, | ||
| }, | ||
|
|
||
| methods: { | ||
| updateNews(value) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have a bug here. Clicking downvote and upvote has the same effect. |
||
| this.$emit('update', this.news); | ||
| }, | ||
| deleteNews() { | ||
| this.$emit('remove', this.news); | ||
| } | ||
| } | ||
| } | ||
| /* | ||
| import { Vue, Component, Prop, Emit } from 'nuxt-property-decorator'; | ||
| import { Item } from '@/interface/item'; | ||
|
|
||
|
|
@@ -27,6 +55,7 @@ export default class NewsItem extends Vue { | |
| } | ||
|
|
||
| } | ||
| */ | ||
| </script> | ||
|
|
||
| <style scoped> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.