diff --git a/twodeesapp/app/Http/Controllers/ProfileController.php b/twodeesapp/app/Http/Controllers/ProfileController.php index 6280e47..ca2d3a8 100644 --- a/twodeesapp/app/Http/Controllers/ProfileController.php +++ b/twodeesapp/app/Http/Controllers/ProfileController.php @@ -7,10 +7,64 @@ class ProfileController extends Controller { public function index($id) { - $user = User::where('id', $id)->first(); + $user = User::find($id); if($user != null) { - return view('profile.index', compact('user')); + $region = $user->location->region; + + if($region != null) { + $country = $region->country; + } + + return view('profile.index', compact('user', 'region', 'country')); + } else { + return redirect()->route('/')->with('error', 'The profile you are searching for does not exist!'); + } + } + + public function upload_profile_picture($id) { + $user = User::find($id); + + if($user != null) { + return view('profile.upload_profile_picture', compact('user')); + } else { + return redirect()->route('/')->with('error', 'The profile you are searching for does not exist!'); + } + } + + public function process_profile_picture_upload($id, Request $request) { + $user = User::find($id); + + if($user != null) { + $request->validate([ + 'profile_picture' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048', + ]); + + $profile_picture = $request->file('profile_picture'); + $profile_picture_name = time() . '.' . $request->profile_picture->extension(); + $profile_picture->move(public_path('profile_pictures'), $profile_picture_name); + + $user->profile_picture = 'profile_pictures/' . $profile_picture_name; + $user->save(); + + return redirect()->route('profile.index', $user->id)->with('success', "Your profile picture has been updated! Looking great! \u{1F60A}"); + } else { + return redirect()->route('/')->with('error', 'The profile you are searching for does not exist!'); + } + } + + public function remove_profile_picture($id, Request $request) { + $user = User::find($id); + + if($user != null) { + if(file_exists(public_path($user->profile_picture))) { + unlink(public_path($user->profile_picture)); + } + + $user->profile_picture = null; + $user->save(); + + return redirect()->route('profile.index', $user->id)->with('success', "Your profile picture has been removed! \u{1F622}"); } else { return redirect()->route('/')->with('error', 'The profile you are searching for does not exist!'); } diff --git a/twodeesapp/app/Models/Category.php b/twodeesapp/app/Models/Category.php index d7d7378..bb67d2a 100644 --- a/twodeesapp/app/Models/Category.php +++ b/twodeesapp/app/Models/Category.php @@ -9,7 +9,7 @@ class Category extends Model { use HasFactory; - protected $fillable = ["name", "imagePath"]; //Technique to enable mass assignment yet again, although in the case overkill since model is only made up of one attribute apart from the id and timestamps. + protected $fillable = ['name', 'image_path']; //Technique to enable mass assignment yet again, although in the case overkill since model is only made up of one attribute apart from the id and timestamps. //Establishing a relationship between Item and Category model (one-to-many relationship whereby one category can be assigned to many items). public function items() { diff --git a/twodeesapp/app/Models/Country.php b/twodeesapp/app/Models/Country.php index 4a793ff..34b095a 100644 --- a/twodeesapp/app/Models/Country.php +++ b/twodeesapp/app/Models/Country.php @@ -9,7 +9,7 @@ class Country extends Model { use HasFactory; - protected $fillable = ["name"]; + protected $fillable = ['name']; public function regions() { return $this->hasMany(Region::class); diff --git a/twodeesapp/app/Models/Item.php b/twodeesapp/app/Models/Item.php index 5c6b2a8..68dc96a 100644 --- a/twodeesapp/app/Models/Item.php +++ b/twodeesapp/app/Models/Item.php @@ -9,7 +9,7 @@ class Item extends Model { use HasFactory; - protected $fillable = ["name", "price", "release_date", "description", "image_path", "category_id"]; //Technique to enable mass assignment. + protected $fillable = ['name', 'price', 'release_date', 'description', 'image_path', 'category_id']; //Technique to enable mass assignment. //Establishing a relationship between Item and Category model (one-to-many relationship whereby one category can be assigned to many items). public function category() { diff --git a/twodeesapp/app/Models/Location.php b/twodeesapp/app/Models/Location.php index c009b27..1dd4ef9 100644 --- a/twodeesapp/app/Models/Location.php +++ b/twodeesapp/app/Models/Location.php @@ -9,7 +9,7 @@ class Location extends Model { use HasFactory; - protected $fillable = ["name", "region_id"]; + protected $fillable = ['name', 'region_id']; public function region() { return $this->belongsTo(Region::class); diff --git a/twodeesapp/app/Models/Region.php b/twodeesapp/app/Models/Region.php index 609c165..bc72c59 100644 --- a/twodeesapp/app/Models/Region.php +++ b/twodeesapp/app/Models/Region.php @@ -9,7 +9,7 @@ class Region extends Model { use HasFactory; - protected $fillable = ["name", "country_id"]; + protected $fillable = ['name', 'country_id']; public function country() { return $this->belongsTo(Country::class); diff --git a/twodeesapp/database/seeders/CountriesTableSeeder.php b/twodeesapp/database/seeders/CountriesTableSeeder.php new file mode 100644 index 0000000..d34d22b --- /dev/null +++ b/twodeesapp/database/seeders/CountriesTableSeeder.php @@ -0,0 +1,14 @@ + 'Malta']); + } +} \ No newline at end of file diff --git a/twodeesapp/database/seeders/DatabaseSeeder.php b/twodeesapp/database/seeders/DatabaseSeeder.php index a9f4519..02f0457 100644 --- a/twodeesapp/database/seeders/DatabaseSeeder.php +++ b/twodeesapp/database/seeders/DatabaseSeeder.php @@ -2,21 +2,16 @@ namespace Database\Seeders; -// use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { - /** - * Seed the application's database. - */ public function run(): void { - // \App\Models\User::factory(10)->create(); - - // \App\Models\User::factory()->create([ - // 'name' => 'Test User', - // 'email' => 'test@example.com', - // ]); + $this->call([ + CountriesTableSeeder::class, + RegionsTableSeeder::class, + LocationsTableSeeder::class + ]); } -} +} \ No newline at end of file diff --git a/twodeesapp/database/seeders/LocationsTableSeeder.php b/twodeesapp/database/seeders/LocationsTableSeeder.php new file mode 100644 index 0000000..c93b1ad --- /dev/null +++ b/twodeesapp/database/seeders/LocationsTableSeeder.php @@ -0,0 +1,100 @@ +first()->id; + $gozoRegion = Region::where('name', 'Gozo Region')->first()->id; + $northernRegion = Region::where('name', 'Northern Region')->first()->id; + $portRegion = Region::where('name', 'Port Region')->first()->id; + $southernRegion = Region::where('name', 'Southern Region')->first()->id; + $westernRegion = Region::where('name', 'Western Region')->first()->id; + + $locationObjects = [ + ['name' => 'Fontana', 'region_id' => $gozoRegion], + ['name' => 'Ghajnsielem', 'region_id' => $gozoRegion], + ['name' => 'Gharb', 'region_id' => $gozoRegion], + ['name' => 'Ghasri', 'region_id' => $gozoRegion], + ['name' => 'Kercem', 'region_id' => $gozoRegion], + ['name' => 'Marsalforn', 'region_id' => $gozoRegion], + ['name' => 'Mgarr (Gozo)', 'region_id' => $gozoRegion], + ['name' => 'Munxar', 'region_id' => $gozoRegion], + ['name' => 'Nadur', 'region_id' => $gozoRegion], + ['name' => 'Qala', 'region_id' => $gozoRegion], + ['name' => 'San Lawrenz', 'region_id' => $gozoRegion], + ['name' => 'Sannat', 'region_id' => $gozoRegion], + ['name' => 'Victoria', 'region_id' => $gozoRegion], + ['name' => 'Xaghra', 'region_id' => $gozoRegion], + ['name' => 'Xewkija', 'region_id' => $gozoRegion], + ['name' => 'Xlendi', 'region_id' => $gozoRegion], + ['name' => 'Zebbug (Gozo)', 'region_id' => $gozoRegion], + ['name' => 'Birkirkara', 'region_id' => $easternRegion], + ['name' => 'Gharghur', 'region_id' => $easternRegion], + ['name' => 'Gzira', 'region_id' => $easternRegion], + ['name' => 'Ibragg', 'region_id' => $easternRegion], + ['name' => 'Iklin', 'region_id' => $easternRegion], + ['name' => 'Lija', 'region_id' => $easternRegion], + ['name' => 'Msida', 'region_id' => $easternRegion], + ['name' => 'Pembroke', 'region_id' => $easternRegion], + ['name' => 'Pietà ', 'region_id' => $easternRegion], + ['name' => 'San Giljan', 'region_id' => $easternRegion], + ['name' => 'Sliema', 'region_id' => $easternRegion], + ['name' => 'Swieqi', 'region_id' => $easternRegion], + ['name' => 'Ta\' Xbiex', 'region_id' => $easternRegion], + ['name' => 'Dingli', 'region_id' => $westernRegion], + ['name' => 'Kirkop', 'region_id' => $westernRegion], + ['name' => 'Mdina', 'region_id' => $westernRegion], + ['name' => 'Mqabba', 'region_id' => $westernRegion], + ['name' => 'Qrendi', 'region_id' => $westernRegion], + ['name' => 'Rabat', 'region_id' => $westernRegion], + ['name' => 'Safi', 'region_id' => $westernRegion], + ['name' => 'Siggiewi', 'region_id' => $westernRegion], + ['name' => 'Zebbug (Malta)', 'region_id' => $westernRegion], + ['name' => 'Zurrieq', 'region_id' => $westernRegion], + ['name' => 'Birzebbuga', 'region_id' => $southernRegion], + ['name' => 'Ghaxaq', 'region_id' => $southernRegion], + ['name' => 'Gudja', 'region_id' => $southernRegion], + ['name' => 'Hamrun', 'region_id' => $southernRegion], + ['name' => 'Luqa', 'region_id' => $southernRegion], + ['name' => 'Marsa', 'region_id' => $southernRegion], + ['name' => 'Marsaskala', 'region_id' => $southernRegion], + ['name' => 'Marsaxlokk', 'region_id' => $southernRegion], + ['name' => 'Qormi', 'region_id' => $southernRegion], + ['name' => 'Santa Lucija', 'region_id' => $southernRegion], + ['name' => 'Santa Venera', 'region_id' => $southernRegion], + ['name' => 'Zejtun', 'region_id' => $southernRegion], + ['name' => 'Birgu', 'region_id' => $portRegion], + ['name' => 'Bormla', 'region_id' => $portRegion], + ['name' => 'Fgura', 'region_id' => $portRegion], + ['name' => 'Floriana', 'region_id' => $portRegion], + ['name' => 'Isla', 'region_id' => $portRegion], + ['name' => 'Kalkara', 'region_id' => $portRegion], + ['name' => 'Paola', 'region_id' => $portRegion], + ['name' => 'Tarxien', 'region_id' => $portRegion], + ['name' => 'Valletta', 'region_id' => $portRegion], + ['name' => 'Xghajra', 'region_id' => $portRegion], + ['name' => 'Zabbar', 'region_id' => $portRegion], + ['name' => 'Attard', 'region_id' => $northernRegion], + ['name' => 'Bahar ic-Caghaq', 'region_id' => $northernRegion], + ['name' => 'Bidnija', 'region_id' => $northernRegion], + ['name' => 'Balzan', 'region_id' => $northernRegion], + ['name' => 'Mellieha', 'region_id' => $northernRegion], + ['name' => 'L-Imgarr', 'region_id' => $northernRegion], + ['name' => 'Mosta', 'region_id' => $northernRegion], + ['name' => 'Mtarfa', 'region_id' => $northernRegion], + ['name' => 'Naxxar', 'region_id' => $northernRegion], + ['name' => 'San Pawl il-Bahar', 'region_id' => $northernRegion], + ]; + + foreach($locationObjects as $locationObject) { + Location::create($locationObject); + } + } +} \ No newline at end of file diff --git a/twodeesapp/database/seeders/RegionsTableSeeder.php b/twodeesapp/database/seeders/RegionsTableSeeder.php new file mode 100644 index 0000000..678bfed --- /dev/null +++ b/twodeesapp/database/seeders/RegionsTableSeeder.php @@ -0,0 +1,28 @@ +first()->id; + + $regionObjects = [ + ['name' => 'Eastern Region', 'country_id' => $malta], + ['name' => 'Gozo Region', 'country_id' => $malta], + ['name' => 'Northern Region', 'country_id' => $malta], + ['name' => 'Port Region', 'country_id' => $malta], + ['name' => 'Southern Region', 'country_id' => $malta], + ['name' => 'Western Region', 'country_id' => $malta] + ]; + + foreach($regionObjects as $regionObject) { + Region::create($regionObject); + } + } +} diff --git a/twodeesapp/public/images/1737318350.jpg b/twodeesapp/public/images/1737318350.jpg deleted file mode 100644 index cf862dd..0000000 Binary files a/twodeesapp/public/images/1737318350.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737319402.jpg b/twodeesapp/public/images/1737319402.jpg deleted file mode 100644 index 9a61bac..0000000 Binary files a/twodeesapp/public/images/1737319402.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737320138.jpg b/twodeesapp/public/images/1737320138.jpg deleted file mode 100644 index 7e621b5..0000000 Binary files a/twodeesapp/public/images/1737320138.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737355066.jpg b/twodeesapp/public/images/1737355066.jpg deleted file mode 100644 index 3a3faae..0000000 Binary files a/twodeesapp/public/images/1737355066.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737466715.jpg b/twodeesapp/public/images/1737466715.jpg deleted file mode 100644 index 3d1cc92..0000000 Binary files a/twodeesapp/public/images/1737466715.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737466789.png b/twodeesapp/public/images/1737466789.png deleted file mode 100644 index db07b26..0000000 Binary files a/twodeesapp/public/images/1737466789.png and /dev/null differ diff --git a/twodeesapp/public/images/1737622530.jpg b/twodeesapp/public/images/1737622530.jpg deleted file mode 100644 index 057fd95..0000000 Binary files a/twodeesapp/public/images/1737622530.jpg and /dev/null differ diff --git a/twodeesapp/public/images/1737623670.png b/twodeesapp/public/images/1737623670.png deleted file mode 100644 index db07b26..0000000 Binary files a/twodeesapp/public/images/1737623670.png and /dev/null differ diff --git a/twodeesapp/public/js/custom_frontend.js b/twodeesapp/public/js/custom_frontend.js index 85e483a..cb3a929 100644 --- a/twodeesapp/public/js/custom_frontend.js +++ b/twodeesapp/public/js/custom_frontend.js @@ -1,3 +1,8 @@ +const removeProfilePicture = (event) => { + let form = event.target.parentElement; + form.submit(); +}; + const displayErrorAlert = (message) => { const ALERT_DURATION_MILLISECONDS = 5000; const containerAfterMain = document.querySelector('main.py-5 > .container'); @@ -5,7 +10,7 @@ const displayErrorAlert = (message) => { errorAlertDivElement.setAttribute('class', 'alert alert-danger'); errorAlertDivElement.innerHTML = message; containerAfterMain.prepend(errorAlertDivElement); - setTimeout(() => errorAlertDivElement.remove(), ALERT_DURATION_MILLISECONDS); + setTimeout(() => errorAlertDivElement.remove(), ALERT_DURATION_MILLISECONDS); }; const lower = (value) => value.toLowerCase(); @@ -34,12 +39,12 @@ const attachQueryParametersToUrl = (parameters) => { }; const handleSearch = (searchTerm) => { - if(searchTerm == '') { + if (searchTerm == '') { let errorMessage = 'Nothing to see here... yet. Type something and we will make some magic happen!'; reportError(errorMessage); } else { - window.location.href = attachQueryParametersToUrl({'search': searchTerm}); + window.location.href = attachQueryParametersToUrl({ 'search': searchTerm }); } } @@ -67,26 +72,26 @@ const handleCategoryDropdownSelection = (event) => { const processViewMode = (parameter, currentViewMode) => { let viewModeValue = null; - if(currentViewMode === 'fa-table') { + if (currentViewMode === 'fa-table') { viewModeValue = 'table'; } - else if(currentViewMode === 'fa-images') { + else if (currentViewMode === 'fa-images') { viewModeValue = 'cards'; } - window.location.href = attachQueryParametersToUrl({[parameter]: viewModeValue}); + window.location.href = attachQueryParametersToUrl({ [parameter]: viewModeValue }); }; const processSort = (parameter, arrowDirection) => { let sortValue = null; - if(arrowDirection === 'fa-arrow-up') { + if (arrowDirection === 'fa-arrow-up') { sortValue = 'desc'; - } else if(arrowDirection === 'fa-arrow-down') { + } else if (arrowDirection === 'fa-arrow-down') { sortValue = 'asc'; } - window.location.href = attachQueryParametersToUrl({[parameter]: sortValue}); + window.location.href = attachQueryParametersToUrl({ [parameter]: sortValue }); } const attachEvent = (target, event, callback) => target.addEventListener(event, callback); @@ -96,40 +101,40 @@ const dateFilterDropdown = document.getElementById('filter_date'); const applyFilterBtn = document.getElementById('apply_filter_btn'); const searchBtn = document.getElementById('btn_search'); const searchInput = document.getElementById('search_input'); +const viewModeBtn = document.getElementById('view_mode'); +const removeProfilePictureBtn = document.getElementById('btn_remove_profile_picture'); const arrowFilterBtn = document.querySelectorAll('#arrow_filter'); const deleteBtns = document.querySelectorAll('.btn-delete'); -const viewModeBtn = document.getElementById('view_mode'); - if (categoryFilterDropdown !== null) { attachEvent(categoryFilterDropdown, 'change', (event) => { handleCategoryDropdownSelection(event); }); } -if(dateFilterDropdown !== null) { +if (dateFilterDropdown !== null) { attachEvent(dateFilterDropdown, 'change', (event) => { handleDateDropdownSelection(event); }); } -if(applyFilterBtn !== null) { +if (applyFilterBtn !== null) { attachEvent(applyFilterBtn, 'click', (event) => { event.preventDefault(); - + let minPrice = document.getElementById('min_price').value; let maxPrice = document.getElementById('max_price').value; - - if(minPrice === '') { + + if (minPrice === '') { minPrice = 0; } - + minPrice = parseFloat(minPrice); maxPrice = parseFloat(maxPrice); - - if(isNaN(minPrice) || isNaN(maxPrice)) { - displayErrorAlert('Please ensure that prices are in numeric format!'); + + if (isNaN(minPrice) || isNaN(maxPrice)) { + reportError('Please ensure that prices are in numeric format!'); } else { handlePriceFilter(minPrice, maxPrice); @@ -137,18 +142,18 @@ if(applyFilterBtn !== null) { }); } -if(searchBtn !== null) { +if (searchBtn !== null) { attachEvent(searchBtn, 'click', () => handleSearch(searchInput.value)); attachEvent(searchInput, 'keydown', (event) => { - if(event.keyCode == 13) { + if (event.keyCode == 13) { let target = event.target; handleSearch(target.value); } }); } -if(arrowFilterBtn !== null) { +if (arrowFilterBtn !== null) { arrowFilterBtn.forEach((arrow) => { attachEvent(arrow, 'click', (event) => { let target = event.target; @@ -160,9 +165,9 @@ if(arrowFilterBtn !== null) { }); } -if(deleteBtns !== null) { +if (deleteBtns !== null) { deleteBtns.forEach((deleteBtn) => { - deleteBtn.addEventListener('click', function(event) { + deleteBtn.addEventListener('click', function (event) { event.preventDefault(); $.confirm({ @@ -194,7 +199,7 @@ if(deleteBtns !== null) { }); } -if(viewModeBtn !== null) { +if (viewModeBtn !== null) { attachEvent(viewModeBtn, 'click', (event) => { event.preventDefault(); let target = event.target; @@ -202,13 +207,27 @@ if(viewModeBtn !== null) { let classes = null; - if(tagName === 'I') { + if (tagName === 'I') { classes = Array.from(target.classList); - } else if(tagName === 'A') { + } else if (tagName === 'A') { classes = Array.from(target.firstChild.classList); } let viewMode = classes.at(1); processViewMode('view_mode', viewMode); }); -} \ No newline at end of file +} + +if (removeProfilePictureBtn !== null) { + attachEvent(removeProfilePictureBtn, 'click', (event) => { + event.preventDefault(); + removeProfilePicture(event); + }); +} + +Fancybox.bind("[data-fancybox]", { + hideScrollbar: false, + dragToClose: true, + showClass: "f-fadeIn", + hideClass: "f-scaleOut" +}); \ No newline at end of file diff --git a/twodeesapp/public/profile_pictures/1737623327.png b/twodeesapp/public/profile_pictures/1737623327.png deleted file mode 100644 index 7ee6ccb..0000000 Binary files a/twodeesapp/public/profile_pictures/1737623327.png and /dev/null differ diff --git a/twodeesapp/public/profile_pictures/1737623332.png b/twodeesapp/public/profile_pictures/1737623332.png deleted file mode 100644 index 7ee6ccb..0000000 Binary files a/twodeesapp/public/profile_pictures/1737623332.png and /dev/null differ diff --git a/twodeesapp/public/profile_pictures/1737623420.png b/twodeesapp/public/profile_pictures/1737623420.png deleted file mode 100644 index 7ee6ccb..0000000 Binary files a/twodeesapp/public/profile_pictures/1737623420.png and /dev/null differ diff --git a/twodeesapp/public/profile_pictures/1737623486.png b/twodeesapp/public/profile_pictures/1737623486.png deleted file mode 100644 index 7ee6ccb..0000000 Binary files a/twodeesapp/public/profile_pictures/1737623486.png and /dev/null differ diff --git a/twodeesapp/resources/views/items/_date_format.blade.php b/twodeesapp/resources/views/common/_date_format.blade.php similarity index 100% rename from twodeesapp/resources/views/items/_date_format.blade.php rename to twodeesapp/resources/views/common/_date_format.blade.php diff --git a/twodeesapp/resources/views/items/index.blade.php b/twodeesapp/resources/views/items/index.blade.php index 587993e..5448790 100644 --- a/twodeesapp/resources/views/items/index.blade.php +++ b/twodeesapp/resources/views/items/index.blade.php @@ -52,7 +52,7 @@ class="fa fa-plus-circle"> Add New
Full Stack Developer
-Bay Area, San Francisco, CA
--}} -Bay Area, San Francisco, CA
--}} + @if(Auth::check()) + @if ($user->id == auth()->user()->id) + @if(file_exists($user->profile_picture)) + +Location
+{{ $user->location->name }}, {{ $country->name }}
+{{ $region->name }}
+Date of birth
+{{ format_date($user->birth_date) }}
+Bio
@@ -60,16 +99,20 @@ class="rounded-circle shadow-4 img-fluid" style="width: 150px;" alt="Avatar" />Please remember that it is your responsibility to ensure all the information on your profile is accurate and up to date. Should you notice any mistakes, feel free to make the necessary corrections.
-Please remember that it is your responsibility to ensure all the information on your profile is accurate and up to date. Should you notice any mistakes, feel free to make the necessary corrections.
+