Skip to content

Instantly share code, notes, and snippets.

@mboynes
Created March 29, 2020 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mboynes/62ceea37159867ef00f8bb65ab2343f6 to your computer and use it in GitHub Desktop.
Save mboynes/62ceea37159867ef00f8bb65ab2343f6 to your computer and use it in GitHub Desktop.
diff --git a/resources/js/app.js b/resources/js/app.js
index 01b8468..8c93dcc 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -7,6 +7,10 @@
require('./bootstrap');
window.Vue = require('vue');
+window.Vue.prototype.authorize = function(handler) {
+ const { user } = window.App;
+ return !! user ? handler(user) : false;
+};
window.events = new Vue();
@@ -26,7 +30,8 @@ window.flash = function(message) {
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('flash', require('./components/Flash.vue').default);
-Vue.component('reply', require('./components/Reply.vue').default);
+
+Vue.component('thread-view', require('./pages/Thread.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
diff --git a/resources/js/components/Replies.vue b/resources/js/components/Replies.vue
new file mode 100644
index 0000000..95a2cc4
--- /dev/null
+++ b/resources/js/components/Replies.vue
@@ -0,0 +1,33 @@
+<template>
+ <div>
+ <div v-for="(reply, index) in items">
+ <reply :data="reply" @deleted="remove(index)"></reply>
+ </div>
+ </div>
+</template>
+
+<script>
+ import Reply from "./Reply";
+
+ export default {
+ props: ['data'],
+
+ components: {
+ Reply,
+ },
+
+ data() {
+ return {
+ items: this.data,
+ };
+ },
+
+ methods: {
+ remove(index) {
+ this.items.splice(index, 1);
+ this.$emit('removed');
+ flash('Reply was deleted.');
+ },
+ },
+ }
+</script>
diff --git a/resources/js/components/Reply.vue b/resources/js/components/Reply.vue
index a9bafcc..13adcea 100644
--- a/resources/js/components/Reply.vue
+++ b/resources/js/components/Reply.vue
@@ -1,21 +1,61 @@
+<template>
+ <div :id="`reply-${id}`" class="card mb-3">
+ <div class="card-header level">
+ <h5 class="flex">
+ <a :href="`/profiles/${data.owner.name}`" v-text="data.owner.name"></a> said
+ {{ data.created_at }}...
+ </h5>
+
+ <div v-if="signedIn">
+ <favorite :reply="data"></favorite>
+ </div>
+ </div>
+ <div class="card-body">
+ <div v-if="editing" v-cloak>
+ <div class="form-group">
+ <textarea v-model="body" class="form-control" rows="5"></textarea>
+ </div>
+ <button class="btn btn-sm btn-primary" @click="update">Update</button>
+ <button class="btn btn-sm btn-link" @click="editing = false">Cancel</button>
+ </div>
+ <div v-else v-text="body"></div>
+ </div>
+
+ <div class="card-footer level" v-if="canUpdate">
+ <button class="btn btn-sm btn-outline-info mr-2" @click="editing = true">Edit</button>
+ <button class="btn btn-outline-danger btn-sm" @click="destroy">Delete Reply</button>
+ </div>
+ </div>
+</template>
<script>
import Favorite from './Favorite';
export default {
- props: ['attributes'],
+ props: ['data'],
data() {
return {
editing: false,
- body: this.attributes.body,
+ id: this.data.id,
+ body: this.data.body,
};
},
components: { Favorite },
+ computed: {
+ signedIn() {
+ return window.App.signedIn;
+ },
+
+ canUpdate() {
+ return this.authorize((user) => this.data.user_id === window.App.user.id);
+ },
+ },
+
methods: {
update() {
- axios.patch('/replies/' + this.attributes.id, {
+ axios.patch('/replies/' + this.data.id, {
body: this.body,
});
@@ -24,8 +64,8 @@
},
destroy() {
- axios.delete('/replies/' + this.attributes.id);
- $(this.$el).fadeOut(700, () => flash('Your reply has been deleted.'));
+ axios.delete('/replies/' + this.data.id);
+ this.$emit('deleted', this.data.id);
},
},
}
diff --git a/resources/js/pages/Thread.vue b/resources/js/pages/Thread.vue
new file mode 100644
index 0000000..6e23f2d
--- /dev/null
+++ b/resources/js/pages/Thread.vue
@@ -0,0 +1,18 @@
+<script>
+ import Replies from "../components/Replies";
+ export default {
+ props: [
+ 'initialRepliesCount',
+ ],
+
+ components: {
+ Replies,
+ },
+
+ data() {
+ return {
+ repliesCount: this.initialRepliesCount,
+ };
+ },
+ }
+</script>
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
index 038ac9f..3e22493 100644
--- a/resources/views/layouts/app.blade.php
+++ b/resources/views/layouts/app.blade.php
@@ -22,6 +22,13 @@
<style>
[v-cloak] { display: none; }
</style>
+
+ <script>
+ window.App = {!! json_encode([
+ 'signedIn' => Auth::check(),
+ 'user' => Auth::user(),
+ ]) !!}
+ </script>
</head>
<body>
<div id="app">
diff --git a/resources/views/threads/reply.blade.php b/resources/views/threads/reply.blade.php
index 7228866..264f301 100644
--- a/resources/views/threads/reply.blade.php
+++ b/resources/views/threads/reply.blade.php
@@ -1,4 +1,4 @@
-<reply :attributes="{{ $reply }}" inline-template>
+<reply :data="{{ $reply }}" inline-template>
<div id="reply-{{ $reply->id }}" class="card mb-3">
<div class="card-header level">
<h5 class="flex">
diff --git a/resources/views/threads/show.blade.php b/resources/views/threads/show.blade.php
index 8716b8a..47851c5 100644
--- a/resources/views/threads/show.blade.php
+++ b/resources/views/threads/show.blade.php
@@ -1,6 +1,7 @@
@extends('layouts.app')
@section('content')
+ <thread-view :initial-replies-count="{{ $thread->replies_count }}" inline-template>
<div class="container">
<div class="row">
<div class="col-md-8">
@@ -27,11 +28,9 @@
</div>
</div>
- @foreach($replies as $reply)
- @include('threads.reply')
- @endforeach
+ <replies :data="{{ $thread->replies }}" @removed="repliesCount--"></replies>
- {{ $replies->links() }}
+ {{-- {{ $replies->links() }}--}}
@auth
<form action="{{ $thread->path() }}/replies" method="post">
@@ -59,11 +58,13 @@
<div class="card">
<div class="card-body">
This thread was published {{ $thread->created_at->diffForHumans() }}
- by <a href="#">{{ $thread->creator->name }}</a> and has {{ $thread->replies_count }}
+ by <a href="#">{{ $thread->creator->name }}</a> and has
+ <span v-text="repliesCount"></span>
{{ Illuminate\Support\Str::plural('comment', $thread->replies_count) }}.
</div>
</div>
</div>
</div>
</div>
+ </thread-view>
@endsection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment