diff --git a/Modules/CircleXO/App/Http/Controllers/CircleXOController.php b/Modules/CircleXO/App/Http/Controllers/CircleXOController.php index f04eaee..89b5727 100644 --- a/Modules/CircleXO/App/Http/Controllers/CircleXOController.php +++ b/Modules/CircleXO/App/Http/Controllers/CircleXOController.php @@ -36,8 +36,6 @@ public function verify(Account $account) return redirect()->back(); } - - public function sponsoring($username) { $account = Account::where('username', $username)->first(); @@ -70,6 +68,9 @@ public function post($username, $post) ->first(); if($post){ + if(auth('accounts')->user()){ + auth('accounts')->user()->view($post); + } return view('circle-xo::post', compact('account', 'post')); } else { @@ -147,4 +148,50 @@ public function profile($username, Request $request) abort(404); } } + + public function like($username, $post) + { + $account = Account::where('username', $username)->first(); + if($account){ + $post = AccountListing::where('account_id', $account->id) + ->where('type', 'post') + ->where('id', $post) + ->first(); + + if($post){ + auth('accounts')->user()->like($post); + + return back(); + } + else { + abort(404); + } + } + else { + abort(404); + } + } + + public function unlike($username, $post) + { + $account = Account::where('username', $username)->first(); + if($account){ + $post = AccountListing::where('account_id', $account->id) + ->where('type', 'post') + ->where('id', $post) + ->first(); + + if($post){ + auth('accounts')->user()->unlike($post); + + return back(); + } + else { + abort(404); + } + } + else { + abort(404); + } + } } diff --git a/Modules/CircleXO/App/Http/Controllers/ProfileController.php b/Modules/CircleXO/App/Http/Controllers/ProfileController.php index 8250412..259b8a6 100644 --- a/Modules/CircleXO/App/Http/Controllers/ProfileController.php +++ b/Modules/CircleXO/App/Http/Controllers/ProfileController.php @@ -61,6 +61,11 @@ public function following(Request $request) return view('circle-xo::profile.following'); } + public function followers(Request $request) + { + return view('circle-xo::profile.followers'); + } + public function messages(Request $request) { return view('circle-xo::profile.messages', [ diff --git a/Modules/CircleXO/App/Models/AccountListing.php b/Modules/CircleXO/App/Models/AccountListing.php index ee80543..a1f33af 100644 --- a/Modules/CircleXO/App/Models/AccountListing.php +++ b/Modules/CircleXO/App/Models/AccountListing.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model; use Multicaret\Acquaintances\Traits\CanBeLiked; use Multicaret\Acquaintances\Traits\CanBeRated; +use Multicaret\Acquaintances\Traits\CanBeViewed; use Multicaret\Acquaintances\Traits\CanLike; use Multicaret\Acquaintances\Traits\CanRate; use Spatie\MediaLibrary\HasMedia; @@ -14,8 +15,8 @@ class AccountListing extends Model implements HasMedia { use InteractsWithMedia; - use CanLike, CanBeLiked; - use CanRate, CanBeRated; + use CanBeLiked; + use CanBeViewed; /** * The attributes that are mass assignable. diff --git a/Modules/CircleXO/App/Providers/CircleXOServiceProvider.php b/Modules/CircleXO/App/Providers/CircleXOServiceProvider.php index 1c28fe1..db337a2 100644 --- a/Modules/CircleXO/App/Providers/CircleXOServiceProvider.php +++ b/Modules/CircleXO/App/Providers/CircleXOServiceProvider.php @@ -2,6 +2,7 @@ namespace Modules\CircleXO\App\Providers; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; @@ -56,6 +57,8 @@ public function registerComponents(): void \Modules\CircleXO\App\View\Components\ProfileButtons::class, \Modules\CircleXO\App\View\Components\ProfileInfo::class, \Modules\CircleXO\App\View\Components\ListingType::class, + \Modules\CircleXO\App\View\Components\Recap::class, + \Modules\CircleXO\App\View\Components\Share::class, ]); } diff --git a/Modules/CircleXO/App/View/Components/Recap.php b/Modules/CircleXO/App/View/Components/Recap.php new file mode 100644 index 0000000..a9badd8 --- /dev/null +++ b/Modules/CircleXO/App/View/Components/Recap.php @@ -0,0 +1,51 @@ +type === 'hidden'; + } + + + + /** + * Get the view/contents that represent the component. + */ + public function render(): View|string + { + return view('circle-xo::components.recap'); + } +} diff --git a/Modules/CircleXO/App/View/Components/Share.php b/Modules/CircleXO/App/View/Components/Share.php new file mode 100644 index 0000000..9f65dcc --- /dev/null +++ b/Modules/CircleXO/App/View/Components/Share.php @@ -0,0 +1,30 @@ + @endif @endif + + + + + + + diff --git a/Modules/CircleXO/resources/views/components/profile-card.blade.php b/Modules/CircleXO/resources/views/components/profile-card.blade.php index ce19737..ca2fcb4 100644 --- a/Modules/CircleXO/resources/views/components/profile-card.blade.php +++ b/Modules/CircleXO/resources/views/components/profile-card.blade.php @@ -38,6 +38,12 @@ @endif @endif -
Joined {{ $account->created_at->diffForHumans() }}
+
+ {{ $account->followers()->count() .' ' . __('Followers')}} . + {{ $account->followings()->count() .' ' . __('Following') }} +
+
+ {{__('Joined')}} {{ $account->created_at->diffForHumans() }} +
diff --git a/Modules/CircleXO/resources/views/components/profile-info.blade.php b/Modules/CircleXO/resources/views/components/profile-info.blade.php index 1cd1fc1..605742c 100644 --- a/Modules/CircleXO/resources/views/components/profile-info.blade.php +++ b/Modules/CircleXO/resources/views/components/profile-info.blade.php @@ -40,5 +40,14 @@ @endif -
{{__('Joined')}} {{ $account->created_at->diffForHumans() }}
+
+ @if($edit) + {{ $account->followers()->count() .' ' . __('Followers')}} . + {{ $account->followings()->count() .' ' . __('Following') }} . + @else + {{ $account->followers()->count() .' ' . __('Followers')}} . + {{ $account->followings()->count() .' ' . __('Following') }} . + @endif + {{__('Joined')}} {{ $account->created_at->diffForHumans() }} +
diff --git a/Modules/CircleXO/resources/views/components/recap.blade.php b/Modules/CircleXO/resources/views/components/recap.blade.php new file mode 100644 index 0000000..7dd5e73 --- /dev/null +++ b/Modules/CircleXO/resources/views/components/recap.blade.php @@ -0,0 +1,6 @@ +only(['v-if', 'v-show', 'class', 'v-model', 'v-bind:hasError'])->class(['hidden' => $isHidden()]) }} + v-model="{{ $vueModel() }}" + siteKey="6LfudzMnAAAAAPyF1Z1wXFBEve9KqZE8ykJEZNsR" +> + diff --git a/Modules/CircleXO/resources/views/components/share.blade.php b/Modules/CircleXO/resources/views/components/share.blade.php new file mode 100644 index 0000000..1a8dc93 --- /dev/null +++ b/Modules/CircleXO/resources/views/components/share.blade.php @@ -0,0 +1,96 @@ + + + {{ $slot }} + + + +
+
+
+ +
+
+ {{__('Share On Facebook')}} +
+
+
+
+ +
+
+
+ +
+
+ {{__('Share On Twitter')}} +
+
+
+
+ +
+
+
+ +
+
+ {{__('Share On Linkedin')}} +
+
+
+
+ +
+
+
+ +
+
+ {{__('Share On Whatsapp')}} +
+
+
+
+ +
+
+
+ +
+
+ {{__('Share On Telegram')}} +
+
+
+
+
diff --git a/Modules/CircleXO/resources/views/post.blade.php b/Modules/CircleXO/resources/views/post.blade.php index 3c8d764..4793b40 100644 --- a/Modules/CircleXO/resources/views/post.blade.php +++ b/Modules/CircleXO/resources/views/post.blade.php @@ -24,4 +24,49 @@
+ @if(auth('accounts')->user()) +
+
+ @if(!auth('accounts')->user()->hasLiked($post)) + + +
+
+ +
+
+
+

{{ $post->likers()->count() }}

+
+
+
+
+
+ @else + + +
+
+ +
+
+

{{ $post->likers()->count() }}

+
+
+
+
+ @endif +
+ +
+ + + + + + + +
+
+ @endif diff --git a/Modules/CircleXO/resources/views/profile/edit/social-edit.blade.php b/Modules/CircleXO/resources/views/profile/edit/social-edit.blade.php index af75354..cd507af 100644 --- a/Modules/CircleXO/resources/views/profile/edit/social-edit.blade.php +++ b/Modules/CircleXO/resources/views/profile/edit/social-edit.blade.php @@ -20,6 +20,7 @@ + diff --git a/Modules/CircleXO/resources/views/profile/edit/social.blade.php b/Modules/CircleXO/resources/views/profile/edit/social.blade.php index 11d39b1..402603d 100644 --- a/Modules/CircleXO/resources/views/profile/edit/social.blade.php +++ b/Modules/CircleXO/resources/views/profile/edit/social.blade.php @@ -20,6 +20,7 @@ + diff --git a/Modules/CircleXO/resources/views/profile/followers.blade.php b/Modules/CircleXO/resources/views/profile/followers.blade.php new file mode 100644 index 0000000..6b1e98c --- /dev/null +++ b/Modules/CircleXO/resources/views/profile/followers.blade.php @@ -0,0 +1,27 @@ + +
+ @if(!auth('accounts')->user()->followers()->get()->count()) +
+
+ +

{{__("You still don't follow any user!")}}

+
+
+ @else + @php + $followers = auth('accounts')->user()->followers()->paginate(8); + @endphp + +
+ @foreach($followers as $follower) + + @endforeach +
+ +
+ {!! $followers->links('tomato-admin::components.pagination') !!} +
+ + @endif +
+
diff --git a/Modules/CircleXO/routes/web.php b/Modules/CircleXO/routes/web.php index 43126bd..359f01f 100644 --- a/Modules/CircleXO/routes/web.php +++ b/Modules/CircleXO/routes/web.php @@ -52,6 +52,7 @@ Route::get('/qr', [ProfileController::class, 'qr'])->name('qr'); Route::post('/qr', [ProfileController::class, 'qrUpdate'])->name('qr.update'); Route::get('/following', [ProfileController::class, 'following'])->name('following'); + Route::get('/followers', [ProfileController::class, 'followers'])->name('followers'); Route::get('/messages', [ProfileController::class, 'messages'])->name('messages'); Route::get('/messages/{message}', [ProfileController::class, 'message'])->name('messages.show'); Route::get('/edit/social-accounts', [ProfileController::class, 'socialAccounts'])->name('social-accounts.show'); @@ -104,3 +105,9 @@ Route::post('/{username}/contact', [CircleXOController::class, 'send'])->name('home.contact.send'); Route::get('/{username}/posts/{post}', [CircleXOController::class, 'post'])->name('home.posts'); }); + +Route::middleware(['splade', 'auth:accounts'])->group(function (){ + Route::post('/{username}/posts/{post}/like', [CircleXOController::class, 'like'])->name('home.posts.like'); + Route::post('/{username}/posts/{post}/unlike', [CircleXOController::class, 'unlike'])->name('home.posts.unlike'); + Route::post('/{username}/posts/{post}/rate', [CircleXOController::class, 'rate'])->name('home.posts.rate'); +}); diff --git a/app/Models/Account.php b/app/Models/Account.php index c748bef..97f3699 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -9,6 +9,11 @@ use Laravel\Sanctum\HasApiTokens; use Laravel\Scout\Searchable; use Modules\TomatoNotifications\App\Traits\InteractWithNotifications; +use Multicaret\Acquaintances\Traits\CanBeLiked; +use Multicaret\Acquaintances\Traits\CanBeRated; +use Multicaret\Acquaintances\Traits\CanLike; +use Multicaret\Acquaintances\Traits\CanRate; +use Multicaret\Acquaintances\Traits\CanView; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; use Spatie\Permission\Traits\HasRoles; @@ -47,7 +52,10 @@ class Account extends Authenticatable implements HasMedia use InteractsWithMedia; use HasApiTokens, HasFactory, Notifiable; use InteractWithNotifications; - use CanFollow, CanBeFollowed; + use CanFollow; + use CanBeFollowed; + use CanLike; + use CanView; use Searchable; /** * @var array diff --git a/package.json b/package.json index 82a1549..0103921 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,11 @@ "tippy.js": "^6.3.7", "vue-draggable-next": "^2.2.1", "vue-instantsearch": "^4.14.0", + "vue-social-sharing": "^4.0.0-alpha4", "vue3-carousel": "^0.3.1", "vue3-editor": "^0.1.1", + "vue3-recaptcha2": "^1.8.0", + "vue3-star-ratings": "^3.0.5", "vue3-swatches": "^1.2.3", "vue3-tel-input": "^1.0.4" } diff --git a/resources/js/app.js b/resources/js/app.js index 9f81a76..f955877 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -33,7 +33,10 @@ import InstantSearch from 'vue-instantsearch/vue3/es'; import { MdEditor, MdPreview } from 'md-editor-v3'; import 'md-editor-v3/lib/style.css'; import Search from "./components/Search.vue"; +import vue3StarRatings from "vue3-star-ratings"; +import VueSocialSharing from 'vue-social-sharing'; +import Recap from "./components/Recap.vue"; createApp({ render: renderSpladeApp({ el }) @@ -45,6 +48,9 @@ createApp({ view_transitions: false }) .use(InstantSearch) + .use(VueSocialSharing) + .component("Recap", Recap) + .component("Rating", vue3StarRatings) .component("Search", Search) .component("Swiper", Swiper) .component("SwiperSlide", SwiperSlide) diff --git a/resources/js/components/Recap.vue b/resources/js/components/Recap.vue new file mode 100644 index 0000000..70882b0 --- /dev/null +++ b/resources/js/components/Recap.vue @@ -0,0 +1,64 @@ + + + diff --git a/yarn.lock b/yarn.lock index 5309581..1e5cf53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2556,6 +2556,11 @@ vue-instantsearch@^4.14.0: instantsearch.js "4.66.0" mitt "^2.1.0" +vue-social-sharing@^4.0.0-alpha4: + version "4.0.0-alpha4" + resolved "https://registry.yarnpkg.com/vue-social-sharing/-/vue-social-sharing-4.0.0-alpha4.tgz#48d17f4ff2828c60689f2a065df86588af2bd1fb" + integrity sha512-hMbgpZkY5aRAiznSB/sgzdMVgdSbkmIHEaELX7pUbuUd6KS1Z/GAi7a/q0Qn+GFn0+6qMMvwyp3ZOE0+WYPQ1w== + vue3-carousel@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/vue3-carousel/-/vue3-carousel-0.3.1.tgz#d001be7dea416dc2f4e66afc4d56af66696dc117" @@ -2569,6 +2574,18 @@ vue3-editor@^0.1.1: core-js "^3.6.5" quill "^1.3.7" +vue3-recaptcha2@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/vue3-recaptcha2/-/vue3-recaptcha2-1.8.0.tgz#4a50b0dbfa052568de347dc64d1839d02bdc3384" + integrity sha512-lICGpLGv9wsdVjgWZ0usbZ+Ki52YX5kOzjt8l/ADun9GxdjJ5/AkGpxE7dZ+mG3VcE4ASZG2B/nYWB4wWFadvQ== + +vue3-star-ratings@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/vue3-star-ratings/-/vue3-star-ratings-3.0.5.tgz#43f88467b9498208e6ba45baa213caadb76aeafe" + integrity sha512-V5k/T/7JoEq1VxhtJr1bVdDT181PqbSYMqhyj4myuMFBYXZ2f7bzAcmwFGEkoMmcIg3IVEhroBPUVtPQ4anQDQ== + dependencies: + vue "^3.3.4" + vue3-swatches@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/vue3-swatches/-/vue3-swatches-1.2.4.tgz#24821fd3af99c96ced47a15dbceea72299a8f5c5" @@ -2584,7 +2601,7 @@ vue3-tel-input@^1.0.4: user "^0.0.0" vue "^3.0.0-beta.1" -vue@^3.0.0-beta.1, vue@^3.2.41: +vue@^3.0.0-beta.1, vue@^3.2.41, vue@^3.3.4: version "3.4.21" resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.21.tgz#69ec30e267d358ee3a0ce16612ba89e00aaeb731" integrity sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==