add profile pictures & (attempt) fix uploads

This commit is contained in:
yuriko 🦊 2025-05-24 22:43:03 -04:00
parent 2aa0689720
commit bb15fc96b4
8 changed files with 92 additions and 9 deletions

20
app/Livewire/App/Pfp.php Normal file
View file

@ -0,0 +1,20 @@
<?php
namespace App\Livewire\App;
use App\Models\User;
use Livewire\Component;
class Pfp extends Component
{
public User $user;
public string $size = '3rem';
public string $shape = 'circle';
public function render()
{
return view('livewire.app.pfp', [
'pfp' => $this->user->getAvatarBase64()
]);
}
}

View file

@ -3,14 +3,38 @@
namespace App\Livewire\Pages;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Livewire\WithFileUploads;
class Profile extends Component
{
use WithFileUploads;
public User $user;
#[Validate('image|max:10240')]
public $avatar = null;
public function render()
{
return view('livewire.pages.profile')->title($this->user->name);
}
public function updated($name, $value)
{
if (Auth::id() != $this->user->id)
{
abort(401);
}
$this->validateOnly($name);
$this->user->avatarExt = $this->avatar->getClientOriginalExtension();
$this->user->save();
$this->avatar->storeAs('avatars', $this->user->id);
return $this->redirect("/profiles/{$this->user->id}");
}
}

View file

@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\HasApiTokens;
use MongoDB\Laravel\Auth\User as Authenticatable;
use MongoDB\Laravel\Relations\HasMany;
@ -21,6 +22,7 @@ class User extends Authenticatable implements Searchable
protected $fillable = [
'name',
'email',
'avatarExt',
];
protected $hidden = [
@ -55,4 +57,12 @@ class User extends Authenticatable implements Searchable
$url
);
}
public function getAvatarBase64(): string
{
$ext = $this->avatarExt;
$file = Storage::get("avatars/$this->id");
$data = base64_encode($file);
return "data:image/$ext;base64,$data";
}
}

View file

@ -5,7 +5,7 @@
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<h3 class="wa-caption-m">{{ $title }}</h3>
<wa-format-number class="wa-heading-l" :$value></wa-format-number>
<wa-format-number class="wa-heading-l" value="{{ $value }}"></wa-format-number>
</div>
</div>
</wa-card>

View file

@ -35,7 +35,12 @@
@endguest
@auth
<wa-button href="{{ url('/profiles/' . Auth::id()) }}" appearance="plain" wire:navigate.hover>{{ Auth::user()->name }}</wa-button>
<div class="wa-cluster wa-gap-3xs wa-align-items-center">
<livewire:app.pfp :user="Auth::user()" size="2rem" />
<wa-button href="{{ url('/profiles/' . Auth::id()) }}" appearance="plain" wire:navigate.hover>
{{ Auth::user()->name }}
</wa-button>
</div>
<wa-icon-button href="{{ route('logout') }}" appearance="plain" name="arrow-left-from-bracket"></wa-icon-button>
@endauth
</div>

View file

@ -0,0 +1,2 @@
<wa-avatar image="{{ $pfp }}" label="{{ $user->name }}'s Profile Picture" shape="{{ $shape }}" loading="lazy" style="--size: {{ $size }}">
</wa-avatar>

View file

@ -1,8 +1,30 @@
<div class="wa-stack">
<div class="wa-stack wa-gap-3xl">
<div class="wa-stack">
<div class="wa-flank wa-align-items-center">
<livewire:app.pfp :$user size="5rem" shape="rounded" />
<h1>{{ $user->name }}</h1>
</div>
<div class="wa-grid" style="--min-column-size: 30ch;">
<livewire:app.data-card icon="images" title="Posts" value="{{ $user->posts->count() }}" />
<livewire:app.data-card icon="comments" title="Comments" value="{{ $user->comments->count() }}" />
</div>
</div>
@if (Auth::id() == $user->id)
<div class="wa-stack">
<h2>User settings</h2>
<form wire:submit>
<wa-card>
<div class="wa-stack">
<span class="wa-heading-m">Profile picture</span>
<input type="file" wire:model.live="avatar" wire:loading.attr="disabled" />
@error('avatar')
<span class="wa-caption-m">{{ $message }}</span>
@enderror
</div>
</wa-card>
</form>
</div>
@endif
</div>

View file

@ -1,5 +1,5 @@
<div class="wa-flank wa-align-items-start">
<wa-avatar initials="" label="{{ $comment->user->name }}"></wa-avatar>
<div class="wa-flank wa-align-items-center">
<livewire:app.pfp :user="$comment->user" />
<div class="wa-split">
<div class="wa-stack wa-gap-3xs">
<div class="wa-cluster wa-align-items-center">