diff --git a/app/Http/Controllers/Forum/CategoriesController.php b/app/Http/Controllers/Forum/CategoriesController.php index d102f3c..0d4d443 100644 --- a/app/Http/Controllers/Forum/CategoriesController.php +++ b/app/Http/Controllers/Forum/CategoriesController.php @@ -3,9 +3,15 @@ namespace App\Http\Controllers\Forum; use App\Http\Controllers\Controller; +use App\Models\Forum\Category; use Illuminate\Http\Request; class CategoriesController extends Controller { - // + public function index() + { + $categories = Category::with('threads')->get(); + + return view('forum.index', compact('categories')); + } } diff --git a/app/Http/Controllers/MediaListController.php b/app/Http/Controllers/MediaListController.php index ccdec60..1d61d63 100644 --- a/app/Http/Controllers/MediaListController.php +++ b/app/Http/Controllers/MediaListController.php @@ -5,6 +5,8 @@ namespace App\Http\Controllers; use App\Http\Requests\MediaListRequest; use App\Models\MediaList; use App\Models\MediaListItem; +use App\Models\Movie; +use App\Models\Show; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -12,27 +14,31 @@ use Illuminate\Support\Str; class MediaListController extends Controller { - public function index() + public function index(string $slug) { $lists = MediaList::whereNotIn('name', MediaList::SPECIAL_LISTS) ->where('user_id', Auth::user()->id) ->get(); - return view('profile.lists.index', compact('lists')); + $user = User::where('slug', $slug)->first(); + + return view('profile.lists.index', compact('lists', 'user')); } public function show(string $userSlug, string $listSlug) { $user = User::where('slug', $userSlug)->first(); $list = MediaList::where('user_id', $user->id)->where('slug', $listSlug)->first(); - $items = MediaListItem::where('media_list_id', $list->id)->paginate(15); + $items = MediaListItem::with('item')->where('media_list_id', $list->id)->paginate(15); - return view('profile.lists.show', compact('list', 'items')); + return view('profile.lists.show', compact('list', 'items', 'user')); } public function create() { - return view('profile.lists.create'); + $user = Auth::user(); + + return view('profile.lists.create', compact('user')); } public function store(MediaListRequest $request) @@ -48,4 +54,49 @@ class MediaListController extends Controller return redirect()->route('profile.list.show', [Auth::user()->slug, $slug]); } + + public function toggleListItem(string $listSlug, int $itemId, string $itemType) + { + $mediaList = MediaList::where('slug', $listSlug) + ->where('user_id', Auth::user()->id) + ->first(); + + if ($itemType == 'movie') { + $item = Movie::find($itemId); + } else { + $item = Show::find($itemId); + } + + if (!$item) { + return response()->json([ + 'success' => false + ]); + } + + $mediaListItem = MediaListItem::where('media_list_id', $mediaList->id) + ->where('item_id', $itemId) + ->where('item_type', $itemType) + ->first(); + + if ($mediaListItem) { + $mediaListItem->delete(); + + return response()->json([ + 'success' => true, + 'added' => false, + ]); + } + + MediaListItem::create([ + 'media_list_id' => $mediaList->id, + 'item_id' => $itemId, + 'item_type' => $itemType, + 'tmdb_id' => $item->tmdb_id, + ]); + + return response()->json([ + 'success' => true, + 'added' => true, + ]); + } } diff --git a/app/Http/Controllers/RatingController.php b/app/Http/Controllers/RatingController.php new file mode 100644 index 0000000..0b10768 --- /dev/null +++ b/app/Http/Controllers/RatingController.php @@ -0,0 +1,28 @@ + auth()->user()->id, + 'item_id' => $itemId, + 'item_type' => $itemType, + ], + [ + 'rate' => $rate + ] + ); + + return response()->json([ + 'success' => true, + 'rate' => $rate, + ]); + } +} diff --git a/app/Models/Forum/Category.php b/app/Models/Forum/Category.php index 9a973d1..ebe74f8 100644 --- a/app/Models/Forum/Category.php +++ b/app/Models/Forum/Category.php @@ -6,5 +6,10 @@ use Illuminate\Database\Eloquent\Model; class Category extends Model { - // + protected $table = 'forum_categories'; + + public function threads() + { + return $this->hasMany(Thread::class, 'category_id', 'id'); + } } diff --git a/app/Models/Forum/Thread.php b/app/Models/Forum/Thread.php index d8b21cc..c175386 100644 --- a/app/Models/Forum/Thread.php +++ b/app/Models/Forum/Thread.php @@ -6,5 +6,5 @@ use Illuminate\Database\Eloquent\Model; class Thread extends Model { - // + protected $table = 'forum_threads'; } diff --git a/app/Models/MediaListItem.php b/app/Models/MediaListItem.php index 5386f1f..454ab3d 100644 --- a/app/Models/MediaListItem.php +++ b/app/Models/MediaListItem.php @@ -12,4 +12,13 @@ class MediaListItem extends Model 'item_type', 'tmdb_id', ]; + + public function item() + { + if ($this->item_type == 'movie') { + return $this->hasOne(Movie::class, 'id', 'item_id'); + } + + return $this->hasOne(Show::class, 'id', 'item_id'); + } } diff --git a/app/Models/Movie.php b/app/Models/Movie.php index b753b06..4c65afd 100644 --- a/app/Models/Movie.php +++ b/app/Models/Movie.php @@ -32,6 +32,32 @@ class Movie extends Model 'release_date' => 'date' ]; + public function wasListedBy(string $listSlug, User $user) + { + $mediaList = MediaList::where('slug', $listSlug)->where('user_id', $user->id)->first(); + + if ($mediaList) { + $mediaListItem = MediaListItem::where('media_list_id', $mediaList->id) + ->where('item_id', $this->id) + ->where('item_type', 'movie') + ->first(); + + return !empty($mediaListItem); + } + + return false; + } + + public function ratingBy(User $user) + { + $rating = Rate::where('user_id', $user->id) + ->where('item_id', $this->id) + ->where('item_type', 'movie') + ->first(); + + return $rating ? $rating->rate : null; + } + public function director() { return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id') diff --git a/app/Models/Rate.php b/app/Models/Rate.php new file mode 100644 index 0000000..aaa0284 --- /dev/null +++ b/app/Models/Rate.php @@ -0,0 +1,17 @@ +where('tmdb_id', $tmdbReview['id']) ->first(); + // @todo create user + $user = User::where('name', $tmdbReview['author'])->first(); + + if (!$user) { + $user = User::create([ + 'name' => $tmdbReview['author'], + 'slug' => Str::slug($tmdbReview['author']), + 'email' => $tmdbReview['author'].'@nowhere.wtf', + 'password' => 'no_password_neeeded_here', + 'is_dummy_account' => true, + ]); + } + + if (!$existingReview) { Comment::create([ 'entity_id' => $movie->id, 'entity_type' => Comment::TYPE_MOVIE, + 'user_id' => $user->id, 'author_name' => $tmdbReview['author'], 'author_avatar' => $tmdbReview['author_details']['avatar_path'], 'author_rating' => $tmdbReview['author_details']['rating'], diff --git a/app/Service/ToolService.php b/app/Service/ToolService.php new file mode 100644 index 0000000..550adfa --- /dev/null +++ b/app/Service/ToolService.php @@ -0,0 +1,18 @@ +path(); + $uri = ltrim(str_replace(env('APP_URL'), '', $routePath), '/'); + + return $currentPath == $uri; + } +} diff --git a/database/migrations/2025_01_27_191007_create_threads_table.php b/database/migrations/2025_01_27_191007_create_threads_table.php index 691ce56..37f2ab7 100644 --- a/database/migrations/2025_01_27_191007_create_threads_table.php +++ b/database/migrations/2025_01_27_191007_create_threads_table.php @@ -16,8 +16,8 @@ return new class extends Migration $table->unsignedBigInteger('category_id'); $table->string('name'); $table->string('slug'); - $table->string('icon'); - $table->text('description'); + $table->string('icon')->nullable(); + $table->text('description')->nullable(); $table->integer('order')->default(0); $table->timestamps(); }); diff --git a/database/migrations/2025_01_31_221518_create_rates_table.php b/database/migrations/2025_01_31_221518_create_rates_table.php new file mode 100644 index 0000000..7b56bed --- /dev/null +++ b/database/migrations/2025_01_31_221518_create_rates_table.php @@ -0,0 +1,31 @@ +id(); + $table->unsignedBigInteger('item_id'); + $table->enum('item_type', ['movie', 'show']); + $table->decimal('rate', 10, 2); + $table->unsignedBigInteger('user_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('ratings'); + } +}; diff --git a/package-lock.json b/package-lock.json index 455d8f8..defe277 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,9 @@ "requires": true, "packages": { "": { + "dependencies": { + "jquery": "^3.7.1" + }, "devDependencies": { "@popperjs/core": "^2.11.6", "autoprefixer": "^10.4.20", @@ -2065,6 +2068,12 @@ "jiti": "bin/jiti.js" } }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, "node_modules/laravel-vite-plugin": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.1.1.tgz", diff --git a/package.json b/package.json index 5a70f21..8725fd7 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,8 @@ "sass": "^1.56.1", "tailwindcss": "^3.4.13", "vite": "^6.0" + }, + "dependencies": { + "jquery": "^3.7.1" } } diff --git a/public/img/email-pattern.webp b/public/img/email-pattern.webp new file mode 100644 index 0000000..019ef43 Binary files /dev/null and b/public/img/email-pattern.webp differ diff --git a/public/img/folk-pattern.webp b/public/img/folk-pattern.webp new file mode 100644 index 0000000..badec3c Binary files /dev/null and b/public/img/folk-pattern.webp differ diff --git a/public/img/funky-lines.webp b/public/img/funky-lines.webp new file mode 100644 index 0000000..9385220 Binary files /dev/null and b/public/img/funky-lines.webp differ diff --git a/public/img/greek-vase.webp b/public/img/greek-vase.webp new file mode 100644 index 0000000..dc7e7f2 Binary files /dev/null and b/public/img/greek-vase.webp differ diff --git a/public/img/hypnotize.webp b/public/img/hypnotize.webp new file mode 100644 index 0000000..0afc58f Binary files /dev/null and b/public/img/hypnotize.webp differ diff --git a/public/img/leaves-pattern.webp b/public/img/leaves-pattern.webp new file mode 100644 index 0000000..efe7172 Binary files /dev/null and b/public/img/leaves-pattern.webp differ diff --git a/public/img/star_rating.png b/public/img/star_rating.png new file mode 100644 index 0000000..5a47a34 Binary files /dev/null and b/public/img/star_rating.png differ diff --git a/public/img/user_no_avatar.png b/public/img/user_no_avatar.png new file mode 100644 index 0000000..9d8e08a Binary files /dev/null and b/public/img/user_no_avatar.png differ diff --git a/public/uploads/forums/categories/cinema.png b/public/uploads/forums/categories/cinema.png new file mode 100644 index 0000000..10c53f7 Binary files /dev/null and b/public/uploads/forums/categories/cinema.png differ diff --git a/public/uploads/forums/categories/film-camera.png b/public/uploads/forums/categories/film-camera.png new file mode 100644 index 0000000..f06dbe8 Binary files /dev/null and b/public/uploads/forums/categories/film-camera.png differ diff --git a/public/uploads/forums/categories/popcorn.png b/public/uploads/forums/categories/popcorn.png new file mode 100644 index 0000000..98fbe26 Binary files /dev/null and b/public/uploads/forums/categories/popcorn.png differ diff --git a/resources/js/app.js b/resources/js/app.js index e59d6a0..2439f8b 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1 +1,62 @@ import './bootstrap'; +import './star_rating'; + +import $ from 'jquery'; + +$(".my-rating").starRating({ + starSize: 20, + totalStars: 10, + callback: function(currentRating, $el){ + let type = $($el[0]).data('type'); + let id = $($el[0]).data('id'); + + let url = '/rate/'+type+'/'+id+'/'+currentRating; + + var self = this + + $.ajax({ + url: url, + method: 'GET', + success: function(data){ + $(self).attr('data-rating', currentRating) + } + }); + } +}); + +$('.mark-as-seen-btn').on('click', function (e) { + e.preventDefault(); + let url = '/lists/' + $(this).data('list') + '/' + $(this).data('id') + '/' + $(this).data('type'); + var self = this + $.ajax({ + url: url, + method: 'GET', + success: function(data){ + if(data.added) { + $(self).addClass('seen'); + } else { + $(self).removeClass('seen'); + } + + } + }); + return false; +}); + +$('.like-btn').on('click', function (e) { + e.preventDefault(); + let url = '/lists/' + $(this).data('list') + '/' + $(this).data('id') + '/' + $(this).data('type'); + var self = this + $.ajax({ + url: url, + method: 'GET', + success: function(data){ + if(data.added) { + $(self).addClass('liked'); + } else { + $(self).removeClass('liked'); + } + } + }); + return false; +}); diff --git a/resources/js/star_rating.js b/resources/js/star_rating.js new file mode 100644 index 0000000..5195de7 --- /dev/null +++ b/resources/js/star_rating.js @@ -0,0 +1,343 @@ +import $ from 'jquery'; + +/* + * jQuery StarRatingSvg v1.2.0 + * + * http://github.com/nashio/star-rating-svg + * Author: Ignacio Chavez + * hello@ignaciochavez.com + * Licensed under MIT + */ + +;(function ( $, window, document, undefined ) { + + 'use strict'; + + // Create the defaults once + var pluginName = 'starRating'; + var noop = function(){}; + var defaults = { + totalStars: 5, + useFullStars: false, + starShape: 'straight', + emptyColor: 'lightgray', + hoverColor: 'orange', + activeColor: 'gold', + ratedColor: 'crimson', + useGradient: true, + readOnly: false, + disableAfterRate: true, + baseUrl: false, + starGradient: { + start: '#FEF7CD', + end: '#FF9511' + }, + strokeWidth: 4, + strokeColor: 'black', + initialRating: 0, + starSize: 40, + callback: noop, + onHover: noop, + onLeave: noop + }; + + // The actual plugin constructor + var Plugin = function( element, options ) { + var _rating; + var newRating; + var roundFn; + + this.element = element; + this.$el = $(element); + this.settings = $.extend( {}, defaults, options ); + + // grab rating if defined on the element + _rating = this.$el.data('rating') || this.settings.initialRating; + + // round to the nearest half + roundFn = this.settings.forceRoundUp ? Math.ceil : Math.round; + newRating = (roundFn( _rating * 2 ) / 2).toFixed(1); + this._state = { + rating: newRating + }; + + // create unique id for stars + this._uid = Math.floor( Math.random() * 999 ); + + // override gradient if not used + if( !options.starGradient && !this.settings.useGradient ){ + this.settings.starGradient.start = this.settings.starGradient.end = this.settings.activeColor; + } + + this._defaults = defaults; + this._name = pluginName; + this.init(); + }; + + var methods = { + init: function () { + this.renderMarkup(); + this.addListeners(); + this.initRating(); + }, + + addListeners: function(){ + if( this.settings.readOnly ){ return; } + this.$stars.on('mouseover', this.hoverRating.bind(this)); + this.$stars.on('mouseout', this.restoreState.bind(this)); + this.$stars.on('click', this.handleRating.bind(this)); + }, + + // apply styles to hovered stars + hoverRating: function(e){ + var index = this.getIndex(e); + this.paintStars(index, 'hovered'); + this.settings.onHover(index + 1, this._state.rating, this.$el); + }, + + // clicked on a rate, apply style and state + handleRating: function(e){ + var index = this.getIndex(e); + var rating = index + 1; + + this.applyRating(rating, this.$el); + this.executeCallback( rating, this.$el ); + + if(this.settings.disableAfterRate){ + this.$stars.off(); + } + }, + + applyRating: function(rating){ + var index = rating - 1; + // paint selected and remove hovered color + this.paintStars(index, 'rated'); + this._state.rating = index + 1; + this._state.rated = true; + }, + + restoreState: function(e){ + var index = this.getIndex(e); + var rating = this._state.rating || -1; + // determine star color depending on manually rated + var colorType = this._state.rated ? 'rated' : 'active'; + this.paintStars(rating - 1, colorType); + this.settings.onLeave(index + 1, this._state.rating, this.$el); + }, + + getIndex: function(e){ + var $target = $(e.currentTarget); + var width = $target.width(); + var side = $(e.target).attr('data-side'); + var minRating = this.settings.minRating; + + // hovered outside the star, calculate by pixel instead + side = (!side) ? this.getOffsetByPixel(e, $target, width) : side; + side = (this.settings.useFullStars) ? 'right' : side ; + + // get index for half or whole star + var index = $target.index() - ((side === 'left') ? 0.5 : 0); + + // pointer is way to the left, rating should be none + index = ( index < 0.5 && (e.offsetX < width / 4) ) ? -1 : index; + + // force minimum rating + index = ( minRating && minRating <= this.settings.totalStars && index < minRating ) ? minRating - 1 : index; + return index; + }, + + getOffsetByPixel: function(e, $target, width){ + var leftX = e.pageX - $target.offset().left; + return ( leftX <= (width / 2) && !this.settings.useFullStars) ? 'left' : 'right'; + }, + + initRating: function(){ + this.paintStars(this._state.rating - 1, 'active'); + }, + + paintStars: function(endIndex, stateClass){ + var $polygonLeft; + var $polygonRight; + var leftClass; + var rightClass; + var s = this.settings; + + $.each(this.$stars, function(index, star){ + $polygonLeft = $(star).find('[data-side="left"]'); + $polygonRight = $(star).find('[data-side="right"]'); + leftClass = rightClass = (index <= endIndex) ? stateClass : 'empty'; + + // has another half rating, add half star + leftClass = ( index - endIndex === 0.5 ) ? stateClass : leftClass; + + $polygonLeft.attr('class', 'svg-' + leftClass + '-' + this._uid); + $polygonRight.attr('class', 'svg-' + rightClass + '-' + this._uid); + + // get color for level + var ratedColorsIndex = endIndex >= 0 ? Math.ceil(endIndex) : 0; + + var ratedColor; + if (s.ratedColors && s.ratedColors.length && s.ratedColors[ratedColorsIndex]) { + ratedColor = s.ratedColors[ratedColorsIndex]; + } else { + ratedColor = this._defaults.ratedColor; + } + + // only override colors in rated stars and when rated number is valid + if (stateClass === 'rated' && endIndex > -1) { + // limit to painting only to rated stars, and specific case for half star + if (index <= Math.ceil(endIndex) || (index < 1 && endIndex < 0)) { + $polygonLeft.attr('style', 'fill:'+ratedColor); + } + if (index <= endIndex) { + $polygonRight.attr('style', 'fill:'+ratedColor); + } + } + }.bind(this)); + }, + + renderMarkup: function () { + var s = this.settings; + var baseUrl = s.baseUrl ? location.href.split('#')[0] : ''; + + // inject an svg manually to have control over attributes + var star = '
' + + + this.getLinearGradient(this._uid + '_SVGID_1_', s.emptyColor, s.emptyColor, s.starShape) + + this.getLinearGradient(this._uid + '_SVGID_2_', s.hoverColor, s.hoverColor, s.starShape) + + this.getLinearGradient(this._uid + '_SVGID_3_', s.starGradient.start, s.starGradient.end, s.starShape) + + this.getVectorPath(this._uid, { + starShape: s.starShape, + strokeWidth: s.strokeWidth, + strokeColor: s.strokeColor + } ) + + '
'; + + // inject svg markup + var starsMarkup = ''; + for( var i = 0; i < s.totalStars; i++){ + starsMarkup += star; + } + this.$el.append(starsMarkup); + this.$stars = this.$el.find('.jq-star'); + }, + + getVectorPath: function(id, attrs){ + return (attrs.starShape === 'rounded') ? + this.getRoundedVectorPath(id, attrs) : this.getSpikeVectorPath(id, attrs); + }, + + getSpikeVectorPath: function(id, attrs){ + return '' + + '' + + ''; + }, + + getRoundedVectorPath: function(id, attrs){ + var fullPoints = 'M520.9,336.5c-3.8-11.8-14.2-20.5-26.5-22.2l-140.9-20.5l-63-127.7 c-5.5-11.2-16.8-18.2-29.3-18.2c-12.5,0-23.8,7-29.3,18.2l-63,127.7L28,314.2C15.7,316,5.4,324.7,1.6,336.5S1,361.3,9.9,370 l102,99.4l-24,140.3c-2.1,12.3,2.9,24.6,13,32c5.7,4.2,12.4,6.2,19.2,6.2c5.2,0,10.5-1.2,15.2-3.8l126-66.3l126,66.2 c4.8,2.6,10,3.8,15.2,3.8c6.8,0,13.5-2.1,19.2-6.2c10.1-7.3,15.1-19.7,13-32l-24-140.3l102-99.4 C521.6,361.3,524.8,348.3,520.9,336.5z'; + + return ''; + }, + + getSvgDimensions: function(starShape){ + return (starShape === 'rounded') ? 'width="550px" height="500.2px" viewBox="0 146.8 550 500.2" style="enable-background:new 0 0 550 500.2;' : 'x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305;'; + }, + + getLinearGradient: function(id, startColor, endColor, starShape){ + var height = (starShape === 'rounded') ? 500 : 250; + return ' '; + }, + + executeCallback: function(rating, $el){ + var callback = this.settings.callback; + callback(rating, $el); + } + + }; + + var publicMethods = { + + unload: function() { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name).$stars; + $starSet.off(); + $el.removeData(_name).remove(); + }, + + setRating: function(rating, round) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $plugin = $el.data(_name); + if( rating > $plugin.settings.totalStars || rating < 0 ) { return; } + if( round ){ + rating = Math.round(rating); + } + $plugin.applyRating(rating); + }, + + getRating: function() { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name); + return $starSet._state.rating; + }, + + resize: function(newSize) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $starSet = $el.data(_name); + var $stars = $starSet.$stars; + + if(newSize <= 1 || newSize > 200) { + console.error('star size out of bounds'); + return; + } + + $stars = Array.prototype.slice.call($stars); + $stars.forEach(function(star){ + $(star).css({ + 'width': newSize + 'px', + 'height': newSize + 'px' + }); + }); + }, + + setReadOnly: function(flag) { + var _name = 'plugin_' + pluginName; + var $el = $(this); + var $plugin = $el.data(_name); + if(flag === true){ + $plugin.$stars.off('mouseover mouseout click'); + } else { + $plugin.settings.readOnly = false; + $plugin.addListeners(); + } + } + + }; + + + // Avoid Plugin.prototype conflicts + $.extend(Plugin.prototype, methods); + + $.fn[ pluginName ] = function ( options ) { + + // if options is a public method + if( !$.isPlainObject(options) ){ + if( publicMethods.hasOwnProperty(options) ){ + return publicMethods[options].apply(this, Array.prototype.slice.call(arguments, 1)); + } else { + $.error('Method '+ options +' does not exist on ' + pluginName + '.js'); + } + } + + return this.each(function() { + // preventing against multiple instantiations + if ( !$.data( this, 'plugin_' + pluginName ) ) { + $.data( this, 'plugin_' + pluginName, new Plugin( this, options ) ); + } + }); + }; + +})( $, window, document ); diff --git a/resources/sass/app.scss b/resources/sass/app.scss index d198b7c..af6a8d0 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -16,6 +16,94 @@ body.light-mode{ } .light-mode{ + .forums{ + .category{ + .title{ + font-size: 20px; + line-height: 1; + margin-bottom: 0; + small{ + font-size: 14px; + font-weight: 500; + } + } + } + } + .medium-info-box{ + border: 1px solid #ccc; + border-radius: 15px; + padding: 15px; + text-align: center; + margin-top: 45px; + } + .profile-page{ + background: #ccc; + padding: 15px 0; + margin-top: -50px; + .user-avatar{ + width: 125px; + border-radius: 50%; + border: 2px solid white; + box-shadow: 1px 1px 1px #b5b3b3; + } + h1{ + display: inline-block; + margin-right: 15px; + } + &.pattern1{ + background: url("/public/img/email-pattern.webp"); + } + &.pattern2{ + background: url("/public/img/greek-vase.webp"); + } + &.pattern3{ + background: url("/public/img/hypnotize.webp"); + } + &.pattern4{ + background: url("/public/img/funky-lines.webp"); + } + &.pattern5{ + background: url("/public/img/leaves-pattern.webp"); + } + &.pattern6{ + background: url("/public/img/folk-pattern.webp"); + } + } + .profile-page-menu{ + background: rgba(255, 255, 255, .3); + ul{ + margin: 0; + li{ + padding: 5px; + a{ + text-decoration: none; + &:hover{} + &.active{ + color: black; + text-decoration: underline; + } + } + } + } + } + .large-list-item{ + margin: 15px 0; + border-radius: 5px; + background: white; + border: 1px solid #ccc; + box-shadow: 0px 0px 5px #ccc; + .poster{ + border-bottom-left-radius: 5px; + border-top-left-radius: 5px; + } + } + .jq-star{ + display: inline-block; + svg{ + max-width: 20px; + max-height: 20px; + } + } header{ background: white; padding-right: 1rem; @@ -70,4 +158,55 @@ body.light-mode{ } } } + .user-actions{ + padding: 5px; + .mark-as-seen-btn{ + margin-top: 5px; + display: block; + border: 1px solid #903eb3; + padding: 7px 10px; + text-decoration: none; + &:hover{ + color: white; + transition: all .5s; + background: #903eb3; + } + &.seen{ + color: white; + background: #903eb3; + } + } + .like-btn{ + display: block; + margin-top: 5px; + padding: 7px 10px; + text-decoration: none; + border: 1px solid #16a085; + &:hover{ + color: white; + transition: all .5s; + background: #16a085; + } + &.liked{ + color: white; + background: #16a085; + } + } + .add-to-list-btn{ + display: block; + margin-top: 5px; + padding: 7px 10px; + text-decoration: none; + border: 1px solid #ff5f06; + &:hover{ + color: white; + transition: all .5s; + background: #ff5f06; + } + &.listed{ + color: white; + background: #ff5f06; + } + } + } } diff --git a/resources/views/celebrity/show.blade.php b/resources/views/celebrity/show.blade.php index 40663f0..8c88cf9 100644 --- a/resources/views/celebrity/show.blade.php +++ b/resources/views/celebrity/show.blade.php @@ -14,11 +14,27 @@
- birth / death + @if($celebrity->birtday) + Birthday {{ $celebrity->birtday }} @if($celebrity->palce_of_birth) ({{ $celebrity->palce_of_birth }}) @endif + @endif + @if($celebrity->deathday) + Deathday {{ $celebrity->deathday }} + @endif

{{ $celebrity->biography }}

- info movies + @if($celebrity->also_known_as) +

+ Also known as: + @foreach(json_decode($celebrity->also_known_as ?? "{}", true) as $alsoKnown) + {{ $alsoKnown }} + @if(!$loop->last), @endif + @endforeach +

+ @endif + popularity /
+ tmdb/imdb/homepage
+ movies
diff --git a/resources/views/forum/index.blade.php b/resources/views/forum/index.blade.php new file mode 100644 index 0000000..55fe916 --- /dev/null +++ b/resources/views/forum/index.blade.php @@ -0,0 +1,71 @@ +@extends('layouts.app') + +@section('content') +
+
+
+ @foreach($categories as $category) +
+
+

+
+ @if($category->icon) +
+
+ +
+
+
+ {{ $category->name }}
+ {{ $category->description }} +
+ @else +
+ {{ $category->name }}
+ {{ $category->description }} +
+ @endif +
+

+
+
+ @foreach($category->threads as $thread) +
+
+ i +
+ +
+ last +
+
+ @endforeach +
+
+ @endforeach +
+
+
+ +
+
+
+
+@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 5e9beef..d24bf1e 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -16,7 +16,7 @@ - + @vite(['resources/sass/app.scss', 'resources/js/app.js']) @livewireStyles @@ -30,5 +30,6 @@ @livewireScripts + diff --git a/resources/views/layouts/header.blade.php b/resources/views/layouts/header.blade.php index 8f62a3d..0d0200d 100644 --- a/resources/views/layouts/header.blade.php +++ b/resources/views/layouts/header.blade.php @@ -7,11 +7,11 @@